about summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/alloc/Cargo.toml1
-rw-r--r--library/alloc/benches/binary_heap.rs2
-rw-r--r--library/alloc/benches/btree/map.rs39
-rw-r--r--library/alloc/benches/vec.rs6
-rw-r--r--library/alloc/src/borrow.rs1
-rw-r--r--library/alloc/src/boxed.rs71
-rw-r--r--library/alloc/src/collections/binary_heap.rs28
-rw-r--r--library/alloc/src/collections/btree/fix.rs2
-rw-r--r--library/alloc/src/collections/btree/map.rs205
-rw-r--r--library/alloc/src/collections/btree/map/entry.rs1
-rw-r--r--library/alloc/src/collections/btree/map/tests.rs14
-rw-r--r--library/alloc/src/collections/btree/navigate.rs282
-rw-r--r--library/alloc/src/collections/btree/node.rs14
-rw-r--r--library/alloc/src/collections/btree/set.rs53
-rw-r--r--library/alloc/src/collections/btree/set/tests.rs14
-rw-r--r--library/alloc/src/collections/linked_list.rs165
-rw-r--r--library/alloc/src/collections/linked_list/tests.rs47
-rw-r--r--library/alloc/src/collections/mod.rs49
-rw-r--r--library/alloc/src/collections/vec_deque/drain.rs30
-rw-r--r--library/alloc/src/collections/vec_deque/into_iter.rs50
-rw-r--r--library/alloc/src/collections/vec_deque/iter.rs16
-rw-r--r--library/alloc/src/collections/vec_deque/iter_mut.rs16
-rw-r--r--library/alloc/src/collections/vec_deque/macros.rs4
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs192
-rw-r--r--library/alloc/src/collections/vec_deque/pair_slices.rs4
-rw-r--r--library/alloc/src/fmt.rs4
-rw-r--r--library/alloc/src/lib.rs14
-rw-r--r--library/alloc/src/macros.rs2
-rw-r--r--library/alloc/src/raw_vec.rs21
-rw-r--r--library/alloc/src/rc.rs12
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/str.rs2
-rw-r--r--library/alloc/src/string.rs169
-rw-r--r--library/alloc/src/sync.rs36
-rw-r--r--library/alloc/src/vec/into_iter.rs12
-rw-r--r--library/alloc/src/vec/mod.rs95
-rw-r--r--library/alloc/src/vec/source_iter_marker.rs27
-rw-r--r--library/alloc/src/vec/spec_extend.rs2
-rw-r--r--library/alloc/tests/binary_heap.rs2
-rw-r--r--library/alloc/tests/const_fns.rs53
-rw-r--r--library/alloc/tests/lib.rs6
-rw-r--r--library/alloc/tests/slice.rs61
-rw-r--r--library/alloc/tests/str.rs51
-rw-r--r--library/alloc/tests/string.rs155
-rw-r--r--library/alloc/tests/vec.rs233
-rw-r--r--library/alloc/tests/vec_deque.rs203
-rw-r--r--library/core/Cargo.toml1
-rw-r--r--library/core/benches/iter.rs2
-rw-r--r--library/core/src/alloc/global.rs69
-rw-r--r--library/core/src/alloc/layout.rs19
-rw-r--r--library/core/src/alloc/mod.rs4
-rw-r--r--library/core/src/any.rs1
-rw-r--r--library/core/src/array/equality.rs155
-rw-r--r--library/core/src/array/iter.rs46
-rw-r--r--library/core/src/array/mod.rs155
-rw-r--r--library/core/src/bool.rs2
-rw-r--r--library/core/src/cell.rs18
-rw-r--r--library/core/src/char/decode.rs7
-rw-r--r--library/core/src/char/methods.rs34
-rw-r--r--library/core/src/char/mod.rs8
-rw-r--r--library/core/src/clone.rs2
-rw-r--r--library/core/src/cmp.rs91
-rw-r--r--library/core/src/convert/mod.rs2
-rw-r--r--library/core/src/convert/num.rs17
-rw-r--r--library/core/src/default.rs5
-rw-r--r--library/core/src/fmt/builders.rs5
-rw-r--r--library/core/src/fmt/float.rs9
-rw-r--r--library/core/src/fmt/mod.rs35
-rw-r--r--library/core/src/fmt/nofloat.rs15
-rw-r--r--library/core/src/fmt/num.rs10
-rw-r--r--library/core/src/future/future.rs6
-rw-r--r--library/core/src/future/ready.rs2
-rw-r--r--library/core/src/hash/mod.rs50
-rw-r--r--library/core/src/hint.rs21
-rw-r--r--library/core/src/internal_macros.rs1
-rw-r--r--library/core/src/intrinsics.rs528
-rw-r--r--library/core/src/iter/adapters/cloned.rs15
-rw-r--r--library/core/src/iter/adapters/copied.rs15
-rw-r--r--library/core/src/iter/adapters/enumerate.rs15
-rw-r--r--library/core/src/iter/adapters/flatten.rs94
-rw-r--r--library/core/src/iter/adapters/fuse.rs266
-rw-r--r--library/core/src/iter/adapters/map.rs15
-rw-r--r--library/core/src/iter/adapters/mod.rs5
-rw-r--r--library/core/src/iter/adapters/peekable.rs23
-rw-r--r--library/core/src/iter/adapters/take.rs23
-rw-r--r--library/core/src/iter/adapters/zip.rs240
-rw-r--r--library/core/src/iter/mod.rs4
-rw-r--r--library/core/src/iter/range.rs17
-rw-r--r--library/core/src/iter/sources/empty.rs3
-rw-r--r--library/core/src/iter/sources/repeat.rs1
-rw-r--r--library/core/src/iter/traits/accum.rs18
-rw-r--r--library/core/src/iter/traits/collect.rs60
-rw-r--r--library/core/src/iter/traits/double_ended.rs10
-rw-r--r--library/core/src/iter/traits/exact_size.rs1
-rw-r--r--library/core/src/iter/traits/iterator.rs157
-rw-r--r--library/core/src/lib.rs172
-rw-r--r--library/core/src/macros/mod.rs93
-rw-r--r--library/core/src/marker.rs4
-rw-r--r--library/core/src/mem/manually_drop.rs15
-rw-r--r--library/core/src/mem/maybe_uninit.rs158
-rw-r--r--library/core/src/mem/mod.rs10
-rw-r--r--library/core/src/num/dec2flt/algorithm.rs429
-rw-r--r--library/core/src/num/dec2flt/common.rs198
-rw-r--r--library/core/src/num/dec2flt/decimal.rs351
-rw-r--r--library/core/src/num/dec2flt/float.rs207
-rw-r--r--library/core/src/num/dec2flt/fpu.rs89
-rw-r--r--library/core/src/num/dec2flt/lemire.rs166
-rw-r--r--library/core/src/num/dec2flt/mod.rs220
-rw-r--r--library/core/src/num/dec2flt/num.rs81
-rw-r--r--library/core/src/num/dec2flt/number.rs86
-rw-r--r--library/core/src/num/dec2flt/parse.rs304
-rw-r--r--library/core/src/num/dec2flt/rawfp.rs363
-rw-r--r--library/core/src/num/dec2flt/slow.rs109
-rw-r--r--library/core/src/num/dec2flt/table.rs1937
-rw-r--r--library/core/src/num/diy_float.rs2
-rw-r--r--library/core/src/num/error.rs23
-rw-r--r--library/core/src/num/flt2dec/decoder.rs2
-rw-r--r--library/core/src/num/flt2dec/mod.rs104
-rw-r--r--library/core/src/num/fmt.rs108
-rw-r--r--library/core/src/num/int_log10.rs134
-rw-r--r--library/core/src/num/int_macros.rs213
-rw-r--r--library/core/src/num/mod.rs36
-rw-r--r--library/core/src/num/nonzero.rs573
-rw-r--r--library/core/src/num/uint_macros.rs204
-rw-r--r--library/core/src/ops/control_flow.rs54
-rw-r--r--library/core/src/ops/drop.rs2
-rw-r--r--library/core/src/ops/mod.rs11
-rw-r--r--library/core/src/ops/range.rs13
-rw-r--r--library/core/src/ops/try.rs61
-rw-r--r--library/core/src/ops/try_trait.rs15
-rw-r--r--library/core/src/option.rs426
-rw-r--r--library/core/src/panic.rs348
-rw-r--r--library/core/src/panic/location.rs189
-rw-r--r--library/core/src/panic/panic_info.rs145
-rw-r--r--library/core/src/panic/unwind_safe.rs305
-rw-r--r--library/core/src/panicking.rs15
-rw-r--r--library/core/src/pin.rs42
-rw-r--r--library/core/src/prelude/mod.rs16
-rw-r--r--library/core/src/prelude/v1.rs22
-rw-r--r--library/core/src/ptr/const_ptr.rs12
-rw-r--r--library/core/src/ptr/metadata.rs2
-rw-r--r--library/core/src/ptr/mod.rs19
-rw-r--r--library/core/src/ptr/mut_ptr.rs17
-rw-r--r--library/core/src/ptr/non_null.rs96
-rw-r--r--library/core/src/raw.rs90
-rw-r--r--library/core/src/result.rs284
-rw-r--r--library/core/src/slice/iter.rs140
-rw-r--r--library/core/src/slice/iter/macros.rs16
-rw-r--r--library/core/src/slice/mod.rs72
-rw-r--r--library/core/src/slice/rotate.rs56
-rw-r--r--library/core/src/slice/sort.rs2
-rw-r--r--library/core/src/slice/specialize.rs16
-rw-r--r--library/core/src/str/converts.rs4
-rw-r--r--library/core/src/str/error.rs5
-rw-r--r--library/core/src/str/iter.rs9
-rw-r--r--library/core/src/str/mod.rs14
-rw-r--r--library/core/src/str/pattern.rs19
-rw-r--r--library/core/src/str/traits.rs2
-rw-r--r--library/core/src/stream/from_iter.rs38
-rw-r--r--library/core/src/stream/mod.rs2
-rw-r--r--library/core/src/sync/atomic.rs23
-rw-r--r--library/core/src/task/mod.rs2
-rw-r--r--library/core/src/task/poll.rs160
-rw-r--r--library/core/src/task/ready.rs6
-rw-r--r--library/core/src/time.rs153
-rw-r--r--library/core/src/unicode/mod.rs2
-rwxr-xr-xlibrary/core/src/unicode/printable.py2
-rw-r--r--library/core/tests/char.rs12
-rw-r--r--library/core/tests/hash/mod.rs9
-rw-r--r--library/core/tests/iter/adapters/flatten.rs40
-rw-r--r--library/core/tests/iter/adapters/mod.rs2
-rw-r--r--library/core/tests/iter/adapters/zip.rs27
-rw-r--r--library/core/tests/lib.rs10
-rw-r--r--library/core/tests/macros.rs6
-rw-r--r--library/core/tests/manually_drop.rs8
-rw-r--r--library/core/tests/mem.rs22
-rw-r--r--library/core/tests/num/const_from.rs25
-rw-r--r--library/core/tests/num/dec2flt/float.rs33
-rw-r--r--library/core/tests/num/dec2flt/lemire.rs53
-rw-r--r--library/core/tests/num/dec2flt/mod.rs17
-rw-r--r--library/core/tests/num/dec2flt/parse.rs162
-rw-r--r--library/core/tests/num/dec2flt/rawfp.rs172
-rw-r--r--library/core/tests/num/flt2dec/mod.rs3
-rw-r--r--library/core/tests/num/int_log.rs153
-rw-r--r--library/core/tests/num/mod.rs3
-rw-r--r--library/core/tests/option.rs34
-rw-r--r--library/core/tests/result.rs1
-rw-r--r--library/core/tests/slice.rs50
-rw-r--r--library/panic_abort/Cargo.toml1
-rw-r--r--library/panic_abort/src/android.rs2
-rw-r--r--library/panic_abort/src/lib.rs3
-rw-r--r--library/panic_unwind/Cargo.toml1
-rw-r--r--library/panic_unwind/src/dwarf/eh.rs8
-rw-r--r--library/panic_unwind/src/gcc.rs8
-rw-r--r--library/panic_unwind/src/lib.rs9
-rw-r--r--library/panic_unwind/src/seh.rs16
-rw-r--r--library/proc_macro/Cargo.toml1
-rw-r--r--library/proc_macro/src/bridge/buffer.rs29
-rw-r--r--library/proc_macro/src/bridge/client.rs2
-rw-r--r--library/proc_macro/src/bridge/mod.rs2
-rw-r--r--library/proc_macro/src/bridge/rpc.rs2
-rw-r--r--library/proc_macro/src/diagnostic.rs9
-rw-r--r--library/proc_macro/src/lib.rs87
-rw-r--r--library/profiler_builtins/Cargo.toml3
-rw-r--r--library/rustc-std-workspace-alloc/Cargo.toml1
-rw-r--r--library/rustc-std-workspace-core/Cargo.toml1
-rw-r--r--library/rustc-std-workspace-std/Cargo.toml1
-rw-r--r--library/std/Cargo.toml5
-rw-r--r--library/std/build.rs1
-rw-r--r--library/std/src/backtrace.rs11
-rw-r--r--library/std/src/collections/hash/map.rs94
-rw-r--r--library/std/src/collections/hash/map/tests.rs35
-rw-r--r--library/std/src/collections/hash/set.rs43
-rw-r--r--library/std/src/collections/hash/set/tests.rs12
-rw-r--r--library/std/src/collections/mod.rs6
-rw-r--r--library/std/src/env.rs50
-rw-r--r--library/std/src/error.rs3
-rw-r--r--library/std/src/f32.rs42
-rw-r--r--library/std/src/f32/tests.rs63
-rw-r--r--library/std/src/f64.rs42
-rw-r--r--library/std/src/f64/tests.rs55
-rw-r--r--library/std/src/ffi/mod.rs4
-rw-r--r--library/std/src/ffi/os_str.rs8
-rw-r--r--library/std/src/fs.rs63
-rw-r--r--library/std/src/fs/tests.rs23
-rw-r--r--library/std/src/io/buffered/bufreader.rs8
-rw-r--r--library/std/src/io/buffered/bufwriter.rs50
-rw-r--r--library/std/src/io/buffered/mod.rs8
-rw-r--r--library/std/src/io/cursor.rs63
-rw-r--r--library/std/src/io/error.rs185
-rw-r--r--library/std/src/io/impls.rs10
-rw-r--r--library/std/src/io/mod.rs224
-rw-r--r--library/std/src/io/stdio.rs282
-rw-r--r--library/std/src/io/stdio/tests.rs119
-rw-r--r--library/std/src/io/tests.rs70
-rw-r--r--library/std/src/io/util.rs29
-rw-r--r--library/std/src/keyword_docs.rs32
-rw-r--r--library/std/src/lazy.rs33
-rw-r--r--library/std/src/lib.rs38
-rw-r--r--library/std/src/macros.rs4
-rw-r--r--library/std/src/net/addr.rs2
-rw-r--r--library/std/src/net/ip.rs340
-rw-r--r--library/std/src/net/ip/tests.rs29
-rw-r--r--library/std/src/net/tcp/tests.rs2
-rw-r--r--library/std/src/net/udp.rs6
-rw-r--r--library/std/src/num.rs7
-rw-r--r--library/std/src/os/espidf/fs.rs117
-rw-r--r--library/std/src/os/espidf/mod.rs6
-rw-r--r--library/std/src/os/espidf/raw.rs69
-rw-r--r--library/std/src/os/fortanix_sgx/arch.rs12
-rw-r--r--library/std/src/os/fortanix_sgx/ffi.rs5
-rw-r--r--library/std/src/os/hermit/ffi.rs5
-rw-r--r--library/std/src/os/linux/mod.rs1
-rw-r--r--library/std/src/os/linux/process.rs145
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/unix/ffi/mod.rs (renamed from library/std/src/os/unix/ffi.rs)4
-rw-r--r--library/std/src/os/unix/ffi/os_str.rs68
-rw-r--r--library/std/src/os/unix/fs.rs39
-rw-r--r--library/std/src/os/unix/mod.rs3
-rw-r--r--library/std/src/os/unix/net/addr.rs2
-rw-r--r--library/std/src/os/unix/net/ancillary.rs110
-rw-r--r--library/std/src/os/unix/net/stream.rs3
-rw-r--r--library/std/src/os/unix/process.rs4
-rw-r--r--library/std/src/os/unix/ucred.rs14
-rw-r--r--library/std/src/os/wasi/ffi.rs5
-rw-r--r--library/std/src/os/wasi/fs.rs5
-rw-r--r--library/std/src/os/wasi/io.rs23
-rw-r--r--library/std/src/os/windows/process.rs13
-rw-r--r--library/std/src/panic.rs319
-rw-r--r--library/std/src/panicking.rs23
-rw-r--r--library/std/src/path.rs30
-rw-r--r--library/std/src/prelude/mod.rs32
-rw-r--r--library/std/src/prelude/v1.rs24
-rw-r--r--library/std/src/primitive_docs.rs6
-rw-r--r--library/std/src/process.rs25
-rw-r--r--library/std/src/process/tests.rs9
-rw-r--r--library/std/src/rt.rs37
-rw-r--r--library/std/src/sync/condvar.rs6
-rw-r--r--library/std/src/sync/mpsc/mod.rs53
-rw-r--r--library/std/src/sync/mpsc/mpsc_queue.rs6
-rw-r--r--library/std/src/sync/mpsc/spsc_queue.rs2
-rw-r--r--library/std/src/sync/mpsc/stream.rs4
-rw-r--r--library/std/src/sync/mutex.rs40
-rw-r--r--library/std/src/sync/once.rs2
-rw-r--r--library/std/src/sync/poison.rs2
-rw-r--r--library/std/src/sync/rwlock.rs48
-rw-r--r--library/std/src/sys/common/alloc.rs3
-rw-r--r--library/std/src/sys/hermit/args.rs2
-rw-r--r--library/std/src/sys/hermit/condvar.rs2
-rw-r--r--library/std/src/sys/hermit/fs.rs2
-rw-r--r--library/std/src/sys/hermit/mod.rs5
-rw-r--r--library/std/src/sys/hermit/mutex.rs4
-rw-r--r--library/std/src/sys/hermit/net.rs51
-rw-r--r--library/std/src/sys/hermit/os.rs11
-rw-r--r--library/std/src/sys/hermit/rwlock.rs2
-rw-r--r--library/std/src/sys/hermit/stdio.rs8
-rw-r--r--library/std/src/sys/hermit/thread.rs8
-rw-r--r--library/std/src/sys/sgx/abi/mem.rs4
-rw-r--r--library/std/src/sys/sgx/mod.rs10
-rw-r--r--library/std/src/sys/sgx/mutex.rs3
-rw-r--r--library/std/src/sys/sgx/net.rs2
-rw-r--r--library/std/src/sys/sgx/os.rs4
-rw-r--r--library/std/src/sys/sgx/rwlock.rs2
-rw-r--r--library/std/src/sys/sgx/stdio.rs2
-rw-r--r--library/std/src/sys/sgx/thread.rs6
-rw-r--r--library/std/src/sys/sgx/waitqueue/unsafe_list.rs1
-rw-r--r--library/std/src/sys/unix/alloc.rs3
-rw-r--r--library/std/src/sys/unix/android.rs2
-rw-r--r--library/std/src/sys/unix/args.rs50
-rw-r--r--library/std/src/sys/unix/condvar.rs27
-rw-r--r--library/std/src/sys/unix/env.rs11
-rw-r--r--library/std/src/sys/unix/fd.rs36
-rw-r--r--library/std/src/sys/unix/fs.rs93
-rw-r--r--library/std/src/sys/unix/kernel_copy.rs1
-rw-r--r--library/std/src/sys/unix/mod.rs123
-rw-r--r--library/std/src/sys/unix/net.rs14
-rw-r--r--library/std/src/sys/unix/os.rs108
-rw-r--r--library/std/src/sys/unix/os/tests.rs2
-rw-r--r--library/std/src/sys/unix/os_str.rs (renamed from library/std/src/sys_common/os_str_bytes.rs)98
-rw-r--r--library/std/src/sys/unix/os_str/tests.rs10
-rw-r--r--library/std/src/sys/unix/process/mod.rs3
-rw-r--r--library/std/src/sys/unix/process/process_common.rs43
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs144
-rw-r--r--library/std/src/sys/unix/process/process_unsupported.rs122
-rw-r--r--library/std/src/sys/unix/rand.rs13
-rw-r--r--library/std/src/sys/unix/rwlock.rs54
-rw-r--r--library/std/src/sys/unix/thread.rs193
-rw-r--r--library/std/src/sys/unix/time.rs4
-rw-r--r--library/std/src/sys/unix/weak.rs8
-rw-r--r--library/std/src/sys/unsupported/common.rs4
-rw-r--r--library/std/src/sys/unsupported/mod.rs2
-rw-r--r--library/std/src/sys/unsupported/os.rs4
-rw-r--r--library/std/src/sys/unsupported/rwlock.rs2
-rw-r--r--library/std/src/sys/unsupported/thread.rs5
-rw-r--r--library/std/src/sys/wasi/fd.rs89
-rw-r--r--library/std/src/sys/wasi/fs.rs12
-rw-r--r--library/std/src/sys/wasi/mod.rs7
-rw-r--r--library/std/src/sys/wasi/net.rs13
-rw-r--r--library/std/src/sys/wasi/os.rs9
-rw-r--r--library/std/src/sys/wasi/stdio.rs7
-rw-r--r--library/std/src/sys/wasi/thread.rs5
-rw-r--r--library/std/src/sys/wasm/atomics/rwlock.rs2
-rw-r--r--library/std/src/sys/wasm/atomics/thread.rs5
-rw-r--r--library/std/src/sys/wasm/mod.rs4
-rw-r--r--library/std/src/sys/windows/c.rs84
-rw-r--r--library/std/src/sys/windows/c/errors.rs1883
-rw-r--r--library/std/src/sys/windows/fs.rs7
-rw-r--r--library/std/src/sys/windows/mod.rs64
-rw-r--r--library/std/src/sys/windows/mutex.rs2
-rw-r--r--library/std/src/sys/windows/net.rs305
-rw-r--r--library/std/src/sys/windows/os.rs19
-rw-r--r--library/std/src/sys/windows/process.rs195
-rw-r--r--library/std/src/sys/windows/process/tests.rs89
-rw-r--r--library/std/src/sys/windows/rwlock.rs2
-rw-r--r--library/std/src/sys/windows/stdio.rs2
-rw-r--r--library/std/src/sys/windows/thread.rs16
-rw-r--r--library/std/src/sys/windows/thread_local_key.rs2
-rw-r--r--library/std/src/sys_common/backtrace.rs2
-rw-r--r--library/std/src/sys_common/bytestring.rs26
-rw-r--r--library/std/src/sys_common/bytestring/tests.rs19
-rw-r--r--library/std/src/sys_common/io.rs4
-rw-r--r--library/std/src/sys_common/mod.rs5
-rw-r--r--library/std/src/sys_common/process.rs10
-rw-r--r--library/std/src/sys_common/rwlock.rs120
-rw-r--r--library/std/src/sys_common/wtf8.rs3
-rw-r--r--library/std/src/sys_common/wtf8/tests.rs18
-rw-r--r--library/std/src/thread/available_concurrency.rs156
-rw-r--r--library/std/src/thread/local.rs7
-rw-r--r--library/std/src/thread/local/tests.rs2
-rw-r--r--library/std/src/thread/mod.rs148
-rw-r--r--library/std/src/time.rs6
-rw-r--r--library/std/tests/run-time-detect.rs38
m---------library/stdarch0
-rw-r--r--library/term/Cargo.toml9
-rw-r--r--library/term/src/lib.rs194
-rw-r--r--library/test/Cargo.toml2
-rw-r--r--library/test/src/console.rs2
-rw-r--r--library/test/src/formatters/junit.rs8
-rw-r--r--library/test/src/formatters/pretty.rs1
-rw-r--r--library/test/src/formatters/terse.rs1
-rw-r--r--library/test/src/lib.rs3
-rw-r--r--library/test/src/stats.rs2
-rw-r--r--library/test/src/term.rs85
-rw-r--r--library/test/src/term/terminfo/mod.rs (renamed from library/term/src/terminfo/mod.rs)97
-rw-r--r--library/test/src/term/terminfo/parm.rs (renamed from library/term/src/terminfo/parm.rs)43
-rw-r--r--library/test/src/term/terminfo/parm/tests.rs (renamed from library/term/src/terminfo/parm/tests.rs)22
-rw-r--r--library/test/src/term/terminfo/parser/compiled.rs (renamed from library/term/src/terminfo/parser/compiled.rs)16
-rw-r--r--library/test/src/term/terminfo/parser/compiled/tests.rs (renamed from library/term/src/terminfo/parser/compiled/tests.rs)0
-rw-r--r--library/test/src/term/terminfo/searcher.rs (renamed from library/term/src/terminfo/searcher.rs)2
-rw-r--r--library/test/src/term/terminfo/searcher/tests.rs (renamed from library/term/src/terminfo/searcher/tests.rs)0
-rw-r--r--library/test/src/term/win.rs (renamed from library/term/src/win.rs)58
-rw-r--r--library/test/src/tests.rs38
-rw-r--r--library/test/src/types.rs8
-rw-r--r--library/unwind/Cargo.toml3
-rw-r--r--library/unwind/src/lib.rs3
-rw-r--r--library/unwind/src/libunwind.rs13
396 files changed, 15915 insertions, 7933 deletions
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 5793f5e681b..b3ff0fd0a31 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "alloc"
 version = "0.0.0"
 license = "MIT OR Apache-2.0"
diff --git a/library/alloc/benches/binary_heap.rs b/library/alloc/benches/binary_heap.rs
index 5b6538ea6c6..491243e22c7 100644
--- a/library/alloc/benches/binary_heap.rs
+++ b/library/alloc/benches/binary_heap.rs
@@ -36,7 +36,7 @@ fn bench_peek_mut_deref_mut(b: &mut Bencher) {
         let mut peek_mut = bheap.peek_mut().unwrap();
         // The compiler shouldn't be able to optimize away the `sift_down`
         // assignment in `PeekMut`'s `DerefMut` implementation since
-        // the loop may not run.
+        // the loop might not run.
         for &i in vec.iter() {
             *peek_mut = i;
         }
diff --git a/library/alloc/benches/btree/map.rs b/library/alloc/benches/btree/map.rs
index 21a0fb844e8..920a5ca7db0 100644
--- a/library/alloc/benches/btree/map.rs
+++ b/library/alloc/benches/btree/map.rs
@@ -177,7 +177,7 @@ pub fn iteration_mut_100000(b: &mut Bencher) {
     bench_iteration_mut(b, 100000);
 }
 
-fn bench_first_and_last(b: &mut Bencher, size: i32) {
+fn bench_first_and_last_nightly(b: &mut Bencher, size: i32) {
     let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
     b.iter(|| {
         for _ in 0..10 {
@@ -187,19 +187,44 @@ fn bench_first_and_last(b: &mut Bencher, size: i32) {
     });
 }
 
+fn bench_first_and_last_stable(b: &mut Bencher, size: i32) {
+    let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+    b.iter(|| {
+        for _ in 0..10 {
+            black_box(map.iter().next());
+            black_box(map.iter().next_back());
+        }
+    });
+}
+
+#[bench]
+pub fn first_and_last_0_nightly(b: &mut Bencher) {
+    bench_first_and_last_nightly(b, 0);
+}
+
+#[bench]
+pub fn first_and_last_0_stable(b: &mut Bencher) {
+    bench_first_and_last_stable(b, 0);
+}
+
+#[bench]
+pub fn first_and_last_100_nightly(b: &mut Bencher) {
+    bench_first_and_last_nightly(b, 100);
+}
+
 #[bench]
-pub fn first_and_last_0(b: &mut Bencher) {
-    bench_first_and_last(b, 0);
+pub fn first_and_last_100_stable(b: &mut Bencher) {
+    bench_first_and_last_stable(b, 100);
 }
 
 #[bench]
-pub fn first_and_last_100(b: &mut Bencher) {
-    bench_first_and_last(b, 100);
+pub fn first_and_last_10k_nightly(b: &mut Bencher) {
+    bench_first_and_last_nightly(b, 10_000);
 }
 
 #[bench]
-pub fn first_and_last_10k(b: &mut Bencher) {
-    bench_first_and_last(b, 10_000);
+pub fn first_and_last_10k_stable(b: &mut Bencher) {
+    bench_first_and_last_stable(b, 10_000);
 }
 
 const BENCH_RANGE_SIZE: i32 = 145;
diff --git a/library/alloc/benches/vec.rs b/library/alloc/benches/vec.rs
index 91eec10d575..c93a493cadb 100644
--- a/library/alloc/benches/vec.rs
+++ b/library/alloc/benches/vec.rs
@@ -726,3 +726,9 @@ fn bench_dedup_old_100000(b: &mut Bencher) {
 fn bench_dedup_new_100000(b: &mut Bencher) {
     bench_vec_dedup_new(b, 100000);
 }
+
+#[bench]
+fn bench_flat_map_collect(b: &mut Bencher) {
+    let v = vec![777u32; 500000];
+    b.iter(|| v.iter().flat_map(|color| color.rotate_left(8).to_be_bytes()).collect::<Vec<_>>());
+}
diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs
index 9d61b3684b8..482a497201d 100644
--- a/library/alloc/src/borrow.rs
+++ b/library/alloc/src/borrow.rs
@@ -177,6 +177,7 @@ where
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Cow")]
 pub enum Cow<'a, B: ?Sized + 'a>
 where
     B: ToOwned,
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index eb91af8c61c..72216852376 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -157,7 +157,6 @@ use crate::alloc::{handle_alloc_error, WriteCloneIntoRaw};
 use crate::alloc::{AllocError, Allocator, Global, Layout};
 #[cfg(not(no_global_oom_handling))]
 use crate::borrow::Cow;
-#[cfg(not(no_global_oom_handling))]
 use crate::raw_vec::RawVec;
 #[cfg(not(no_global_oom_handling))]
 use crate::str::from_boxed_utf8_unchecked;
@@ -187,8 +186,6 @@ impl<T> Box<T> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[inline(always)]
-    #[doc(alias = "alloc")]
-    #[doc(alias = "malloc")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(x: T) -> Self {
         box x
@@ -239,7 +236,6 @@ impl<T> Box<T> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[doc(alias = "calloc")]
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
         Self::new_zeroed_in(Global)
@@ -592,6 +588,71 @@ impl<T> Box<[T]> {
     pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
         unsafe { RawVec::with_capacity_zeroed(len).into_box(len) }
     }
+
+    /// Constructs a new boxed slice with uninitialized contents. Returns an error if
+    /// the allocation fails
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(allocator_api, new_uninit)]
+    ///
+    /// let mut values = Box::<[u32]>::try_new_uninit_slice(3)?;
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     values[0].as_mut_ptr().write(1);
+    ///     values[1].as_mut_ptr().write(2);
+    ///     values[2].as_mut_ptr().write(3);
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3]);
+    /// # Ok::<(), std::alloc::AllocError>(())
+    /// ```
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn try_new_uninit_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> {
+        unsafe {
+            let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
+                Ok(l) => l,
+                Err(_) => return Err(AllocError),
+            };
+            let ptr = Global.allocate(layout)?;
+            Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len))
+        }
+    }
+
+    /// Constructs a new boxed slice with uninitialized contents, with the memory
+    /// being filled with `0` bytes. Returns an error if the allocation fails
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
+    /// of this method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(allocator_api, new_uninit)]
+    ///
+    /// let values = Box::<[u32]>::try_new_zeroed_slice(3)?;
+    /// let values = unsafe { values.assume_init() };
+    ///
+    /// assert_eq!(*values, [0, 0, 0]);
+    /// # Ok::<(), std::alloc::AllocError>(())
+    /// ```
+    ///
+    /// [zeroed]: mem::MaybeUninit::zeroed
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn try_new_zeroed_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> {
+        unsafe {
+            let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
+                Ok(l) => l,
+                Err(_) => return Err(AllocError),
+            };
+            let ptr = Global.allocate_zeroed(layout)?;
+            Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len))
+        }
+    }
 }
 
 impl<T, A: Allocator> Box<[T], A> {
@@ -1209,7 +1270,7 @@ impl<T: ?Sized + Hasher, A: Allocator> Hasher for Box<T, A> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_for_ptrs", since = "1.6.0")]
 impl<T> From<T> for Box<T> {
-    /// Converts a generic type `T` into a `Box<T>`
+    /// Converts a `T` into a `Box<T>`
     ///
     /// The conversion allocates on the heap and moves `t`
     /// from the stack into it.
diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs
index 544e18d1ff3..fb340734e0b 100644
--- a/library/alloc/src/collections/binary_heap.rs
+++ b/library/alloc/src/collections/binary_heap.rs
@@ -209,6 +209,14 @@ use super::SpecExtend;
 /// assert!(heap.is_empty())
 /// ```
 ///
+/// A `BinaryHeap` with a known list of items can be initialized from an array:
+///
+/// ```
+/// use std::collections::BinaryHeap;
+///
+/// let heap = BinaryHeap::from([1, 5, 2]);
+/// ```
+///
 /// ## Min-heap
 ///
 /// Either `std::cmp::Reverse` or a custom `Ord` implementation can be used to
@@ -965,7 +973,6 @@ impl<T> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(shrink_to)]
     /// use std::collections::BinaryHeap;
     /// let mut heap: BinaryHeap<i32> = BinaryHeap::with_capacity(100);
     ///
@@ -974,7 +981,7 @@ impl<T> BinaryHeap<T> {
     /// assert!(heap.capacity() >= 10);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.data.shrink_to(min_capacity)
     }
@@ -1034,7 +1041,6 @@ impl<T> BinaryHeap<T> {
     ///
     /// assert_eq!(heap.len(), 2);
     /// ```
-    #[doc(alias = "length")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize {
         self.data.len()
@@ -1466,6 +1472,22 @@ impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
     }
 }
 
+#[stable(feature = "std_collections_from_array", since = "1.56.0")]
+impl<T: Ord, const N: usize> From<[T; N]> for BinaryHeap<T> {
+    /// ```
+    /// use std::collections::BinaryHeap;
+    ///
+    /// let mut h1 = BinaryHeap::from([1, 4, 2, 3]);
+    /// let mut h2: BinaryHeap<_> = [1, 4, 2, 3].into();
+    /// while let Some((a, b)) = h1.pop().zip(h2.pop()) {
+    ///     assert_eq!(a, b);
+    /// }
+    /// ```
+    fn from(arr: [T; N]) -> Self {
+        core::array::IntoIter::new(arr).collect()
+    }
+}
+
 #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
 impl<T> From<BinaryHeap<T>> for Vec<T> {
     /// Converts a `BinaryHeap<T>` into a `Vec<T>`.
diff --git a/library/alloc/src/collections/btree/fix.rs b/library/alloc/src/collections/btree/fix.rs
index af87a9b956a..c4861817dd0 100644
--- a/library/alloc/src/collections/btree/fix.rs
+++ b/library/alloc/src/collections/btree/fix.rs
@@ -3,7 +3,7 @@ use super::node::{marker, ForceResult::*, Handle, LeftOrRight::*, NodeRef, Root}
 
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
     /// Stocks up a possibly underfull node by merging with or stealing from a
-    /// sibling. If succesful but at the cost of shrinking the parent node,
+    /// sibling. If successful but at the cost of shrinking the parent node,
     /// returns that shrunk parent node. Returns an `Err` if the node is
     /// an empty root.
     fn fix_node_through_parent(
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 30194aa446f..4b649e43371 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -9,7 +9,7 @@ use core::ops::{Index, RangeBounds};
 use core::ptr;
 
 use super::borrow::DormantMutRef;
-use super::navigate::LeafRange;
+use super::navigate::{LazyLeafRange, LeafRange};
 use super::node::{self, marker, ForceResult::*, Handle, NodeRef, Root};
 use super::search::SearchResult::*;
 
@@ -109,7 +109,20 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
 /// }
 /// ```
 ///
-/// `BTreeMap` also implements an [`Entry API`], which allows for more complex
+/// A `BTreeMap` with a known list of items can be initialized from an array:
+///
+/// ```
+/// use std::collections::BTreeMap;
+///
+/// let solar_distance = BTreeMap::from([
+///     ("Mercury", 0.4),
+///     ("Venus", 0.7),
+///     ("Earth", 1.0),
+///     ("Mars", 1.5),
+/// ]);
+/// ```
+///
+/// `BTreeMap` implements an [`Entry API`], which allows for complex
 /// methods of getting, setting, updating and removing keys and their values:
 ///
 /// [`Entry API`]: BTreeMap::entry
@@ -148,9 +161,7 @@ pub struct BTreeMap<K, V> {
 #[stable(feature = "btree_drop", since = "1.7.0")]
 unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> {
     fn drop(&mut self) {
-        if let Some(root) = self.root.take() {
-            Dropper { front: root.into_dying().first_leaf_edge(), remaining_length: self.length };
-        }
+        drop(unsafe { ptr::read(self) }.into_iter())
     }
 }
 
@@ -278,7 +289,7 @@ where
 /// [`iter`]: BTreeMap::iter
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, K: 'a, V: 'a> {
-    range: Range<'a, K, V>,
+    range: LazyLeafRange<marker::Immut<'a>, K, V>,
     length: usize,
 }
 
@@ -296,10 +307,20 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
 ///
 /// [`iter_mut`]: BTreeMap::iter_mut
 #[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Debug)]
 pub struct IterMut<'a, K: 'a, V: 'a> {
-    range: RangeMut<'a, K, V>,
+    range: LazyLeafRange<marker::ValMut<'a>, K, V>,
     length: usize,
+
+    // Be invariant in `K` and `V`
+    _marker: PhantomData<&'a mut (K, V)>,
+}
+
+#[stable(feature = "collection_debug", since = "1.17.0")]
+impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let range = Iter { range: self.range.reborrow(), length: self.length };
+        f.debug_list().entries(range).finish()
+    }
 }
 
 /// An owning iterator over the entries of a `BTreeMap`.
@@ -310,7 +331,7 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
 /// [`into_iter`]: IntoIterator::into_iter
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<K, V> {
-    range: LeafRange<marker::Dying, K, V>,
+    range: LazyLeafRange<marker::Dying, K, V>,
     length: usize,
 }
 
@@ -318,8 +339,7 @@ impl<K, V> IntoIter<K, V> {
     /// Returns an iterator of references over the remaining items.
     #[inline]
     pub(super) fn iter(&self) -> Iter<'_, K, V> {
-        let range = Range { inner: self.range.reborrow() };
-        Iter { range: range, length: self.length }
+        Iter { range: self.range.reborrow(), length: self.length }
     }
 }
 
@@ -330,14 +350,6 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
     }
 }
 
-/// A simplified version of `IntoIter` that is not double-ended and has only one
-/// purpose: to drop the remainder of an `IntoIter`. Therefore it also serves to
-/// drop an entire tree without the need to first look up a `back` leaf edge.
-struct Dropper<K, V> {
-    front: Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge>,
-    remaining_length: usize,
-}
-
 /// An iterator over the keys of a `BTreeMap`.
 ///
 /// This `struct` is created by the [`keys`] method on [`BTreeMap`]. See its
@@ -889,7 +901,6 @@ impl<K, V> BTreeMap<K, V> {
     /// assert_eq!(map.remove(&1), Some("a"));
     /// assert_eq!(map.remove(&1), None);
     /// ```
-    #[doc(alias = "delete")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
     where
@@ -936,6 +947,7 @@ impl<K, V> BTreeMap<K, V> {
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
+    /// The elements are visited in ascending key order.
     ///
     /// # Examples
     ///
@@ -1415,7 +1427,7 @@ impl<'a, K, V> IterMut<'a, K, V> {
     /// Returns an iterator of references over the remaining items.
     #[inline]
     pub(super) fn iter(&self) -> Iter<'_, K, V> {
-        Iter { range: self.range.iter(), length: self.length }
+        Iter { range: self.range.reborrow(), length: self.length }
     }
 }
 
@@ -1431,52 +1443,62 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
 
             IntoIter { range: full_range, length: me.length }
         } else {
-            IntoIter { range: LeafRange::none(), length: 0 }
+            IntoIter { range: LazyLeafRange::none(), length: 0 }
         }
     }
 }
 
-impl<K, V> Drop for Dropper<K, V> {
+#[stable(feature = "btree_drop", since = "1.7.0")]
+impl<K, V> Drop for IntoIter<K, V> {
     fn drop(&mut self) {
-        // Similar to advancing a non-fusing iterator.
-        fn next_or_end<K, V>(
-            this: &mut Dropper<K, V>,
-        ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>>
-        {
-            if this.remaining_length == 0 {
-                unsafe { ptr::read(&this.front).deallocating_end() }
-                None
-            } else {
-                this.remaining_length -= 1;
-                Some(unsafe { this.front.deallocating_next_unchecked() })
-            }
-        }
-
-        struct DropGuard<'a, K, V>(&'a mut Dropper<K, V>);
+        struct DropGuard<'a, K, V>(&'a mut IntoIter<K, V>);
 
         impl<'a, K, V> Drop for DropGuard<'a, K, V> {
             fn drop(&mut self) {
                 // Continue the same loop we perform below. This only runs when unwinding, so we
                 // don't have to care about panics this time (they'll abort).
-                while let Some(kv) = next_or_end(&mut self.0) {
-                    kv.drop_key_val();
+                while let Some(kv) = self.0.dying_next() {
+                    // SAFETY: we consume the dying handle immediately.
+                    unsafe { kv.drop_key_val() };
                 }
             }
         }
 
-        while let Some(kv) = next_or_end(self) {
+        while let Some(kv) = self.dying_next() {
             let guard = DropGuard(self);
-            kv.drop_key_val();
+            // SAFETY: we don't touch the tree before consuming the dying handle.
+            unsafe { kv.drop_key_val() };
             mem::forget(guard);
         }
     }
 }
 
-#[stable(feature = "btree_drop", since = "1.7.0")]
-impl<K, V> Drop for IntoIter<K, V> {
-    fn drop(&mut self) {
-        if let Some(front) = self.range.front.take() {
-            Dropper { front, remaining_length: self.length };
+impl<K, V> IntoIter<K, V> {
+    /// Core of a `next` method returning a dying KV handle,
+    /// invalidated by further calls to this function and some others.
+    fn dying_next(
+        &mut self,
+    ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
+        if self.length == 0 {
+            self.range.deallocating_end();
+            None
+        } else {
+            self.length -= 1;
+            Some(unsafe { self.range.deallocating_next_unchecked() })
+        }
+    }
+
+    /// Core of a `next_back` method returning a dying KV handle,
+    /// invalidated by further calls to this function and some others.
+    fn dying_next_back(
+        &mut self,
+    ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
+        if self.length == 0 {
+            self.range.deallocating_end();
+            None
+        } else {
+            self.length -= 1;
+            Some(unsafe { self.range.deallocating_next_back_unchecked() })
         }
     }
 }
@@ -1486,14 +1508,8 @@ impl<K, V> Iterator for IntoIter<K, V> {
     type Item = (K, V);
 
     fn next(&mut self) -> Option<(K, V)> {
-        if self.length == 0 {
-            None
-        } else {
-            self.length -= 1;
-            let front = self.range.front.as_mut().unwrap();
-            let kv = unsafe { front.deallocating_next_unchecked() };
-            Some(kv.into_key_val())
-        }
+        // SAFETY: we consume the dying handle immediately.
+        self.dying_next().map(unsafe { |kv| kv.into_key_val() })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -1504,14 +1520,8 @@ impl<K, V> Iterator for IntoIter<K, V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
     fn next_back(&mut self) -> Option<(K, V)> {
-        if self.length == 0 {
-            None
-        } else {
-            self.length -= 1;
-            let back = self.range.back.as_mut().unwrap();
-            let kv = unsafe { back.deallocating_next_back_unchecked() };
-            Some(kv.into_key_val())
-        }
+        // SAFETY: we consume the dying handle immediately.
+        self.dying_next_back().map(unsafe { |kv| kv.into_key_val() })
     }
 }
 
@@ -1727,7 +1737,7 @@ impl<'a, K, V> Iterator for Range<'a, K, V> {
     type Item = (&'a K, &'a V);
 
     fn next(&mut self) -> Option<(&'a K, &'a V)> {
-        if self.inner.is_empty() { None } else { Some(unsafe { self.next_unchecked() }) }
+        self.inner.next_checked()
     }
 
     fn last(mut self) -> Option<(&'a K, &'a V)> {
@@ -1777,12 +1787,6 @@ impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
 #[stable(feature = "fused", since = "1.26.0")]
 impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
 
-impl<'a, K, V> Range<'a, K, V> {
-    unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
-        unsafe { self.inner.front.as_mut().unwrap_unchecked().next_unchecked() }
-    }
-}
-
 #[stable(feature = "map_into_keys_values", since = "1.54.0")]
 impl<K, V> Iterator for IntoKeys<K, V> {
     type Item = K;
@@ -1862,13 +1866,7 @@ impl<K, V> FusedIterator for IntoValues<K, V> {}
 #[stable(feature = "btree_range", since = "1.17.0")]
 impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> {
     fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
-        if self.inner.is_empty() { None } else { Some(unsafe { self.next_back_unchecked() }) }
-    }
-}
-
-impl<'a, K, V> Range<'a, K, V> {
-    unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
-        unsafe { self.inner.back.as_mut().unwrap_unchecked().next_back_unchecked() }
+        self.inner.next_back_checked()
     }
 }
 
@@ -1878,7 +1876,7 @@ impl<K, V> FusedIterator for Range<'_, K, V> {}
 #[stable(feature = "btree_range", since = "1.17.0")]
 impl<K, V> Clone for Range<'_, K, V> {
     fn clone(&self) -> Self {
-        Range { inner: LeafRange { front: self.inner.front, back: self.inner.back } }
+        Range { inner: self.inner.clone() }
     }
 }
 
@@ -1887,7 +1885,7 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
     type Item = (&'a K, &'a mut V);
 
     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
-        if self.inner.is_empty() { None } else { Some(unsafe { self.next_unchecked() }) }
+        self.inner.next_checked()
     }
 
     fn last(mut self) -> Option<(&'a K, &'a mut V)> {
@@ -1903,34 +1901,16 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
     }
 }
 
-impl<'a, K, V> RangeMut<'a, K, V> {
-    unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
-        unsafe { self.inner.front.as_mut().unwrap_unchecked().next_unchecked() }
-    }
-
-    /// Returns an iterator of references over the remaining items.
-    #[inline]
-    pub(super) fn iter(&self) -> Range<'_, K, V> {
-        Range { inner: self.inner.reborrow() }
-    }
-}
-
 #[stable(feature = "btree_range", since = "1.17.0")]
 impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
     fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
-        if self.inner.is_empty() { None } else { Some(unsafe { self.next_back_unchecked() }) }
+        self.inner.next_back_checked()
     }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
 impl<K, V> FusedIterator for RangeMut<'_, K, V> {}
 
-impl<'a, K, V> RangeMut<'a, K, V> {
-    unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
-        unsafe { self.inner.back.as_mut().unwrap_unchecked().next_back_unchecked() }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
     fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> BTreeMap<K, V> {
@@ -2036,6 +2016,20 @@ where
     }
 }
 
+#[stable(feature = "std_collections_from_array", since = "1.56.0")]
+impl<K: Ord, V, const N: usize> From<[(K, V); N]> for BTreeMap<K, V> {
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let map1 = BTreeMap::from([(1, 2), (3, 4)]);
+    /// let map2: BTreeMap<_, _> = [(1, 2), (3, 4)].into();
+    /// assert_eq!(map1, map2);
+    /// ```
+    fn from(arr: [(K, V); N]) -> Self {
+        core::array::IntoIter::new(arr).collect()
+    }
+}
+
 impl<K, V> BTreeMap<K, V> {
     /// Gets an iterator over the entries of the map, sorted by key.
     ///
@@ -2063,9 +2057,9 @@ impl<K, V> BTreeMap<K, V> {
         if let Some(root) = &self.root {
             let full_range = root.reborrow().full_range();
 
-            Iter { range: Range { inner: full_range }, length: self.length }
+            Iter { range: full_range, length: self.length }
         } else {
-            Iter { range: Range { inner: LeafRange::none() }, length: 0 }
+            Iter { range: LazyLeafRange::none(), length: 0 }
         }
     }
 
@@ -2095,15 +2089,9 @@ impl<K, V> BTreeMap<K, V> {
         if let Some(root) = &mut self.root {
             let full_range = root.borrow_valmut().full_range();
 
-            IterMut {
-                range: RangeMut { inner: full_range, _marker: PhantomData },
-                length: self.length,
-            }
+            IterMut { range: full_range, length: self.length, _marker: PhantomData }
         } else {
-            IterMut {
-                range: RangeMut { inner: LeafRange::none(), _marker: PhantomData },
-                length: 0,
-            }
+            IterMut { range: LazyLeafRange::none(), length: 0, _marker: PhantomData }
         }
     }
 
@@ -2189,7 +2177,6 @@ impl<K, V> BTreeMap<K, V> {
     /// a.insert(1, "a");
     /// assert_eq!(a.len(), 1);
     /// ```
-    #[doc(alias = "length")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")]
     pub const fn len(&self) -> usize {
diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs
index 6b30d959773..5fec8dc2d13 100644
--- a/library/alloc/src/collections/btree/map/entry.rs
+++ b/library/alloc/src/collections/btree/map/entry.rs
@@ -14,6 +14,7 @@ use Entry::*;
 ///
 /// [`entry`]: BTreeMap::entry
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeEntry")]
 pub enum Entry<'a, K: 'a, V: 'a> {
     /// A vacant entry.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index 3a74b6a6fa8..17e53848343 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -1786,13 +1786,6 @@ fn test_ord_absence() {
     }
 }
 
-#[allow(dead_code)]
-fn test_const() {
-    const MAP: &'static BTreeMap<(), ()> = &BTreeMap::new();
-    const LEN: usize = MAP.len();
-    const IS_EMPTY: bool = MAP.is_empty();
-}
-
 #[test]
 fn test_occupied_entry_key() {
     let mut a = BTreeMap::new();
@@ -2173,3 +2166,10 @@ fn test_insert_remove_intertwined_ord_chaos() {
     }
     map.check_invariants();
 }
+
+#[test]
+fn from_array() {
+    let map = BTreeMap::from([(1, 2), (3, 4)]);
+    let unordered_duplicates = BTreeMap::from([(3, 4), (1, 2), (1, 2)]);
+    assert_eq!(map, unordered_duplicates);
+}
diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs
index 563c070dd0f..7b1d4d68c4f 100644
--- a/library/alloc/src/collections/btree/navigate.rs
+++ b/library/alloc/src/collections/btree/navigate.rs
@@ -1,12 +1,20 @@
 use core::borrow::Borrow;
+use core::hint;
 use core::ops::RangeBounds;
 use core::ptr;
 
 use super::node::{marker, ForceResult::*, Handle, NodeRef};
 
+// `front` and `back` are always both `None` or both `Some`.
 pub struct LeafRange<BorrowType, K, V> {
-    pub front: Option<Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>>,
-    pub back: Option<Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>>,
+    front: Option<Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>>,
+    back: Option<Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>>,
+}
+
+impl<'a, K: 'a, V: 'a> Clone for LeafRange<marker::Immut<'a>, K, V> {
+    fn clone(&self) -> Self {
+        LeafRange { front: self.front.clone(), back: self.back.clone() }
+    }
 }
 
 impl<BorrowType, K, V> LeafRange<BorrowType, K, V> {
@@ -14,7 +22,7 @@ impl<BorrowType, K, V> LeafRange<BorrowType, K, V> {
         LeafRange { front: None, back: None }
     }
 
-    pub fn is_empty(&self) -> bool {
+    fn is_empty(&self) -> bool {
         self.front == self.back
     }
 
@@ -27,6 +35,203 @@ impl<BorrowType, K, V> LeafRange<BorrowType, K, V> {
     }
 }
 
+impl<'a, K, V> LeafRange<marker::Immut<'a>, K, V> {
+    #[inline]
+    pub fn next_checked(&mut self) -> Option<(&'a K, &'a V)> {
+        self.perform_next_checked(|kv| kv.into_kv())
+    }
+
+    #[inline]
+    pub fn next_back_checked(&mut self) -> Option<(&'a K, &'a V)> {
+        self.perform_next_back_checked(|kv| kv.into_kv())
+    }
+}
+
+impl<'a, K, V> LeafRange<marker::ValMut<'a>, K, V> {
+    #[inline]
+    pub fn next_checked(&mut self) -> Option<(&'a K, &'a mut V)> {
+        self.perform_next_checked(|kv| unsafe { ptr::read(kv) }.into_kv_valmut())
+    }
+
+    #[inline]
+    pub fn next_back_checked(&mut self) -> Option<(&'a K, &'a mut V)> {
+        self.perform_next_back_checked(|kv| unsafe { ptr::read(kv) }.into_kv_valmut())
+    }
+}
+
+impl<BorrowType: marker::BorrowType, K, V> LeafRange<BorrowType, K, V> {
+    /// If possible, extract some result from the following KV and move to the edge beyond it.
+    fn perform_next_checked<F, R>(&mut self, f: F) -> Option<R>
+    where
+        F: Fn(&Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::KV>) -> R,
+    {
+        if self.is_empty() {
+            None
+        } else {
+            super::mem::replace(self.front.as_mut().unwrap(), |front| {
+                let kv = front.next_kv().ok().unwrap();
+                let result = f(&kv);
+                (kv.next_leaf_edge(), Some(result))
+            })
+        }
+    }
+
+    /// If possible, extract some result from the preceding KV and move to the edge beyond it.
+    fn perform_next_back_checked<F, R>(&mut self, f: F) -> Option<R>
+    where
+        F: Fn(&Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::KV>) -> R,
+    {
+        if self.is_empty() {
+            None
+        } else {
+            super::mem::replace(self.back.as_mut().unwrap(), |back| {
+                let kv = back.next_back_kv().ok().unwrap();
+                let result = f(&kv);
+                (kv.next_back_leaf_edge(), Some(result))
+            })
+        }
+    }
+}
+
+enum LazyLeafHandle<BorrowType, K, V> {
+    Root(NodeRef<BorrowType, K, V, marker::LeafOrInternal>), // not yet descended
+    Edge(Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>),
+}
+
+impl<'a, K: 'a, V: 'a> Clone for LazyLeafHandle<marker::Immut<'a>, K, V> {
+    fn clone(&self) -> Self {
+        match self {
+            LazyLeafHandle::Root(root) => LazyLeafHandle::Root(*root),
+            LazyLeafHandle::Edge(edge) => LazyLeafHandle::Edge(*edge),
+        }
+    }
+}
+
+impl<BorrowType, K, V> LazyLeafHandle<BorrowType, K, V> {
+    fn reborrow(&self) -> LazyLeafHandle<marker::Immut<'_>, K, V> {
+        match self {
+            LazyLeafHandle::Root(root) => LazyLeafHandle::Root(root.reborrow()),
+            LazyLeafHandle::Edge(edge) => LazyLeafHandle::Edge(edge.reborrow()),
+        }
+    }
+}
+
+// `front` and `back` are always both `None` or both `Some`.
+pub struct LazyLeafRange<BorrowType, K, V> {
+    front: Option<LazyLeafHandle<BorrowType, K, V>>,
+    back: Option<LazyLeafHandle<BorrowType, K, V>>,
+}
+
+impl<'a, K: 'a, V: 'a> Clone for LazyLeafRange<marker::Immut<'a>, K, V> {
+    fn clone(&self) -> Self {
+        LazyLeafRange { front: self.front.clone(), back: self.back.clone() }
+    }
+}
+
+impl<BorrowType, K, V> LazyLeafRange<BorrowType, K, V> {
+    pub fn none() -> Self {
+        LazyLeafRange { front: None, back: None }
+    }
+
+    /// Temporarily takes out another, immutable equivalent of the same range.
+    pub fn reborrow(&self) -> LazyLeafRange<marker::Immut<'_>, K, V> {
+        LazyLeafRange {
+            front: self.front.as_ref().map(|f| f.reborrow()),
+            back: self.back.as_ref().map(|b| b.reborrow()),
+        }
+    }
+}
+
+impl<'a, K, V> LazyLeafRange<marker::Immut<'a>, K, V> {
+    #[inline]
+    pub unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
+        unsafe { self.init_front().unwrap().next_unchecked() }
+    }
+
+    #[inline]
+    pub unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
+        unsafe { self.init_back().unwrap().next_back_unchecked() }
+    }
+}
+
+impl<'a, K, V> LazyLeafRange<marker::ValMut<'a>, K, V> {
+    #[inline]
+    pub unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
+        unsafe { self.init_front().unwrap().next_unchecked() }
+    }
+
+    #[inline]
+    pub unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
+        unsafe { self.init_back().unwrap().next_back_unchecked() }
+    }
+}
+
+impl<K, V> LazyLeafRange<marker::Dying, K, V> {
+    fn take_front(
+        &mut self,
+    ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge>> {
+        match self.front.take()? {
+            LazyLeafHandle::Root(root) => Some(root.first_leaf_edge()),
+            LazyLeafHandle::Edge(edge) => Some(edge),
+        }
+    }
+
+    #[inline]
+    pub unsafe fn deallocating_next_unchecked(
+        &mut self,
+    ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
+        debug_assert!(self.front.is_some());
+        let front = self.init_front().unwrap();
+        unsafe { front.deallocating_next_unchecked() }
+    }
+
+    #[inline]
+    pub unsafe fn deallocating_next_back_unchecked(
+        &mut self,
+    ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
+        debug_assert!(self.back.is_some());
+        let back = self.init_back().unwrap();
+        unsafe { back.deallocating_next_back_unchecked() }
+    }
+
+    #[inline]
+    pub fn deallocating_end(&mut self) {
+        if let Some(front) = self.take_front() {
+            front.deallocating_end()
+        }
+    }
+}
+
+impl<BorrowType: marker::BorrowType, K, V> LazyLeafRange<BorrowType, K, V> {
+    fn init_front(
+        &mut self,
+    ) -> Option<&mut Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>> {
+        if let Some(LazyLeafHandle::Root(root)) = &self.front {
+            self.front = Some(LazyLeafHandle::Edge(unsafe { ptr::read(root) }.first_leaf_edge()));
+        }
+        match &mut self.front {
+            None => None,
+            Some(LazyLeafHandle::Edge(edge)) => Some(edge),
+            // SAFETY: the code above would have replaced it.
+            Some(LazyLeafHandle::Root(_)) => unsafe { hint::unreachable_unchecked() },
+        }
+    }
+
+    fn init_back(
+        &mut self,
+    ) -> Option<&mut Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>> {
+        if let Some(LazyLeafHandle::Root(root)) = &self.back {
+            self.back = Some(LazyLeafHandle::Edge(unsafe { ptr::read(root) }.last_leaf_edge()));
+        }
+        match &mut self.back {
+            None => None,
+            Some(LazyLeafHandle::Edge(edge)) => Some(edge),
+            // SAFETY: the code above would have replaced it.
+            Some(LazyLeafHandle::Root(_)) => unsafe { hint::unreachable_unchecked() },
+        }
+    }
+}
+
 impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
     /// Finds the distinct leaf edges delimiting a specified range in a tree.
     ///
@@ -36,7 +241,7 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
     /// result will eventually reach the same edge.
     ///
     /// If there are no such edges, i.e., if the tree contains no key within
-    /// the range, returns a pair of empty options.
+    /// the range, returns an empty `front` and `back`.
     ///
     /// # Safety
     /// Unless `BorrowType` is `Immut`, do not use the handles to visit the same
@@ -78,26 +283,13 @@ impl<BorrowType: marker::BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Lea
     }
 }
 
-/// Equivalent to `(root1.first_leaf_edge(), root2.last_leaf_edge())` but more efficient.
 fn full_range<BorrowType: marker::BorrowType, K, V>(
     root1: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
     root2: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
-) -> LeafRange<BorrowType, K, V> {
-    let mut min_node = root1;
-    let mut max_node = root2;
-    loop {
-        let front = min_node.first_edge();
-        let back = max_node.last_edge();
-        match (front.force(), back.force()) {
-            (Leaf(f), Leaf(b)) => {
-                return LeafRange { front: Some(f), back: Some(b) };
-            }
-            (Internal(min_int), Internal(max_int)) => {
-                min_node = min_int.descend();
-                max_node = max_int.descend();
-            }
-            _ => unreachable!("BTreeMap has different depths"),
-        };
+) -> LazyLeafRange<BorrowType, K, V> {
+    LazyLeafRange {
+        front: Some(LazyLeafHandle::Root(root1)),
+        back: Some(LazyLeafHandle::Root(root2)),
     }
 }
 
@@ -117,7 +309,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>
     }
 
     /// Finds the pair of leaf edges delimiting an entire tree.
-    pub fn full_range(self) -> LeafRange<marker::Immut<'a>, K, V> {
+    pub fn full_range(self) -> LazyLeafRange<marker::Immut<'a>, K, V> {
         full_range(self, self)
     }
 }
@@ -144,7 +336,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::ValMut<'a>, K, V, marker::LeafOrInternal>
     /// Splits a unique reference into a pair of leaf edges delimiting the full range of the tree.
     /// The results are non-unique references allowing mutation (of values only), so must be used
     /// with care.
-    pub fn full_range(self) -> LeafRange<marker::ValMut<'a>, K, V> {
+    pub fn full_range(self) -> LazyLeafRange<marker::ValMut<'a>, K, V> {
         // We duplicate the root NodeRef here -- we will never visit the same KV
         // twice, and never end up with overlapping value references.
         let self2 = unsafe { ptr::read(&self) };
@@ -156,7 +348,7 @@ impl<K, V> NodeRef<marker::Dying, K, V, marker::LeafOrInternal> {
     /// Splits a unique reference into a pair of leaf edges delimiting the full range of the tree.
     /// The results are non-unique references allowing massively destructive mutation, so must be
     /// used with the utmost care.
-    pub fn full_range(self) -> LeafRange<marker::Dying, K, V> {
+    pub fn full_range(self) -> LazyLeafRange<marker::Dying, K, V> {
         // We duplicate the root NodeRef here -- we will never access it in a way
         // that overlaps references obtained from the root.
         let self2 = unsafe { ptr::read(&self) };
@@ -191,7 +383,7 @@ impl<BorrowType: marker::BorrowType, K, V>
     /// Given a leaf edge handle, returns [`Result::Ok`] with a handle to the neighboring KV
     /// on the left side, which is either in the same leaf node or in an ancestor node.
     /// If the leaf edge is the first one in the tree, returns [`Result::Err`] with the root node.
-    pub fn next_back_kv(
+    fn next_back_kv(
         self,
     ) -> Result<
         Handle<NodeRef<BorrowType, K, V, marker::LeafOrInternal>, marker::KV>,
@@ -216,7 +408,7 @@ impl<BorrowType: marker::BorrowType, K, V>
     /// Given an internal edge handle, returns [`Result::Ok`] with a handle to the neighboring KV
     /// on the right side, which is either in the same internal node or in an ancestor node.
     /// If the internal edge is the last one in the tree, returns [`Result::Err`] with the root node.
-    pub fn next_kv(
+    fn next_kv(
         self,
     ) -> Result<
         Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::KV>,
@@ -250,7 +442,7 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
     /// - The returned KV handle is only valid to access the key and value,
     ///   and only valid until the next call to this method or counterpart
     ///   `deallocating_next_back`.
-    pub unsafe fn deallocating_next(
+    unsafe fn deallocating_next(
         self,
     ) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>
     {
@@ -302,7 +494,7 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
     /// both sides of the tree, and have hit the same edge. As it is intended
     /// only to be called when all keys and values have been returned,
     /// no cleanup is done on any of the keys or values.
-    pub fn deallocating_end(self) {
+    fn deallocating_end(self) {
         let mut edge = self.forget_node_type();
         while let Some(parent_edge) = unsafe { edge.into_node().deallocate_and_ascend() } {
             edge = parent_edge.forget_node_type();
@@ -316,10 +508,9 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
     ///
     /// # Safety
     /// There must be another KV in the direction travelled.
-    pub unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
+    unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) {
         super::mem::replace(self, |leaf_edge| {
-            let kv = leaf_edge.next_kv();
-            let kv = unsafe { kv.ok().unwrap_unchecked() };
+            let kv = leaf_edge.next_kv().ok().unwrap();
             (kv.next_leaf_edge(), kv.into_kv())
         })
     }
@@ -329,10 +520,9 @@ impl<'a, K, V> Handle<NodeRef<marker::Immut<'a>, K, V, marker::Leaf>, marker::Ed
     ///
     /// # Safety
     /// There must be another KV in the direction travelled.
-    pub unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
+    unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) {
         super::mem::replace(self, |leaf_edge| {
-            let kv = leaf_edge.next_back_kv();
-            let kv = unsafe { kv.ok().unwrap_unchecked() };
+            let kv = leaf_edge.next_back_kv().ok().unwrap();
             (kv.next_back_leaf_edge(), kv.into_kv())
         })
     }
@@ -344,10 +534,9 @@ impl<'a, K, V> Handle<NodeRef<marker::ValMut<'a>, K, V, marker::Leaf>, marker::E
     ///
     /// # Safety
     /// There must be another KV in the direction travelled.
-    pub unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
+    unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
         let kv = super::mem::replace(self, |leaf_edge| {
-            let kv = leaf_edge.next_kv();
-            let kv = unsafe { kv.ok().unwrap_unchecked() };
+            let kv = leaf_edge.next_kv().ok().unwrap();
             (unsafe { ptr::read(&kv) }.next_leaf_edge(), kv)
         });
         // Doing this last is faster, according to benchmarks.
@@ -359,10 +548,9 @@ impl<'a, K, V> Handle<NodeRef<marker::ValMut<'a>, K, V, marker::Leaf>, marker::E
     ///
     /// # Safety
     /// There must be another KV in the direction travelled.
-    pub unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
+    unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) {
         let kv = super::mem::replace(self, |leaf_edge| {
-            let kv = leaf_edge.next_back_kv();
-            let kv = unsafe { kv.ok().unwrap_unchecked() };
+            let kv = leaf_edge.next_back_kv().ok().unwrap();
             (unsafe { ptr::read(&kv) }.next_back_leaf_edge(), kv)
         });
         // Doing this last is faster, according to benchmarks.
@@ -383,12 +571,10 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
     ///
     /// The only safe way to proceed with the updated handle is to compare it, drop it,
     /// or call this method or counterpart `deallocating_next_back_unchecked` again.
-    pub unsafe fn deallocating_next_unchecked(
+    unsafe fn deallocating_next_unchecked(
         &mut self,
     ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
-        super::mem::replace(self, |leaf_edge| unsafe {
-            leaf_edge.deallocating_next().unwrap_unchecked()
-        })
+        super::mem::replace(self, |leaf_edge| unsafe { leaf_edge.deallocating_next().unwrap() })
     }
 
     /// Moves the leaf edge handle to the previous leaf edge and returns the key and value
@@ -403,11 +589,11 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
     ///
     /// The only safe way to proceed with the updated handle is to compare it, drop it,
     /// or call this method or counterpart `deallocating_next_unchecked` again.
-    pub unsafe fn deallocating_next_back_unchecked(
+    unsafe fn deallocating_next_back_unchecked(
         &mut self,
     ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
         super::mem::replace(self, |leaf_edge| unsafe {
-            leaf_edge.deallocating_next_back().unwrap_unchecked()
+            leaf_edge.deallocating_next_back().unwrap()
         })
     }
 }
@@ -508,9 +694,7 @@ impl<BorrowType: marker::BorrowType, K, V>
     }
 
     /// Returns the leaf edge closest to a KV for backward navigation.
-    pub fn next_back_leaf_edge(
-        self,
-    ) -> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
+    fn next_back_leaf_edge(self) -> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge> {
         match self.force() {
             Leaf(leaf_kv) => leaf_kv.left_edge(),
             Internal(internal_kv) => {
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 3c453529ba8..8f6a2ec9ebd 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -167,7 +167,7 @@ type BoxedNode<K, V> = NonNull<LeafNode<K, V>>;
 ///   carry a lifetime, because we want it to return `&'a` references.
 ///   Therefore, we define it only for the least powerful type `Immut<'a>`.
 /// - We cannot get implicit coercion from say `Mut<'a>` to `Immut<'a>`.
-///   Therefore, we have to explicitly call `reborrow` on a more powerfull
+///   Therefore, we have to explicitly call `reborrow` on a more powerful
 ///   `NodeRef` in order to reach a method like `into_kv`.
 ///
 /// All methods on `NodeRef` that return some kind of reference, either:
@@ -409,7 +409,7 @@ impl<K, V> NodeRef<marker::Dying, K, V, marker::LeafOrInternal> {
 
 impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
     /// Temporarily takes out another mutable reference to the same node. Beware, as
-    /// this method is very dangerous, doubly so since it may not immediately appear
+    /// this method is very dangerous, doubly so since it might not immediately appear
     /// dangerous.
     ///
     /// Because mutable pointers can roam anywhere around the tree, the returned
@@ -777,7 +777,7 @@ impl<BorrowType, K, V, NodeType, HandleType>
 
 impl<'a, K, V, NodeType, HandleType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, HandleType> {
     /// Temporarily takes out another mutable handle on the same location. Beware, as
-    /// this method is very dangerous, doubly so since it may not immediately appear
+    /// this method is very dangerous, doubly so since it might not immediately appear
     /// dangerous.
     ///
     /// For details, see `NodeRef::reborrow_mut`.
@@ -1058,7 +1058,9 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>
 
 impl<K, V, NodeType> Handle<NodeRef<marker::Dying, K, V, NodeType>, marker::KV> {
     /// Extracts the key and value that the KV handle refers to.
-    pub fn into_key_val(mut self) -> (K, V) {
+    /// # Safety
+    /// The node that the handle refers to must not yet have been deallocated.
+    pub unsafe fn into_key_val(mut self) -> (K, V) {
         debug_assert!(self.idx < self.node.len());
         let leaf = self.node.as_leaf_dying();
         unsafe {
@@ -1069,8 +1071,10 @@ impl<K, V, NodeType> Handle<NodeRef<marker::Dying, K, V, NodeType>, marker::KV>
     }
 
     /// Drops the key and value that the KV handle refers to.
+    /// # Safety
+    /// The node that the handle refers to must not yet have been deallocated.
     #[inline]
-    pub fn drop_key_val(mut self) {
+    pub unsafe fn drop_key_val(mut self) {
         debug_assert!(self.idx < self.node.len());
         let leaf = self.node.as_leaf_dying();
         unsafe {
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 737932d931c..0c268ad32b2 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -59,6 +59,14 @@ use super::Recover;
 ///     println!("{}", book);
 /// }
 /// ```
+///
+/// A `BTreeSet` with a known list of items can be initialized from an array:
+///
+/// ```
+/// use std::collections::BTreeSet;
+///
+/// let set = BTreeSet::from([1, 2, 3]);
+/// ```
 #[derive(Hash, PartialEq, Eq, Ord, PartialOrd)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "BTreeSet")]
@@ -810,7 +818,6 @@ impl<T> BTreeSet<T> {
     /// assert_eq!(set.remove(&2), true);
     /// assert_eq!(set.remove(&2), false);
     /// ```
-    #[doc(alias = "delete")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
     where
@@ -847,6 +854,7 @@ impl<T> BTreeSet<T> {
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+    /// The elements are visited in ascending order.
     ///
     /// # Examples
     ///
@@ -904,8 +912,8 @@ impl<T> BTreeSet<T> {
         self.map.append(&mut other.map);
     }
 
-    /// Splits the collection into two at the given key. Returns everything after the given key,
-    /// including the key.
+    /// Splits the collection into two at the given value. Returns everything after the given value,
+    /// including the value.
     ///
     /// # Examples
     ///
@@ -934,25 +942,27 @@ impl<T> BTreeSet<T> {
     /// assert!(b.contains(&41));
     /// ```
     #[stable(feature = "btree_split_off", since = "1.11.0")]
-    pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self
+    pub fn split_off<Q: ?Sized + Ord>(&mut self, value: &Q) -> Self
     where
         T: Borrow<Q> + Ord,
     {
-        BTreeSet { map: self.map.split_off(key) }
+        BTreeSet { map: self.map.split_off(value) }
     }
 
-    /// Creates an iterator which uses a closure to determine if a value should be removed.
+    /// Creates an iterator that visits all values in ascending order and uses a closure
+    /// to determine if a value should be removed.
     ///
-    /// If the closure returns true, then the value is removed and yielded.
-    /// If the closure returns false, the value will remain in the list and will not be yielded
-    /// by the iterator.
+    /// If the closure returns `true`, the value is removed from the set and yielded. If
+    /// the closure returns `false`, or panics, the value remains in the set and will
+    /// not be yielded.
     ///
-    /// If the iterator is only partially consumed or not consumed at all, each of the remaining
-    /// values will still be subjected to the closure and removed and dropped if it returns true.
+    /// If the iterator is only partially consumed or not consumed at all, each of the
+    /// remaining values is still subjected to the closure and removed and dropped if it
+    /// returns `true`.
     ///
-    /// It is unspecified how many more values will be subjected to the closure
-    /// if a panic occurs in the closure, or if a panic occurs while dropping a value, or if the
-    /// `DrainFilter` itself is leaked.
+    /// It is unspecified how many more values will be subjected to the closure if a
+    /// panic occurs in the closure, or if a panic occurs while dropping a value, or if
+    /// the `DrainFilter` itself is leaked.
     ///
     /// # Examples
     ///
@@ -1021,7 +1031,6 @@ impl<T> BTreeSet<T> {
     /// v.insert(1);
     /// assert_eq!(v.len(), 1);
     /// ```
-    #[doc(alias = "length")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")]
     pub const fn len(&self) -> usize {
@@ -1056,6 +1065,20 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {
     }
 }
 
+#[stable(feature = "std_collections_from_array", since = "1.56.0")]
+impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let set1 = BTreeSet::from([1, 2, 3, 4]);
+    /// let set2: BTreeSet<_> = [1, 2, 3, 4].into();
+    /// assert_eq!(set1, set2);
+    /// ```
+    fn from(arr: [T; N]) -> Self {
+        core::array::IntoIter::new(arr).collect()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IntoIterator for BTreeSet<T> {
     type Item = T;
diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs
index 4cb6e3d6619..5d590a26281 100644
--- a/library/alloc/src/collections/btree/set/tests.rs
+++ b/library/alloc/src/collections/btree/set/tests.rs
@@ -16,13 +16,6 @@ fn test_clone_eq() {
     assert_eq!(m.clone(), m);
 }
 
-#[allow(dead_code)]
-fn test_const() {
-    const SET: &'static BTreeSet<()> = &BTreeSet::new();
-    const LEN: usize = SET.len();
-    const IS_EMPTY: bool = SET.is_empty();
-}
-
 #[test]
 fn test_iter_min_max() {
     let mut a = BTreeSet::new();
@@ -738,3 +731,10 @@ fn test_split_off_large_random_sorted() {
     assert!(set.into_iter().eq(data.clone().into_iter().filter(|x| *x < key)));
     assert!(right.into_iter().eq(data.into_iter().filter(|x| *x >= key)));
 }
+
+#[test]
+fn from_array() {
+    let set = BTreeSet::from([1, 2, 3, 4]);
+    let unordered_duplicates = BTreeSet::from([4, 1, 4, 3, 2]);
+    assert_eq!(set, unordered_duplicates);
+}
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 1a58ad51f78..7aa24ff4afa 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -31,6 +31,13 @@ mod tests;
 /// The `LinkedList` allows pushing and popping elements at either end
 /// in constant time.
 ///
+/// A `LinkedList` with a known list of items can be initialized from an array:
+/// ```
+/// use std::collections::LinkedList;
+///
+/// let list = LinkedList::from([1, 2, 3]);
+/// ```
+///
 /// NOTE: It is almost always better to use `Vec` or `VecDeque` because
 /// array-based containers are generally faster,
 /// more memory efficient, and make better use of CPU cache.
@@ -586,7 +593,6 @@ impl<T> LinkedList<T> {
     /// dl.push_back(3);
     /// assert_eq!(dl.len(), 3);
     /// ```
-    #[doc(alias = "length")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize {
@@ -1243,6 +1249,20 @@ impl<'a, T> Cursor<'a, T> {
             prev.map(|prev| &(*prev.as_ptr()).element)
         }
     }
+
+    /// Provides a reference to the front element of the cursor's parent list,
+    /// or None if the list is empty.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn front(&self) -> Option<&'a T> {
+        self.list.front()
+    }
+
+    /// Provides a reference to the back element of the cursor's parent list,
+    /// or None if the list is empty.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn back(&self) -> Option<&'a T> {
+        self.list.back()
+    }
 }
 
 impl<'a, T> CursorMut<'a, T> {
@@ -1506,6 +1526,135 @@ impl<'a, T> CursorMut<'a, T> {
         self.index = 0;
         unsafe { self.list.split_off_before_node(self.current, split_off_idx) }
     }
+
+    /// Appends an element to the front of the cursor's parent list. The node
+    /// that the cursor points to is unchanged, even if it is the "ghost" node.
+    ///
+    /// This operation should compute in O(1) time.
+    // `push_front` continues to point to "ghost" when it addes a node to mimic
+    // the behavior of `insert_before` on an empty list.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn push_front(&mut self, elt: T) {
+        // Safety: We know that `push_front` does not change the position in
+        // memory of other nodes. This ensures that `self.current` remains
+        // valid.
+        self.list.push_front(elt);
+        self.index += 1;
+    }
+
+    /// Appends an element to the back of the cursor's parent list. The node
+    /// that the cursor points to is unchanged, even if it is the "ghost" node.
+    ///
+    /// This operation should compute in O(1) time.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn push_back(&mut self, elt: T) {
+        // Safety: We know that `push_back` does not change the position in
+        // memory of other nodes. This ensures that `self.current` remains
+        // valid.
+        self.list.push_back(elt);
+        if self.current().is_none() {
+            // The index of "ghost" is the length of the list, so we just need
+            // to increment self.index to reflect the new length of the list.
+            self.index += 1;
+        }
+    }
+
+    /// Removes the first element from the cursor's parent list and returns it,
+    /// or None if the list is empty. The element the cursor points to remains
+    /// unchanged, unless it was pointing to the front element. In that case, it
+    /// points to the new front element.
+    ///
+    /// This operation should compute in O(1) time.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn pop_front(&mut self) -> Option<T> {
+        // We can't check if current is empty, we must check the list directly.
+        // It is possible for `self.current == None` and the list to be
+        // non-empty.
+        if self.list.is_empty() {
+            None
+        } else {
+            // We can't point to the node that we pop. Copying the behavior of
+            // `remove_current`, we move on the the next node in the sequence.
+            // If the list is of length 1 then we end pointing to the "ghost"
+            // node at index 0, which is expected.
+            if self.list.head == self.current {
+                self.move_next();
+            } else {
+                self.index -= 1;
+            }
+            self.list.pop_front()
+        }
+    }
+
+    /// Removes the last element from the cursor's parent list and returns it,
+    /// or None if the list is empty. The element the cursor points to remains
+    /// unchanged, unless it was pointing to the back element. In that case, it
+    /// points to the "ghost" element.
+    ///
+    /// This operation should compute in O(1) time.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn pop_back(&mut self) -> Option<T> {
+        if self.list.is_empty() {
+            None
+        } else {
+            if self.list.tail == self.current {
+                // The index now reflects the length of the list. It was the
+                // length of the list minus 1, but now the list is 1 smaller. No
+                // change is needed for `index`.
+                self.current = None;
+            } else if self.current.is_none() {
+                self.index = self.list.len - 1;
+            }
+            self.list.pop_back()
+        }
+    }
+
+    /// Provides a reference to the front element of the cursor's parent list,
+    /// or None if the list is empty.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn front(&self) -> Option<&T> {
+        self.list.front()
+    }
+
+    /// Provides a mutable reference to the front element of the cursor's
+    /// parent list, or None if the list is empty.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn front_mut(&mut self) -> Option<&mut T> {
+        self.list.front_mut()
+    }
+
+    /// Provides a reference to the back element of the cursor's parent list,
+    /// or None if the list is empty.
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn back(&self) -> Option<&T> {
+        self.list.back()
+    }
+
+    /// Provides a mutable reference to back element of the cursor's parent
+    /// list, or `None` if the list is empty.
+    ///
+    /// # Examples
+    /// Building and mutating a list with a cursor, then getting the back element:
+    /// ```
+    /// #![feature(linked_list_cursors)]
+    /// use std::collections::LinkedList;
+    /// let mut dl = LinkedList::new();
+    /// dl.push_front(3);
+    /// dl.push_front(2);
+    /// dl.push_front(1);
+    /// let mut cursor = dl.cursor_front_mut();
+    /// *cursor.current().unwrap() = 99;
+    /// *cursor.back_mut().unwrap() = 0;
+    /// let mut contents = dl.into_iter();
+    /// assert_eq!(contents.next(), Some(99));
+    /// assert_eq!(contents.next(), Some(2));
+    /// assert_eq!(contents.next(), Some(0));
+    /// assert_eq!(contents.next(), None);
+    /// ```
+    #[unstable(feature = "linked_list_cursors", issue = "58533")]
+    pub fn back_mut(&mut self) -> Option<&mut T> {
+        self.list.back_mut()
+    }
 }
 
 /// An iterator produced by calling `drain_filter` on LinkedList.
@@ -1759,6 +1908,20 @@ impl<T: Hash> Hash for LinkedList<T> {
     }
 }
 
+#[stable(feature = "std_collections_from_array", since = "1.56.0")]
+impl<T, const N: usize> From<[T; N]> for LinkedList<T> {
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let list1 = LinkedList::from([1, 2, 3, 4]);
+    /// let list2: LinkedList<_> = [1, 2, 3, 4].into();
+    /// assert_eq!(list1, list2);
+    /// ```
+    fn from(arr: [T; N]) -> Self {
+        core::array::IntoIter::new(arr).collect()
+    }
+}
+
 // Ensure that `LinkedList` and its read-only iterators are covariant in their type parameters.
 #[allow(dead_code)]
 fn assert_covariance() {
diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs
index ad643a7bdf1..5a65ed7a962 100644
--- a/library/alloc/src/collections/linked_list/tests.rs
+++ b/library/alloc/src/collections/linked_list/tests.rs
@@ -428,3 +428,50 @@ fn test_cursor_mut_insert() {
     check_links(&m);
     assert_eq!(m.iter().cloned().collect::<Vec<_>>(), &[200, 201, 202, 203, 1, 100, 101]);
 }
+
+#[test]
+fn test_cursor_push_front_back() {
+    let mut ll: LinkedList<u32> = LinkedList::new();
+    ll.extend(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+    let mut c = ll.cursor_front_mut();
+    assert_eq!(c.current(), Some(&mut 1));
+    assert_eq!(c.index(), Some(0));
+    c.push_front(0);
+    assert_eq!(c.current(), Some(&mut 1));
+    assert_eq!(c.peek_prev(), Some(&mut 0));
+    assert_eq!(c.index(), Some(1));
+    c.push_back(11);
+    drop(c);
+    let p = ll.cursor_back().front().unwrap();
+    assert_eq!(p, &0);
+    assert_eq!(ll, (0..12).collect());
+    check_links(&ll);
+}
+
+#[test]
+fn test_cursor_pop_front_back() {
+    let mut ll: LinkedList<u32> = LinkedList::new();
+    ll.extend(&[1, 2, 3, 4, 5, 6]);
+    let mut c = ll.cursor_back_mut();
+    assert_eq!(c.pop_front(), Some(1));
+    c.move_prev();
+    c.move_prev();
+    c.move_prev();
+    assert_eq!(c.pop_back(), Some(6));
+    let c = c.as_cursor();
+    assert_eq!(c.front(), Some(&2));
+    assert_eq!(c.back(), Some(&5));
+    assert_eq!(c.index(), Some(1));
+    drop(c);
+    assert_eq!(ll, (2..6).collect());
+    check_links(&ll);
+    let mut c = ll.cursor_back_mut();
+    assert_eq!(c.current(), Some(&mut 5));
+    assert_eq!(c.index, 3);
+    assert_eq!(c.pop_back(), Some(5));
+    assert_eq!(c.current(), None);
+    assert_eq!(c.index, 3);
+    assert_eq!(c.pop_back(), Some(4));
+    assert_eq!(c.current(), None);
+    assert_eq!(c.index, 2);
+}
diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs
index b9b3d650ea2..0d442011921 100644
--- a/library/alloc/src/collections/mod.rs
+++ b/library/alloc/src/collections/mod.rs
@@ -58,7 +58,31 @@ use core::fmt::Display;
 /// The error type for `try_reserve` methods.
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
-pub enum TryReserveError {
+pub struct TryReserveError {
+    kind: TryReserveErrorKind,
+}
+
+impl TryReserveError {
+    /// Details about the allocation that caused the error
+    #[inline]
+    #[unstable(
+        feature = "try_reserve_kind",
+        reason = "Uncertain how much info should be exposed",
+        issue = "48043"
+    )]
+    pub fn kind(&self) -> TryReserveErrorKind {
+        self.kind.clone()
+    }
+}
+
+/// Details of the allocation that caused a `TryReserveError`
+#[derive(Clone, PartialEq, Eq, Debug)]
+#[unstable(
+    feature = "try_reserve_kind",
+    reason = "Uncertain how much info should be exposed",
+    issue = "48043"
+)]
+pub enum TryReserveErrorKind {
     /// Error due to the computed capacity exceeding the collection's maximum
     /// (usually `isize::MAX` bytes).
     CapacityOverflow,
@@ -81,11 +105,24 @@ pub enum TryReserveError {
     },
 }
 
+#[unstable(
+    feature = "try_reserve_kind",
+    reason = "Uncertain how much info should be exposed",
+    issue = "48043"
+)]
+impl From<TryReserveErrorKind> for TryReserveError {
+    #[inline]
+    fn from(kind: TryReserveErrorKind) -> Self {
+        Self { kind }
+    }
+}
+
 #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
 impl From<LayoutError> for TryReserveError {
+    /// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`].
     #[inline]
     fn from(_: LayoutError) -> Self {
-        TryReserveError::CapacityOverflow
+        TryReserveErrorKind::CapacityOverflow.into()
     }
 }
 
@@ -96,11 +133,13 @@ impl Display for TryReserveError {
         fmt: &mut core::fmt::Formatter<'_>,
     ) -> core::result::Result<(), core::fmt::Error> {
         fmt.write_str("memory allocation failed")?;
-        let reason = match &self {
-            TryReserveError::CapacityOverflow => {
+        let reason = match self.kind {
+            TryReserveErrorKind::CapacityOverflow => {
                 " because the computed capacity exceeded the collection's maximum"
             }
-            TryReserveError::AllocError { .. } => " because the memory allocator returned a error",
+            TryReserveErrorKind::AllocError { .. } => {
+                " because the memory allocator returned a error"
+            }
         };
         fmt.write_str(reason)
     }
diff --git a/library/alloc/src/collections/vec_deque/drain.rs b/library/alloc/src/collections/vec_deque/drain.rs
index 4ffb435d1e3..dfa0227dea3 100644
--- a/library/alloc/src/collections/vec_deque/drain.rs
+++ b/library/alloc/src/collections/vec_deque/drain.rs
@@ -2,6 +2,8 @@ use core::iter::FusedIterator;
 use core::ptr::{self, NonNull};
 use core::{fmt, mem};
 
+use crate::alloc::{Allocator, Global};
+
 use super::{count, Iter, VecDeque};
 
 /// A draining iterator over the elements of a `VecDeque`.
@@ -11,15 +13,19 @@ use super::{count, Iter, VecDeque};
 ///
 /// [`drain`]: VecDeque::drain
 #[stable(feature = "drain", since = "1.6.0")]
-pub struct Drain<'a, T: 'a> {
+pub struct Drain<
+    'a,
+    T: 'a,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
     pub(crate) after_tail: usize,
     pub(crate) after_head: usize,
     pub(crate) iter: Iter<'a, T>,
-    pub(crate) deque: NonNull<VecDeque<T>>,
+    pub(crate) deque: NonNull<VecDeque<T, A>>,
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
-impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
+impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("Drain")
             .field(&self.after_tail)
@@ -30,16 +36,16 @@ impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
-unsafe impl<T: Sync> Sync for Drain<'_, T> {}
+unsafe impl<T: Sync, A: Allocator + Sync> Sync for Drain<'_, T, A> {}
 #[stable(feature = "drain", since = "1.6.0")]
-unsafe impl<T: Send> Send for Drain<'_, T> {}
+unsafe impl<T: Send, A: Allocator + Send> Send for Drain<'_, T, A> {}
 
 #[stable(feature = "drain", since = "1.6.0")]
-impl<T> Drop for Drain<'_, T> {
+impl<T, A: Allocator> Drop for Drain<'_, T, A> {
     fn drop(&mut self) {
-        struct DropGuard<'r, 'a, T>(&'r mut Drain<'a, T>);
+        struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>);
 
-        impl<'r, 'a, T> Drop for DropGuard<'r, 'a, T> {
+        impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
             fn drop(&mut self) {
                 self.0.for_each(drop);
 
@@ -96,7 +102,7 @@ impl<T> Drop for Drain<'_, T> {
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
-impl<T> Iterator for Drain<'_, T> {
+impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
     type Item = T;
 
     #[inline]
@@ -111,7 +117,7 @@ impl<T> Iterator for Drain<'_, T> {
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
-impl<T> DoubleEndedIterator for Drain<'_, T> {
+impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
     #[inline]
     fn next_back(&mut self) -> Option<T> {
         self.iter.next_back().map(|elt| unsafe { ptr::read(elt) })
@@ -119,7 +125,7 @@ impl<T> DoubleEndedIterator for Drain<'_, T> {
 }
 
 #[stable(feature = "drain", since = "1.6.0")]
-impl<T> ExactSizeIterator for Drain<'_, T> {}
+impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {}
 
 #[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for Drain<'_, T> {}
+impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs
index 1c635dd4f27..5f13c3bf303 100644
--- a/library/alloc/src/collections/vec_deque/into_iter.rs
+++ b/library/alloc/src/collections/vec_deque/into_iter.rs
@@ -1,5 +1,7 @@
 use core::fmt;
-use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
+use core::iter::{FusedIterator, TrustedLen};
+
+use crate::alloc::{Allocator, Global};
 
 use super::VecDeque;
 
@@ -11,19 +13,22 @@ use super::VecDeque;
 /// [`into_iter`]: VecDeque::into_iter
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct IntoIter<T> {
-    pub(crate) inner: VecDeque<T>,
+pub struct IntoIter<
+    T,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
+    pub(crate) inner: VecDeque<T, A>,
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
-impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
+impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_tuple("IntoIter").field(&self.inner).finish()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Iterator for IntoIter<T> {
+impl<T, A: Allocator> Iterator for IntoIter<T, A> {
     type Item = T;
 
     #[inline]
@@ -36,26 +41,10 @@ impl<T> Iterator for IntoIter<T> {
         let len = self.inner.len();
         (len, Some(len))
     }
-
-    #[inline]
-    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
-    where
-        Self: TrustedRandomAccess,
-    {
-        // Safety: The TrustedRandomAccess contract requires that callers only pass an index
-        // that is in bounds.
-        // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
-        // multiple repeated reads of the same index would be safe and the
-        // values are !Drop, thus won't suffer from double drops.
-        unsafe {
-            let idx = self.inner.wrap_add(self.inner.tail, idx);
-            self.inner.buffer_read(idx)
-        }
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> DoubleEndedIterator for IntoIter<T> {
+impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
     #[inline]
     fn next_back(&mut self) -> Option<T> {
         self.inner.pop_back()
@@ -63,25 +52,14 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> ExactSizeIterator for IntoIter<T> {
+impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
     fn is_empty(&self) -> bool {
         self.inner.is_empty()
     }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
-impl<T> FusedIterator for IntoIter<T> {}
+impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<T> TrustedLen for IntoIter<T> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
-// and thus we can't implement drop-handling
-unsafe impl<T> TrustedRandomAccess for IntoIter<T>
-where
-    T: Copy,
-{
-    const MAY_HAVE_SIDE_EFFECT: bool = false;
-}
+unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs
index f3eb228c9e3..edadd666edc 100644
--- a/library/alloc/src/collections/vec_deque/iter.rs
+++ b/library/alloc/src/collections/vec_deque/iter.rs
@@ -1,5 +1,5 @@
 use core::fmt;
-use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
+use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use core::ops::Try;
 
 use super::{count, wrap_index, RingSlices};
@@ -103,11 +103,9 @@ impl<'a, T> Iterator for Iter<'a, T> {
     }
 
     #[inline]
-    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
-    where
-        Self: TrustedRandomAccess,
-    {
-        // Safety: The TrustedRandomAccess contract requires that callers only  pass an index
+    #[doc(hidden)]
+    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+        // Safety: The TrustedRandomAccess contract requires that callers only pass an index
         // that is in bounds.
         unsafe {
             let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
@@ -176,6 +174,10 @@ unsafe impl<T> TrustedLen for Iter<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<T> TrustedRandomAccess for Iter<'_, T> {
+unsafe impl<T> TrustedRandomAccess for Iter<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<T> TrustedRandomAccessNoCoerce for Iter<'_, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs
index 9493676e66b..7700b31cf5b 100644
--- a/library/alloc/src/collections/vec_deque/iter_mut.rs
+++ b/library/alloc/src/collections/vec_deque/iter_mut.rs
@@ -1,5 +1,5 @@
 use core::fmt;
-use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
+use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use core::marker::PhantomData;
 
 use super::{count, wrap_index, RingSlices};
@@ -89,11 +89,9 @@ impl<'a, T> Iterator for IterMut<'a, T> {
     }
 
     #[inline]
-    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
-    where
-        Self: TrustedRandomAccess,
-    {
-        // Safety: The TrustedRandomAccess contract requires that callers only  pass an index
+    #[doc(hidden)]
+    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
+        // Safety: The TrustedRandomAccess contract requires that callers only pass an index
         // that is in bounds.
         unsafe {
             let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
@@ -145,6 +143,10 @@ unsafe impl<T> TrustedLen for IterMut<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<T> TrustedRandomAccess for IterMut<'_, T> {
+unsafe impl<T> TrustedRandomAccess for IterMut<'_, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<T> TrustedRandomAccessNoCoerce for IterMut<'_, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
diff --git a/library/alloc/src/collections/vec_deque/macros.rs b/library/alloc/src/collections/vec_deque/macros.rs
index 0d59d312cf4..5c7913073fe 100644
--- a/library/alloc/src/collections/vec_deque/macros.rs
+++ b/library/alloc/src/collections/vec_deque/macros.rs
@@ -1,9 +1,9 @@
 macro_rules! __impl_slice_eq1 {
     ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => {
         #[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")]
-        impl<A, B, $($vars)*> PartialEq<$rhs> for $lhs
+        impl<T, U, A: Allocator, $($vars)*> PartialEq<$rhs> for $lhs
         where
-            A: PartialEq<B>,
+            T: PartialEq<U>,
             $($constraints)*
         {
             fn eq(&self, other: &$rhs) -> bool {
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 5d03be35e46..9a2205420a1 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -17,7 +17,9 @@ use core::ops::{Index, IndexMut, Range, RangeBounds};
 use core::ptr::{self, NonNull};
 use core::slice;
 
+use crate::alloc::{Allocator, Global};
 use crate::collections::TryReserveError;
+use crate::collections::TryReserveErrorKind;
 use crate::raw_vec::RawVec;
 use crate::vec::Vec;
 
@@ -67,6 +69,14 @@ const MAXIMUM_ZST_CAPACITY: usize = 1 << (usize::BITS - 1); // Largest possible
 /// push onto the back in this manner, and iterating over `VecDeque` goes front
 /// to back.
 ///
+/// A `VecDeque` with a known list of items can be initialized from an array:
+///
+/// ```
+/// use std::collections::VecDeque;
+///
+/// let deq = VecDeque::from([-1, 0, 1]);
+/// ```
+///
 /// Since `VecDeque` is a ring buffer, its elements are not necessarily contiguous
 /// in memory. If you want to access the elements as a single slice, such as for
 /// efficient sorting, you can use [`make_contiguous`]. It rotates the `VecDeque`
@@ -80,7 +90,10 @@ const MAXIMUM_ZST_CAPACITY: usize = 1 << (usize::BITS - 1); // Largest possible
 /// [`make_contiguous`]: VecDeque::make_contiguous
 #[cfg_attr(not(test), rustc_diagnostic_item = "vecdeque_type")]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct VecDeque<T> {
+pub struct VecDeque<
+    T,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
+> {
     // tail and head are pointers into the buffer. Tail always points
     // to the first element that could be read, Head always points
     // to where data should be written.
@@ -88,13 +101,15 @@ pub struct VecDeque<T> {
     // is defined as the distance between the two.
     tail: usize,
     head: usize,
-    buf: RawVec<T>,
+    buf: RawVec<T, A>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Clone> Clone for VecDeque<T> {
-    fn clone(&self) -> VecDeque<T> {
-        self.iter().cloned().collect()
+impl<T: Clone, A: Allocator + Clone> Clone for VecDeque<T, A> {
+    fn clone(&self) -> Self {
+        let mut deq = Self::with_capacity_in(self.len(), self.allocator().clone());
+        deq.extend(self.iter().cloned());
+        deq
     }
 
     fn clone_from(&mut self, other: &Self) {
@@ -114,7 +129,7 @@ impl<T: Clone> Clone for VecDeque<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<#[may_dangle] T> Drop for VecDeque<T> {
+unsafe impl<#[may_dangle] T, A: Allocator> Drop for VecDeque<T, A> {
     fn drop(&mut self) {
         /// Runs the destructor for all items in the slice when it gets dropped (normally or
         /// during unwinding).
@@ -147,7 +162,7 @@ impl<T> Default for VecDeque<T> {
     }
 }
 
-impl<T> VecDeque<T> {
+impl<T, A: Allocator> VecDeque<T, A> {
     /// Marginally more convenient
     #[inline]
     fn ptr(&self) -> *mut T {
@@ -457,9 +472,10 @@ impl<T> VecDeque<T> {
     ///
     /// let vector: VecDeque<u32> = VecDeque::new();
     /// ```
+    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> VecDeque<T> {
-        VecDeque::with_capacity(INITIAL_CAPACITY)
+        VecDeque::new_in(Global)
     }
 
     /// Creates an empty `VecDeque` with space for at least `capacity` elements.
@@ -471,13 +487,45 @@ impl<T> VecDeque<T> {
     ///
     /// let vector: VecDeque<u32> = VecDeque::with_capacity(10);
     /// ```
+    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(capacity: usize) -> VecDeque<T> {
+        Self::with_capacity_in(capacity, Global)
+    }
+}
+
+impl<T, A: Allocator> VecDeque<T, A> {
+    /// Creates an empty `VecDeque`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let vector: VecDeque<u32> = VecDeque::new();
+    /// ```
+    #[inline]
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn new_in(alloc: A) -> VecDeque<T, A> {
+        VecDeque::with_capacity_in(INITIAL_CAPACITY, alloc)
+    }
+
+    /// Creates an empty `VecDeque` with space for at least `capacity` elements.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let vector: VecDeque<u32> = VecDeque::with_capacity(10);
+    /// ```
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque<T, A> {
         // +1 since the ringbuffer always leaves one space empty
         let cap = cmp::max(capacity + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
         assert!(cap > capacity, "capacity overflow");
 
-        VecDeque { tail: 0, head: 0, buf: RawVec::with_capacity(cap) }
+        VecDeque { tail: 0, head: 0, buf: RawVec::with_capacity_in(cap, alloc) }
     }
 
     /// Provides a reference to the element at the given index.
@@ -650,7 +698,9 @@ impl<T> VecDeque<T> {
     ///
     /// Note that the allocator may give the collection more space than it
     /// requests. Therefore, capacity can not be relied upon to be precisely
-    /// minimal. Prefer `reserve` if future insertions are expected.
+    /// minimal. Prefer [`reserve`] if future insertions are expected.
+    ///
+    /// [`reserve`]: VecDeque::reserve
     ///
     /// # Errors
     ///
@@ -724,7 +774,7 @@ impl<T> VecDeque<T> {
         let new_cap = used_cap
             .checked_add(additional)
             .and_then(|needed_cap| needed_cap.checked_next_power_of_two())
-            .ok_or(TryReserveError::CapacityOverflow)?;
+            .ok_or(TryReserveErrorKind::CapacityOverflow)?;
 
         if new_cap > old_cap {
             self.buf.try_reserve_exact(used_cap, new_cap - used_cap)?;
@@ -766,7 +816,6 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(shrink_to)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::with_capacity(15);
@@ -777,7 +826,7 @@ impl<T> VecDeque<T> {
     /// buf.shrink_to(0);
     /// assert!(buf.capacity() >= 4);
     /// ```
-    #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         let min_capacity = cmp::min(min_capacity, self.capacity());
         // We don't have to worry about an overflow as neither `self.len()` nor `self.capacity()`
@@ -904,6 +953,13 @@ impl<T> VecDeque<T> {
         }
     }
 
+    /// Returns a reference to the underlying allocator.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn allocator(&self) -> &A {
+        self.buf.allocator()
+    }
+
     /// Returns a front-to-back iterator.
     ///
     /// # Examples
@@ -1036,7 +1092,6 @@ impl<T> VecDeque<T> {
     /// v.push_back(1);
     /// assert_eq!(v.len(), 1);
     /// ```
-    #[doc(alias = "length")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize {
         count(self.tail, self.head, self.cap())
@@ -1177,7 +1232,7 @@ impl<T> VecDeque<T> {
     /// ```
     #[inline]
     #[stable(feature = "drain", since = "1.6.0")]
-    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T>
+    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
     where
         R: RangeBounds<usize>,
     {
@@ -1966,12 +2021,15 @@ impl<T> VecDeque<T> {
     #[inline]
     #[must_use = "use `.truncate()` if you don't need the other half"]
     #[stable(feature = "split_off", since = "1.4.0")]
-    pub fn split_off(&mut self, at: usize) -> Self {
+    pub fn split_off(&mut self, at: usize) -> Self
+    where
+        A: Clone,
+    {
         let len = self.len();
         assert!(at <= len, "`at` out of bounds");
 
         let other_len = len - at;
-        let mut other = VecDeque::with_capacity(other_len);
+        let mut other = VecDeque::with_capacity_in(other_len, self.allocator().clone());
 
         unsafe {
             let (first_half, second_half) = self.as_slices();
@@ -2051,7 +2109,8 @@ impl<T> VecDeque<T> {
     /// assert_eq!(buf, [2, 4]);
     /// ```
     ///
-    /// The exact order may be useful for tracking external state, like an index.
+    /// Because the elements are visited exactly once in the original order,
+    /// external state may be used to decide which elements to keep.
     ///
     /// ```
     /// use std::collections::VecDeque;
@@ -2060,8 +2119,8 @@ impl<T> VecDeque<T> {
     /// buf.extend(1..6);
     ///
     /// let keep = [false, true, true, false, true];
-    /// let mut i = 0;
-    /// buf.retain(|_| (keep[i], i += 1).0);
+    /// let mut iter = keep.iter();
+    /// buf.retain(|_| *iter.next().unwrap());
     /// assert_eq!(buf, [2, 3, 5]);
     /// ```
     #[stable(feature = "vec_deque_retain", since = "1.4.0")]
@@ -2594,7 +2653,7 @@ impl<T> VecDeque<T> {
     }
 }
 
-impl<T: Clone> VecDeque<T> {
+impl<T: Clone, A: Allocator> VecDeque<T, A> {
     /// Modifies the `VecDeque` in-place so that `len()` is equal to new_len,
     /// either by removing excess elements from the back or by appending clones of `value`
     /// to the back.
@@ -2638,8 +2697,8 @@ fn count(tail: usize, head: usize, size: usize) -> usize {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialEq> PartialEq for VecDeque<A> {
-    fn eq(&self, other: &VecDeque<A>) -> bool {
+impl<T: PartialEq, A: Allocator> PartialEq for VecDeque<T, A> {
+    fn eq(&self, other: &Self) -> bool {
         if self.len() != other.len() {
             return false;
         }
@@ -2677,32 +2736,32 @@ impl<A: PartialEq> PartialEq for VecDeque<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Eq> Eq for VecDeque<A> {}
+impl<T: Eq, A: Allocator> Eq for VecDeque<T, A> {}
 
-__impl_slice_eq1! { [] VecDeque<A>, Vec<B>, }
-__impl_slice_eq1! { [] VecDeque<A>, &[B], }
-__impl_slice_eq1! { [] VecDeque<A>, &mut [B], }
-__impl_slice_eq1! { [const N: usize] VecDeque<A>, [B; N], }
-__impl_slice_eq1! { [const N: usize] VecDeque<A>, &[B; N], }
-__impl_slice_eq1! { [const N: usize] VecDeque<A>, &mut [B; N], }
+__impl_slice_eq1! { [] VecDeque<T, A>, Vec<U, A>, }
+__impl_slice_eq1! { [] VecDeque<T, A>, &[U], }
+__impl_slice_eq1! { [] VecDeque<T, A>, &mut [U], }
+__impl_slice_eq1! { [const N: usize] VecDeque<T, A>, [U; N], }
+__impl_slice_eq1! { [const N: usize] VecDeque<T, A>, &[U; N], }
+__impl_slice_eq1! { [const N: usize] VecDeque<T, A>, &mut [U; N], }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialOrd> PartialOrd for VecDeque<A> {
-    fn partial_cmp(&self, other: &VecDeque<A>) -> Option<Ordering> {
+impl<T: PartialOrd, A: Allocator> PartialOrd for VecDeque<T, A> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
         self.iter().partial_cmp(other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Ord> Ord for VecDeque<A> {
+impl<T: Ord, A: Allocator> Ord for VecDeque<T, A> {
     #[inline]
-    fn cmp(&self, other: &VecDeque<A>) -> Ordering {
+    fn cmp(&self, other: &Self) -> Ordering {
         self.iter().cmp(other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Hash> Hash for VecDeque<A> {
+impl<T: Hash, A: Allocator> Hash for VecDeque<T, A> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         self.len().hash(state);
         // It's not possible to use Hash::hash_slice on slices
@@ -2716,26 +2775,26 @@ impl<A: Hash> Hash for VecDeque<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Index<usize> for VecDeque<A> {
-    type Output = A;
+impl<T, A: Allocator> Index<usize> for VecDeque<T, A> {
+    type Output = T;
 
     #[inline]
-    fn index(&self, index: usize) -> &A {
+    fn index(&self, index: usize) -> &T {
         self.get(index).expect("Out of bounds access")
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> IndexMut<usize> for VecDeque<A> {
+impl<T, A: Allocator> IndexMut<usize> for VecDeque<T, A> {
     #[inline]
-    fn index_mut(&mut self, index: usize) -> &mut A {
+    fn index_mut(&mut self, index: usize) -> &mut T {
         self.get_mut(index).expect("Out of bounds access")
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> FromIterator<A> for VecDeque<A> {
-    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> VecDeque<A> {
+impl<T> FromIterator<T> for VecDeque<T> {
+    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> VecDeque<T> {
         let iterator = iter.into_iter();
         let (lower, _) = iterator.size_hint();
         let mut deq = VecDeque::with_capacity(lower);
@@ -2745,19 +2804,19 @@ impl<A> FromIterator<A> for VecDeque<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for VecDeque<T> {
+impl<T, A: Allocator> IntoIterator for VecDeque<T, A> {
     type Item = T;
-    type IntoIter = IntoIter<T>;
+    type IntoIter = IntoIter<T, A>;
 
     /// Consumes the `VecDeque` into a front-to-back iterator yielding elements by
     /// value.
-    fn into_iter(self) -> IntoIter<T> {
+    fn into_iter(self) -> IntoIter<T, A> {
         IntoIter { inner: self }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a VecDeque<T> {
+impl<'a, T, A: Allocator> IntoIterator for &'a VecDeque<T, A> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
 
@@ -2767,7 +2826,7 @@ impl<'a, T> IntoIterator for &'a VecDeque<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
+impl<'a, T, A: Allocator> IntoIterator for &'a mut VecDeque<T, A> {
     type Item = &'a mut T;
     type IntoIter = IterMut<'a, T>;
 
@@ -2777,8 +2836,8 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Extend<A> for VecDeque<A> {
-    fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
+impl<T, A: Allocator> Extend<T> for VecDeque<T, A> {
+    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
         // This function should be the moral equivalent of:
         //
         //      for item in iter.into_iter() {
@@ -2800,7 +2859,7 @@ impl<A> Extend<A> for VecDeque<A> {
     }
 
     #[inline]
-    fn extend_one(&mut self, elem: A) {
+    fn extend_one(&mut self, elem: T) {
         self.push_back(elem);
     }
 
@@ -2811,7 +2870,7 @@ impl<A> Extend<A> for VecDeque<A> {
 }
 
 #[stable(feature = "extend_ref", since = "1.2.0")]
-impl<'a, T: 'a + Copy> Extend<&'a T> for VecDeque<T> {
+impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for VecDeque<T, A> {
     fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
         self.extend(iter.into_iter().cloned());
     }
@@ -2828,14 +2887,14 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for VecDeque<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
+impl<T: fmt::Debug, A: Allocator> fmt::Debug for VecDeque<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_list().entries(self).finish()
     }
 }
 
 #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")]
-impl<T> From<Vec<T>> for VecDeque<T> {
+impl<T, A: Allocator> From<Vec<T, A>> for VecDeque<T, A> {
     /// Turn a [`Vec<T>`] into a [`VecDeque<T>`].
     ///
     /// [`Vec<T>`]: crate::vec::Vec
@@ -2844,7 +2903,7 @@ impl<T> From<Vec<T>> for VecDeque<T> {
     /// This avoids reallocating where possible, but the conditions for that are
     /// strict, and subject to change, and so shouldn't be relied upon unless the
     /// `Vec<T>` came from `From<VecDeque<T>>` and hasn't been reallocated.
-    fn from(mut other: Vec<T>) -> Self {
+    fn from(mut other: Vec<T, A>) -> Self {
         let len = other.len();
         if mem::size_of::<T>() == 0 {
             // There's no actual allocation for ZSTs to worry about capacity,
@@ -2862,15 +2921,15 @@ impl<T> From<Vec<T>> for VecDeque<T> {
         }
 
         unsafe {
-            let (other_buf, len, capacity) = other.into_raw_parts();
-            let buf = RawVec::from_raw_parts(other_buf, capacity);
+            let (other_buf, len, capacity, alloc) = other.into_raw_parts_with_alloc();
+            let buf = RawVec::from_raw_parts_in(other_buf, capacity, alloc);
             VecDeque { tail: 0, head: len, buf }
         }
     }
 }
 
 #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")]
-impl<T> From<VecDeque<T>> for Vec<T> {
+impl<T, A: Allocator> From<VecDeque<T, A>> for Vec<T, A> {
     /// Turn a [`VecDeque<T>`] into a [`Vec<T>`].
     ///
     /// [`Vec<T>`]: crate::vec::Vec
@@ -2900,7 +2959,7 @@ impl<T> From<VecDeque<T>> for Vec<T> {
     /// assert_eq!(vec, [8, 9, 1, 2, 3, 4]);
     /// assert_eq!(vec.as_ptr(), ptr);
     /// ```
-    fn from(mut other: VecDeque<T>) -> Self {
+    fn from(mut other: VecDeque<T, A>) -> Self {
         other.make_contiguous();
 
         unsafe {
@@ -2908,11 +2967,26 @@ impl<T> From<VecDeque<T>> for Vec<T> {
             let buf = other.buf.ptr();
             let len = other.len();
             let cap = other.cap();
+            let alloc = ptr::read(other.allocator());
 
             if other.tail != 0 {
                 ptr::copy(buf.add(other.tail), buf, len);
             }
-            Vec::from_raw_parts(buf, len, cap)
+            Vec::from_raw_parts_in(buf, len, cap, alloc)
         }
     }
 }
+
+#[stable(feature = "std_collections_from_array", since = "1.56.0")]
+impl<T, const N: usize> From<[T; N]> for VecDeque<T> {
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let deq1 = VecDeque::from([1, 2, 3, 4]);
+    /// let deq2: VecDeque<_> = [1, 2, 3, 4].into();
+    /// assert_eq!(deq1, deq2);
+    /// ```
+    fn from(arr: [T; N]) -> Self {
+        core::array::IntoIter::new(arr).collect()
+    }
+}
diff --git a/library/alloc/src/collections/vec_deque/pair_slices.rs b/library/alloc/src/collections/vec_deque/pair_slices.rs
index 7b87090fb07..8e3ac9cfd1d 100644
--- a/library/alloc/src/collections/vec_deque/pair_slices.rs
+++ b/library/alloc/src/collections/vec_deque/pair_slices.rs
@@ -1,6 +1,8 @@
 use core::cmp::{self};
 use core::mem::replace;
 
+use crate::alloc::Allocator;
+
 use super::VecDeque;
 
 /// PairSlices pairs up equal length slice parts of two deques
@@ -25,7 +27,7 @@ pub struct PairSlices<'a, 'b, T> {
 }
 
 impl<'a, 'b, T> PairSlices<'a, 'b, T> {
-    pub fn from(to: &'a mut VecDeque<T>, from: &'b VecDeque<T>) -> Self {
+    pub fn from<A: Allocator>(to: &'a mut VecDeque<T, A>, from: &'b VecDeque<T, A>) -> Self {
         let (a0, a1) = to.as_mut_slices();
         let (b0, b1) = from.as_slices();
         PairSlices { a0, a1, b0, b1 }
diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs
index fd5ee189fbf..8c5125d2082 100644
--- a/library/alloc/src/fmt.rs
+++ b/library/alloc/src/fmt.rs
@@ -138,7 +138,7 @@
 //! the `0` flag (see below) is specified for numerics, then the implicit fill character is
 //! `0`.
 //!
-//! Note that alignment may not be implemented by some types. In particular, it
+//! Note that alignment might not be implemented by some types. In particular, it
 //! is not generally implemented for the `Debug` trait.  A good way to ensure
 //! padding is applied is to format your input, then pad this resulting string
 //! to obtain your output:
@@ -300,7 +300,7 @@
 //! count := parameter | integer
 //! parameter := argument '$'
 //! ```
-//! In the above grammar, `text` may not contain any `'{'` or `'}'` characters.
+//! In the above grammar, `text` must not contain any `'{'` or `'}'` characters.
 //!
 //! # Formatting traits
 //!
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index a04e7c8a498..1a387f291cc 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -56,6 +56,10 @@
 //! [`Rc`]: rc
 //! [`RefCell`]: core::cell
 
+// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
 #![allow(unused_attributes)]
 #![stable(feature = "alloc", since = "1.36.0")]
 #![doc(
@@ -81,6 +85,7 @@
 #![feature(allow_internal_unstable)]
 #![feature(arbitrary_self_types)]
 #![feature(async_stream)]
+#![cfg_attr(bootstrap, feature(bindings_after_at))]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(cfg_sanitize)]
@@ -90,6 +95,7 @@
 #![feature(const_fn_trait_bound)]
 #![feature(cow_is_borrowed)]
 #![feature(const_cow_is_borrowed)]
+#![feature(const_trait_impl)]
 #![feature(destructuring_assignment)]
 #![feature(dispatch_from_dyn)]
 #![feature(core_intrinsics)]
@@ -109,7 +115,6 @@
 #![feature(iter_zip)]
 #![feature(lang_items)]
 #![feature(layout_for_ptr)]
-#![feature(maybe_uninit_ref)]
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(nll)]
@@ -137,13 +142,12 @@
 #![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]
 #![feature(alloc_layout_extra)]
 #![feature(trusted_random_access)]
-#![cfg_attr(bootstrap, feature(try_trait))]
-#![cfg_attr(not(bootstrap), feature(try_trait_v2))]
-#![feature(min_type_alias_impl_trait)]
+#![feature(try_trait_v2)]
+#![cfg_attr(bootstrap, feature(min_type_alias_impl_trait))]
+#![cfg_attr(not(bootstrap), feature(type_alias_impl_trait))]
 #![feature(associated_type_bounds)]
 #![feature(slice_group_by)]
 #![feature(decl_macro)]
-#![feature(bindings_after_at)]
 // Allow testing this library
 
 #[cfg(test)]
diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs
index 6a64587a223..189da9f0639 100644
--- a/library/alloc/src/macros.rs
+++ b/library/alloc/src/macros.rs
@@ -35,8 +35,6 @@
 ///
 /// [`Vec`]: crate::vec::Vec
 #[cfg(not(test))]
-#[doc(alias = "alloc")]
-#[doc(alias = "malloc")]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(box_syntax, liballoc_internals)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 2e2c9b76bd4..3caada06f6b 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -13,7 +13,8 @@ use core::slice;
 use crate::alloc::handle_alloc_error;
 use crate::alloc::{Allocator, Global, Layout};
 use crate::boxed::Box;
-use crate::collections::TryReserveError::{self, *};
+use crate::collections::TryReserveError;
+use crate::collections::TryReserveErrorKind::*;
 
 #[cfg(test)]
 mod tests;
@@ -425,7 +426,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         if mem::size_of::<T>() == 0 {
             // Since we return a capacity of `usize::MAX` when `elem_size` is
             // 0, getting to here necessarily means the `RawVec` is overfull.
-            return Err(CapacityOverflow);
+            return Err(CapacityOverflow.into());
         }
 
         // Nothing we can really do about these checks, sadly.
@@ -451,7 +452,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         if mem::size_of::<T>() == 0 {
             // Since we return a capacity of `usize::MAX` when the type size is
             // 0, getting to here necessarily means the `RawVec` is overfull.
-            return Err(CapacityOverflow);
+            return Err(CapacityOverflow.into());
         }
 
         let cap = len.checked_add(additional).ok_or(CapacityOverflow)?;
@@ -463,7 +464,6 @@ impl<T, A: Allocator> RawVec<T, A> {
         Ok(())
     }
 
-    #[cfg(not(no_global_oom_handling))]
     fn shrink(&mut self, amount: usize) -> Result<(), TryReserveError> {
         assert!(amount <= self.capacity(), "Tried to shrink to a larger capacity");
 
@@ -472,10 +472,9 @@ impl<T, A: Allocator> RawVec<T, A> {
 
         let ptr = unsafe {
             let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
-            self.alloc.shrink(ptr, layout, new_layout).map_err(|_| TryReserveError::AllocError {
-                layout: new_layout,
-                non_exhaustive: (),
-            })?
+            self.alloc
+                .shrink(ptr, layout, new_layout)
+                .map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })?
         };
         self.set_ptr(ptr);
         Ok(())
@@ -511,7 +510,7 @@ where
         alloc.allocate(new_layout)
     };
 
-    memory.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () })
+    memory.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () }.into())
 }
 
 unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {
@@ -527,7 +526,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec<T, A> {
 #[cfg(not(no_global_oom_handling))]
 #[inline]
 fn handle_reserve(result: Result<(), TryReserveError>) {
-    match result {
+    match result.map_err(|e| e.kind()) {
         Err(CapacityOverflow) => capacity_overflow(),
         Err(AllocError { layout, .. }) => handle_alloc_error(layout),
         Ok(()) => { /* yay */ }
@@ -546,7 +545,7 @@ fn handle_reserve(result: Result<(), TryReserveError>) {
 #[inline]
 fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
     if usize::BITS < 64 && alloc_size > isize::MAX as usize {
-        Err(CapacityOverflow)
+        Err(CapacityOverflow.into())
     } else {
         Ok(())
     }
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index f131182a896..0b3079fa59d 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -262,6 +262,8 @@ use core::marker::{self, PhantomData, Unpin, Unsize};
 use core::mem::size_of_val;
 use core::mem::{self, align_of_val_raw, forget};
 use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver};
+use core::panic::{RefUnwindSafe, UnwindSafe};
+#[cfg(not(no_global_oom_handling))]
 use core::pin::Pin;
 use core::ptr::{self, NonNull};
 #[cfg(not(no_global_oom_handling))]
@@ -313,6 +315,9 @@ impl<T: ?Sized> !marker::Send for Rc<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !marker::Sync for Rc<T> {}
 
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
+
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
 
@@ -346,6 +351,7 @@ impl<T> Rc<T> {
     ///
     /// let five = Rc::new(5);
     /// ```
+    #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(value: T) -> Rc<T> {
         // There is an implicit weak pointer owned by all the strong
@@ -381,6 +387,7 @@ impl<T> Rc<T> {
     ///     }
     /// }
     /// ```
+    #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "arc_new_cyclic", issue = "75861")]
     pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Rc<T> {
         // Construct the inner in the "uninitialized" state with a single
@@ -577,6 +584,7 @@ impl<T> Rc<T> {
     }
     /// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
     /// `value` will be pinned in memory and unable to be moved.
+    #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn pin(value: T) -> Pin<Rc<T>> {
         unsafe { Pin::new_unchecked(Rc::new(value)) }
@@ -1473,6 +1481,7 @@ impl<T: ?Sized> Clone for Rc<T> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Rc<T> {
     /// Creates a new `Rc<T>`, with the `Default` value for `T`.
@@ -1731,6 +1740,7 @@ impl<T: ?Sized> fmt::Pointer for Rc<T> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_for_ptrs", since = "1.6.0")]
 impl<T> From<T> for Rc<T> {
     /// Converts a generic type `T` into a `Rc<T>`
@@ -2520,7 +2530,7 @@ unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
     // SAFETY: since the only unsized types possible are slices, trait objects,
     // and extern types, the input safety requirement is currently enough to
     // satisfy the requirements of align_of_val_raw; this is an implementation
-    // detail of the language that may not be relied upon outside of std.
+    // detail of the language that must not be relied upon outside of std.
     unsafe { data_offset_align(align_of_val_raw(ptr)) }
 }
 
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index dcd64899204..4c8ea6902ff 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -1042,7 +1042,7 @@ where
 }
 
 /// This merge sort borrows some (but not all) ideas from TimSort, which is described in detail
-/// [here](http://svn.python.org/projects/python/trunk/Objects/listsort.txt).
+/// [here](https://github.com/python/cpython/blob/main/Objects/listsort.txt).
 ///
 /// The algorithm identifies strictly descending and non-descending subsequences, which are called
 /// natural runs. There is a stack of pending runs yet to be merged. Each newly found run is pushed
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index 57279e81a95..62ba2e57655 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -396,7 +396,7 @@ impl str {
         return s;
 
         fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) {
-            // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
+            // See https://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
             // for the definition of `Final_Sigma`.
             debug_assert!('Σ'.len_utf8() == 2);
             let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev())
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index dbe5bc1da46..6568d9f9907 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -48,7 +48,7 @@ use core::fmt;
 use core::hash;
 #[cfg(not(no_global_oom_handling))]
 use core::iter::FromIterator;
-use core::iter::FusedIterator;
+use core::iter::{from_fn, FusedIterator};
 #[cfg(not(no_global_oom_handling))]
 use core::ops::Add;
 #[cfg(not(no_global_oom_handling))]
@@ -419,8 +419,6 @@ impl String {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[doc(alias = "alloc")]
-    #[doc(alias = "malloc")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(capacity: usize) -> String {
         String { vec: Vec::with_capacity(capacity) }
@@ -923,7 +921,7 @@ impl String {
     /// assert!(s.capacity() >= 10);
     /// ```
     ///
-    /// This may not actually increase the capacity:
+    /// This might not actually increase the capacity:
     ///
     /// ```
     /// let mut s = String::with_capacity(10);
@@ -971,7 +969,7 @@ impl String {
     /// assert!(s.capacity() >= 10);
     /// ```
     ///
-    /// This may not actually increase the capacity:
+    /// This might not actually increase the capacity:
     ///
     /// ```
     /// let mut s = String::with_capacity(10);
@@ -1037,7 +1035,9 @@ impl String {
     ///
     /// Note that the allocator may give the collection more space than it
     /// requests. Therefore, capacity can not be relied upon to be precisely
-    /// minimal. Prefer `reserve` if future insertions are expected.
+    /// minimal. Prefer [`reserve`] if future insertions are expected.
+    ///
+    /// [`reserve`]: String::reserve
     ///
     /// # Errors
     ///
@@ -1100,7 +1100,6 @@ impl String {
     /// # Examples
     ///
     /// ```
-    /// #![feature(shrink_to)]
     /// let mut s = String::from("foo");
     ///
     /// s.reserve(100);
@@ -1113,7 +1112,7 @@ impl String {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.vec.shrink_to(min_capacity)
     }
@@ -1290,32 +1289,49 @@ impl String {
     {
         use core::str::pattern::Searcher;
 
-        let matches = {
+        let rejections = {
             let mut searcher = pat.into_searcher(self);
-            let mut matches = Vec::new();
-
-            while let Some(m) = searcher.next_match() {
-                matches.push(m);
-            }
-
-            matches
+            // Per Searcher::next:
+            //
+            // A Match result needs to contain the whole matched pattern,
+            // however Reject results may be split up into arbitrary many
+            // adjacent fragments. Both ranges may have zero length.
+            //
+            // In practice the implementation of Searcher::next_match tends to
+            // be more efficient, so we use it here and do some work to invert
+            // matches into rejections since that's what we want to copy below.
+            let mut front = 0;
+            let rejections: Vec<_> = from_fn(|| {
+                let (start, end) = searcher.next_match()?;
+                let prev_front = front;
+                front = end;
+                Some((prev_front, start))
+            })
+            .collect();
+            rejections.into_iter().chain(core::iter::once((front, self.len())))
         };
 
-        let len = self.len();
-        let mut shrunk_by = 0;
+        let mut len = 0;
+        let ptr = self.vec.as_mut_ptr();
+
+        for (start, end) in rejections {
+            let count = end - start;
+            if start != len {
+                // SAFETY: per Searcher::next:
+                //
+                // The stream of Match and Reject values up to a Done will
+                // contain index ranges that are adjacent, non-overlapping,
+                // covering the whole haystack, and laying on utf8
+                // boundaries.
+                unsafe {
+                    ptr::copy(ptr.add(start), ptr.add(len), count);
+                }
+            }
+            len += count;
+        }
 
-        // SAFETY: start and end will be on utf8 byte boundaries per
-        // the Searcher docs
         unsafe {
-            for (start, end) in matches {
-                ptr::copy(
-                    self.vec.as_mut_ptr().add(end - shrunk_by),
-                    self.vec.as_mut_ptr().add(start - shrunk_by),
-                    len - end,
-                );
-                shrunk_by += end - start;
-            }
-            self.vec.set_len(len - shrunk_by);
+            self.vec.set_len(len);
         }
     }
 
@@ -1335,13 +1351,14 @@ impl String {
     /// assert_eq!(s, "foobar");
     /// ```
     ///
-    /// The exact order may be useful for tracking external state, like an index.
+    /// Because the elements are visited exactly once in the original order,
+    /// external state may be used to decide which elements to keep.
     ///
     /// ```
     /// let mut s = String::from("abcde");
     /// let keep = [false, true, true, false, true];
-    /// let mut i = 0;
-    /// s.retain(|_| (keep[i], i += 1).0);
+    /// let mut iter = keep.iter();
+    /// s.retain(|_| *iter.next().unwrap());
     /// assert_eq!(s, "bce");
     /// ```
     #[inline]
@@ -1434,7 +1451,7 @@ impl String {
 
         unsafe {
             ptr::copy(self.vec.as_ptr().add(idx), self.vec.as_mut_ptr().add(idx + amt), len - idx);
-            ptr::copy(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
+            ptr::copy_nonoverlapping(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
             self.vec.set_len(len + amt);
         }
     }
@@ -1502,7 +1519,7 @@ impl String {
     }
 
     /// Returns the length of this `String`, in bytes, not [`char`]s or
-    /// graphemes. In other words, it may not be what a human considers the
+    /// graphemes. In other words, it might not be what a human considers the
     /// length of the string.
     ///
     /// # Examples
@@ -1517,7 +1534,6 @@ impl String {
     /// assert_eq!(fancy_f.len(), 4);
     /// assert_eq!(fancy_f.chars().count(), 3);
     /// ```
-    #[doc(alias = "length")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize {
@@ -2089,7 +2105,8 @@ impl_eq! { Cow<'a, str>, &'b str }
 impl_eq! { Cow<'a, str>, String }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for String {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl const Default for String {
     /// Creates an empty `String`.
     #[inline]
     fn default() -> String {
@@ -2474,6 +2491,9 @@ impl AsRef<[u8]> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<&str> for String {
+    /// Converts a `&str` into a [`String`].
+    ///
+    /// The result is allocated on the heap.
     #[inline]
     fn from(s: &str) -> String {
         s.to_owned()
@@ -2483,7 +2503,7 @@ impl From<&str> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_mut_str_for_string", since = "1.44.0")]
 impl From<&mut str> for String {
-    /// Converts a `&mut str` into a `String`.
+    /// Converts a `&mut str` into a [`String`].
     ///
     /// The result is allocated on the heap.
     #[inline]
@@ -2495,6 +2515,9 @@ impl From<&mut str> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_ref_string", since = "1.35.0")]
 impl From<&String> for String {
+    /// Converts a `&String` into a [`String`].
+    ///
+    /// This clones `s` and returns the clone.
     #[inline]
     fn from(s: &String) -> String {
         s.clone()
@@ -2505,7 +2528,7 @@ impl From<&String> for String {
 #[cfg(not(test))]
 #[stable(feature = "string_from_box", since = "1.18.0")]
 impl From<Box<str>> for String {
-    /// Converts the given boxed `str` slice to a `String`.
+    /// Converts the given boxed `str` slice to a [`String`].
     /// It is notable that the `str` slice is owned.
     ///
     /// # Examples
@@ -2527,7 +2550,7 @@ impl From<Box<str>> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "box_from_str", since = "1.20.0")]
 impl From<String> for Box<str> {
-    /// Converts the given `String` to a boxed `str` slice that is owned.
+    /// Converts the given [`String`] to a boxed `str` slice that is owned.
     ///
     /// # Examples
     ///
@@ -2548,6 +2571,22 @@ impl From<String> for Box<str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "string_from_cow_str", since = "1.14.0")]
 impl<'a> From<Cow<'a, str>> for String {
+    /// Converts a clone-on-write string to an owned
+    /// instance of [`String`].
+    ///
+    /// This extracts the owned string,
+    /// clones the string if it is not already owned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use std::borrow::Cow;
+    /// // If the string is not owned...
+    /// let cow: Cow<str> = Cow::Borrowed("eggplant");
+    /// // It will allocate on the heap and copy the string.
+    /// let owned: String = String::from(cow);
+    /// assert_eq!(&owned[..], "eggplant");
+    /// ```
     fn from(s: Cow<'a, str>) -> String {
         s.into_owned()
     }
@@ -2556,7 +2595,7 @@ impl<'a> From<Cow<'a, str>> for String {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> From<&'a str> for Cow<'a, str> {
-    /// Converts a string slice into a Borrowed variant.
+    /// Converts a string slice into a [`Borrowed`] variant.
     /// No heap allocation is performed, and the string
     /// is not copied.
     ///
@@ -2566,6 +2605,8 @@ impl<'a> From<&'a str> for Cow<'a, str> {
     /// # use std::borrow::Cow;
     /// assert_eq!(Cow::from("eggplant"), Cow::Borrowed("eggplant"));
     /// ```
+    ///
+    /// [`Borrowed`]: crate::borrow::Cow::Borrowed
     #[inline]
     fn from(s: &'a str) -> Cow<'a, str> {
         Cow::Borrowed(s)
@@ -2575,7 +2616,7 @@ impl<'a> From<&'a str> for Cow<'a, str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> From<String> for Cow<'a, str> {
-    /// Converts a String into an Owned variant.
+    /// Converts a [`String`] into an [`Owned`] variant.
     /// No heap allocation is performed, and the string
     /// is not copied.
     ///
@@ -2587,6 +2628,8 @@ impl<'a> From<String> for Cow<'a, str> {
     /// let s2 = "eggplant".to_string();
     /// assert_eq!(Cow::from(s), Cow::<'static, str>::Owned(s2));
     /// ```
+    ///
+    /// [`Owned`]: crate::borrow::Cow::Owned
     #[inline]
     fn from(s: String) -> Cow<'a, str> {
         Cow::Owned(s)
@@ -2596,7 +2639,7 @@ impl<'a> From<String> for Cow<'a, str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "cow_from_string_ref", since = "1.28.0")]
 impl<'a> From<&'a String> for Cow<'a, str> {
-    /// Converts a String reference into a Borrowed variant.
+    /// Converts a [`String`] reference into a [`Borrowed`] variant.
     /// No heap allocation is performed, and the string
     /// is not copied.
     ///
@@ -2607,6 +2650,8 @@ impl<'a> From<&'a String> for Cow<'a, str> {
     /// let s = "eggplant".to_string();
     /// assert_eq!(Cow::from(&s), Cow::Borrowed("eggplant"));
     /// ```
+    ///
+    /// [`Borrowed`]: crate::borrow::Cow::Borrowed
     #[inline]
     fn from(s: &'a String) -> Cow<'a, str> {
         Cow::Borrowed(s.as_str())
@@ -2639,7 +2684,7 @@ impl<'a> FromIterator<String> for Cow<'a, str> {
 
 #[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
 impl From<String> for Vec<u8> {
-    /// Converts the given `String` to a vector `Vec` that holds values of type `u8`.
+    /// Converts the given [`String`] to a vector [`Vec`] that holds values of type [`u8`].
     ///
     /// # Examples
     ///
@@ -2724,33 +2769,31 @@ impl<'a> Drain<'a> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(string_drain_as_str)]
     /// let mut s = String::from("abc");
     /// let mut drain = s.drain(..);
     /// assert_eq!(drain.as_str(), "abc");
     /// let _ = drain.next().unwrap();
     /// assert_eq!(drain.as_str(), "bc");
     /// ```
-    #[unstable(feature = "string_drain_as_str", issue = "76905")] // Note: uncomment AsRef impls below when stabilizing.
+    #[stable(feature = "string_drain_as_str", since = "1.55.0")]
     pub fn as_str(&self) -> &str {
         self.iter.as_str()
     }
 }
 
-// Uncomment when stabilizing `string_drain_as_str`.
-// #[unstable(feature = "string_drain_as_str", issue = "76905")]
-// impl<'a> AsRef<str> for Drain<'a> {
-//     fn as_ref(&self) -> &str {
-//         self.as_str()
-//     }
-// }
-//
-// #[unstable(feature = "string_drain_as_str", issue = "76905")]
-// impl<'a> AsRef<[u8]> for Drain<'a> {
-//     fn as_ref(&self) -> &[u8] {
-//         self.as_str().as_bytes()
-//     }
-// }
+#[stable(feature = "string_drain_as_str", since = "1.55.0")]
+impl<'a> AsRef<str> for Drain<'a> {
+    fn as_ref(&self) -> &str {
+        self.as_str()
+    }
+}
+
+#[stable(feature = "string_drain_as_str", since = "1.55.0")]
+impl<'a> AsRef<[u8]> for Drain<'a> {
+    fn as_ref(&self) -> &[u8] {
+        self.as_str().as_bytes()
+    }
+}
 
 #[stable(feature = "drain", since = "1.6.0")]
 impl Iterator for Drain<'_> {
@@ -2785,6 +2828,14 @@ impl FusedIterator for Drain<'_> {}
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_char_for_string", since = "1.46.0")]
 impl From<char> for String {
+    /// Allocates an owned [`String`] from a single character.
+    ///
+    /// # Example
+    /// ```rust
+    /// let c: char = 'a';
+    /// let s: String = String::from(c);
+    /// assert_eq!("a", &s[..]);
+    /// ```
     #[inline]
     fn from(c: char) -> Self {
         c.to_string()
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index a8fa028fc90..3183a6db410 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -19,6 +19,7 @@ use core::marker::{PhantomData, Unpin, Unsize};
 use core::mem::size_of_val;
 use core::mem::{self, align_of_val_raw};
 use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver};
+use core::panic::{RefUnwindSafe, UnwindSafe};
 use core::pin::Pin;
 use core::ptr::{self, NonNull};
 #[cfg(not(no_global_oom_handling))]
@@ -240,6 +241,9 @@ unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
 
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
+
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 
@@ -332,6 +336,7 @@ impl<T> Arc<T> {
     ///
     /// let five = Arc::new(5);
     /// ```
+    #[cfg(not(no_global_oom_handling))]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(data: T) -> Arc<T> {
@@ -365,6 +370,7 @@ impl<T> Arc<T> {
     ///     me: me.clone(),
     /// });
     /// ```
+    #[cfg(not(no_global_oom_handling))]
     #[inline]
     #[unstable(feature = "arc_new_cyclic", issue = "75861")]
     pub fn new_cyclic(data_fn: impl FnOnce(&Weak<T>) -> T) -> Arc<T> {
@@ -485,11 +491,19 @@ impl<T> Arc<T> {
 
     /// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
     /// `data` will be pinned in memory and unable to be moved.
+    #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn pin(data: T) -> Pin<Arc<T>> {
         unsafe { Pin::new_unchecked(Arc::new(data)) }
     }
 
+    /// Constructs a new `Pin<Arc<T>>`, return an error if allocation fails.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn try_pin(data: T) -> Result<Pin<Arc<T>>, AllocError> {
+        unsafe { Ok(Pin::new_unchecked(Arc::try_new(data)?)) }
+    }
+
     /// Constructs a new `Arc<T>`, returning an error if allocation fails.
     ///
     /// # Examples
@@ -1046,8 +1060,8 @@ impl<T: ?Sized> Arc<T> {
     // Non-inlined part of `drop`.
     #[inline(never)]
     unsafe fn drop_slow(&mut self) {
-        // Destroy the data at this time, even though we may not free the box
-        // allocation itself (there may still be weak pointers lying around).
+        // Destroy the data at this time, even though we must not free the box
+        // allocation itself (there might still be weak pointers lying around).
         unsafe { ptr::drop_in_place(Self::get_mut_unchecked(self)) };
 
         // Drop the weak ref collectively held by all strong references
@@ -2274,6 +2288,7 @@ impl<T: ?Sized> fmt::Pointer for Arc<T> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Arc<T> {
     /// Creates a new `Arc<T>`, with the `Default` value for `T`.
@@ -2298,8 +2313,23 @@ impl<T: ?Sized + Hash> Hash for Arc<T> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_for_ptrs", since = "1.6.0")]
 impl<T> From<T> for Arc<T> {
+    /// Converts a `T` into an `Arc<T>`
+    ///
+    /// The conversion moves the value into a
+    /// newly allocated `Arc`. It is equivalent to
+    /// calling `Arc::new(t)`.
+    ///
+    /// # Example
+    /// ```rust
+    /// # use std::sync::Arc;
+    /// let x = 5;
+    /// let arc = Arc::new(5);
+    ///
+    /// assert_eq!(Arc::from(x), arc);
+    /// ```
     fn from(t: T) -> Self {
         Arc::new(t)
     }
@@ -2561,7 +2591,7 @@ unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
     // SAFETY: since the only unsized types possible are slices, trait objects,
     // and extern types, the input safety requirement is currently enough to
     // satisfy the requirements of align_of_val_raw; this is an implementation
-    // detail of the language that may not be relied upon outside of std.
+    // detail of the language that must not be relied upon outside of std.
     unsafe { data_offset_align(align_of_val_raw(ptr)) }
 }
 
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index 8da4d995ba5..0bd152f17a6 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -2,7 +2,9 @@ use crate::alloc::{Allocator, Global};
 use crate::raw_vec::RawVec;
 use core::fmt;
 use core::intrinsics::arith_offset;
-use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess};
+use core::iter::{
+    FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccessNoCoerce,
+};
 use core::marker::PhantomData;
 use core::mem::{self};
 use core::ptr::{self, NonNull};
@@ -163,9 +165,10 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
         self.len()
     }
 
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         // SAFETY: the caller must guarantee that `i` is in bounds of the
         // `Vec<T>`, so `i` cannot overflow an `isize`, and the `self.ptr.add(i)`
@@ -218,7 +221,10 @@ unsafe impl<T, A: Allocator> TrustedLen for IntoIter<T, A> {}
 #[unstable(issue = "none", feature = "std_internals")]
 // T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr
 // and thus we can't implement drop-handling
-unsafe impl<T, A: Allocator> TrustedRandomAccess for IntoIter<T, A>
+//
+// TrustedRandomAccess (without NoCoerce) must not be implemented because
+// subtypes/supertypes of `T` might not be `Copy`
+unsafe impl<T, A: Allocator> TrustedRandomAccessNoCoerce for IntoIter<T, A>
 where
     T: Copy,
 {
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 4a1d564e2ab..87a0d371815 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -174,12 +174,13 @@ mod spec_extend;
 /// assert_eq!(vec, [7, 1, 2, 3]);
 /// ```
 ///
-/// The [`vec!`] macro is provided to make initialization more convenient:
+/// The [`vec!`] macro is provided for convenient initialization:
 ///
 /// ```
-/// let mut vec = vec![1, 2, 3];
-/// vec.push(4);
-/// assert_eq!(vec, [1, 2, 3, 4]);
+/// let mut vec1 = vec![1, 2, 3];
+/// vec1.push(4);
+/// let vec2 = Vec::from([1, 2, 3, 4]);
+/// assert_eq!(vec1, vec2);
 /// ```
 ///
 /// It can also initialize each element of a `Vec<T>` with a given value.
@@ -459,7 +460,6 @@ impl<T> Vec<T> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[inline]
-    #[doc(alias = "malloc")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(capacity: usize) -> Self {
         Self::with_capacity_in(capacity, Global)
@@ -799,7 +799,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert!(vec.capacity() >= 11);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[doc(alias = "realloc")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve(&mut self, additional: usize) {
         self.buf.reserve(self.len, additional);
@@ -812,7 +811,9 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// Note that the allocator may give the collection more space than it
     /// requests. Therefore, capacity can not be relied upon to be precisely
-    /// minimal. Prefer `reserve` if future insertions are expected.
+    /// minimal. Prefer [`reserve`] if future insertions are expected.
+    ///
+    /// [`reserve`]: Vec::reserve
     ///
     /// # Panics
     ///
@@ -826,7 +827,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert!(vec.capacity() >= 11);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[doc(alias = "realloc")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve_exact(&mut self, additional: usize) {
         self.buf.reserve_exact(self.len, additional);
@@ -864,7 +864,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// }
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
-    #[doc(alias = "realloc")]
     #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
     pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.buf.try_reserve(self.len, additional)
@@ -878,7 +877,9 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// Note that the allocator may give the collection more space than it
     /// requests. Therefore, capacity can not be relied upon to be precisely
-    /// minimal. Prefer `reserve` if future insertions are expected.
+    /// minimal. Prefer [`reserve`] if future insertions are expected.
+    ///
+    /// [`reserve`]: Vec::reserve
     ///
     /// # Errors
     ///
@@ -906,7 +907,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// }
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
-    #[doc(alias = "realloc")]
     #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
     pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.buf.try_reserve_exact(self.len, additional)
@@ -927,7 +927,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert!(vec.capacity() >= 3);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[doc(alias = "realloc")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn shrink_to_fit(&mut self) {
         // The capacity is never less than the length, and there's nothing to do when
@@ -948,7 +947,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(shrink_to)]
     /// let mut vec = Vec::with_capacity(10);
     /// vec.extend([1, 2, 3]);
     /// assert_eq!(vec.capacity(), 10);
@@ -958,8 +956,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert!(vec.capacity() >= 3);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[doc(alias = "realloc")]
-    #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         if self.capacity() > min_capacity {
             self.buf.shrink_to_fit(cmp::max(self.len, min_capacity));
@@ -1366,6 +1363,12 @@ impl<T, A: Allocator> Vec<T, A> {
     /// Removes and returns the element at position `index` within the vector,
     /// shifting all elements after it to the left.
     ///
+    /// Note: Because this shifts over the remaining elements, it has a
+    /// worst-case performance of O(n). If you don't need the order of elements
+    /// to be preserved, use [`swap_remove`] instead.
+    ///
+    /// [`swap_remove`]: Vec::swap_remove
+    ///
     /// # Panics
     ///
     /// Panics if `index` is out of bounds.
@@ -1378,9 +1381,11 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert_eq!(v, [1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[track_caller]
     pub fn remove(&mut self, index: usize) -> T {
         #[cold]
         #[inline(never)]
+        #[track_caller]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("removal index (is {}) should be < len (is {})", index, len);
         }
@@ -1820,7 +1825,6 @@ impl<T, A: Allocator> Vec<T, A> {
     /// let a = vec![1, 2, 3];
     /// assert_eq!(a.len(), 3);
     /// ```
-    #[doc(alias = "length")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize {
@@ -2236,7 +2240,7 @@ impl<T, A: Allocator> Vec<T, A> {
         unsafe {
             let mut ptr = self.as_mut_ptr().add(self.len());
             // Use SetLenOnDrop to work around bug where compiler
-            // may not realize the store through `ptr` through self.set_len()
+            // might not realize the store through `ptr` through self.set_len()
             // don't alias.
             let mut local_len = SetLenOnDrop::new(&mut self.len);
 
@@ -2375,6 +2379,35 @@ impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
 }
 
 #[cfg(not(no_global_oom_handling))]
+trait SpecCloneFrom {
+    fn clone_from(this: &mut Self, other: &Self);
+}
+
+#[cfg(not(no_global_oom_handling))]
+impl<T: Clone, A: Allocator> SpecCloneFrom for Vec<T, A> {
+    default fn clone_from(this: &mut Self, other: &Self) {
+        // drop anything that will not be overwritten
+        this.truncate(other.len());
+
+        // self.len <= other.len due to the truncate above, so the
+        // slices here are always in-bounds.
+        let (init, tail) = other.split_at(this.len());
+
+        // reuse the contained values' allocations/resources.
+        this.clone_from_slice(init);
+        this.extend_from_slice(tail);
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
+impl<T: Copy, A: Allocator> SpecCloneFrom for Vec<T, A> {
+    fn clone_from(this: &mut Self, other: &Self) {
+        this.clear();
+        this.extend_from_slice(other);
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
     #[cfg(not(test))]
@@ -2394,19 +2427,22 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
     }
 
     fn clone_from(&mut self, other: &Self) {
-        // drop anything that will not be overwritten
-        self.truncate(other.len());
-
-        // self.len <= other.len due to the truncate above, so the
-        // slices here are always in-bounds.
-        let (init, tail) = other.split_at(self.len());
-
-        // reuse the contained values' allocations/resources.
-        self.clone_from_slice(init);
-        self.extend_from_slice(tail);
+        SpecCloneFrom::clone_from(self, other)
     }
 }
 
+/// The hash of a vector is the same as that of the corresponding slice,
+/// as required by the `core::borrow::Borrow` implementation.
+///
+/// ```
+/// #![feature(build_hasher_simple_hash_one)]
+/// use std::hash::BuildHasher;
+///
+/// let b = std::collections::hash_map::RandomState::new();
+/// let v: Vec<u8> = vec![0xa8, 0x3c, 0x09];
+/// let s: &[u8] = &[0xa8, 0x3c, 0x09];
+/// assert_eq!(b.hash_one(v), b.hash_one(s));
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Hash, A: Allocator> Hash for Vec<T, A> {
     #[inline]
@@ -2551,6 +2587,8 @@ impl<T, A: Allocator> Vec<T, A> {
             }
             unsafe {
                 ptr::write(self.as_mut_ptr().add(len), element);
+                // Since next() executes user code which can panic we have to bump the length
+                // after each step.
                 // NB can't overflow since we would have had to alloc the address space
                 self.set_len(len + 1);
             }
@@ -2720,7 +2758,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for Vec<T> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> const Default for Vec<T> {
     /// Creates an empty `Vec<T>`.
     fn default() -> Vec<T> {
         Vec::new()
diff --git a/library/alloc/src/vec/source_iter_marker.rs b/library/alloc/src/vec/source_iter_marker.rs
index e857d284d3a..e05788d99c0 100644
--- a/library/alloc/src/vec/source_iter_marker.rs
+++ b/library/alloc/src/vec/source_iter_marker.rs
@@ -1,4 +1,4 @@
-use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccess};
+use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce};
 use core::mem::{self, ManuallyDrop};
 use core::ptr::{self};
 
@@ -56,7 +56,7 @@ where
 
         let src = unsafe { iterator.as_inner().as_into_iter() };
         // check if SourceIter contract was upheld
-        // caveat: if they weren't we may not even make it to this point
+        // caveat: if they weren't we might not even make it to this point
         debug_assert_eq!(src_buf, src.buf.as_ptr());
         // check InPlaceIterable contract. This is only possible if the iterator advanced the
         // source pointer at all. If it uses unchecked access via TrustedRandomAccess
@@ -71,6 +71,18 @@ where
         // drop any remaining values at the tail of the source
         // but prevent drop of the allocation itself once IntoIter goes out of scope
         // if the drop panics then we also leak any elements collected into dst_buf
+        //
+        // FIXME: Since `SpecInPlaceCollect::collect_in_place` above might use
+        // `__iterator_get_unchecked` internally, this call might be operating on
+        // a `vec::IntoIter` with incorrect internal state regarding which elements
+        // have already been “consumed”. However, the `TrustedRandomIteratorNoCoerce`
+        // implementation of `vec::IntoIter` is only present if the `Vec` elements
+        // don’t have a destructor, so it doesn’t matter if elements are “dropped multiple times”
+        // in this case.
+        // This argument technically currently lacks justification from the `# Safety` docs for
+        // `SourceIter`/`InPlaceIterable` and/or `TrustedRandomAccess`, so it might be possible that
+        // someone could inadvertently create new library unsoundness
+        // involving this `.forget_allocation_drop_remaining()` call.
         src.forget_allocation_drop_remaining();
 
         let vec = unsafe { Vec::from_raw_parts(dst_buf, len, cap) };
@@ -89,6 +101,8 @@ fn write_in_place_with_drop<T>(
             // all we can do is check if it's still in range
             debug_assert!(sink.dst as *const _ <= src_end, "InPlaceIterable contract violation");
             ptr::write(sink.dst, item);
+            // Since this executes user code which can panic we have to bump the pointer
+            // after each step.
             sink.dst = sink.dst.add(1);
         }
         Ok(sink)
@@ -99,6 +113,11 @@ fn write_in_place_with_drop<T>(
 trait SpecInPlaceCollect<T, I>: Iterator<Item = T> {
     /// Collects an iterator (`self`) into the destination buffer (`dst`) and returns the number of items
     /// collected. `end` is the last writable element of the allocation and used for bounds checks.
+    ///
+    /// This method is specialized and one of its implementations makes use of
+    /// `Iterator::__iterator_get_unchecked` calls with a `TrustedRandomAccessNoCoerce` bound
+    /// on `I` which means the caller of this method must take the safety conditions
+    /// of that trait into consideration.
     fn collect_in_place(&mut self, dst: *mut T, end: *const T) -> usize;
 }
 
@@ -122,7 +141,7 @@ where
 
 impl<T, I> SpecInPlaceCollect<T, I> for I
 where
-    I: Iterator<Item = T> + TrustedRandomAccess,
+    I: Iterator<Item = T> + TrustedRandomAccessNoCoerce,
 {
     #[inline]
     fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize {
@@ -136,6 +155,8 @@ where
                 let dst = dst_buf.offset(i as isize);
                 debug_assert!(dst as *const _ <= end, "InPlaceIterable contract violation");
                 ptr::write(dst, self.__iterator_get_unchecked(i));
+                // Since this executes user code which can panic we have to bump the pointer
+                // after each step.
                 drop_guard.dst = dst.add(1);
             }
         }
diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs
index c6f4f22a01f..c3b4534096d 100644
--- a/library/alloc/src/vec/spec_extend.rs
+++ b/library/alloc/src/vec/spec_extend.rs
@@ -40,6 +40,8 @@ where
                 iterator.for_each(move |element| {
                     ptr::write(ptr, element);
                     ptr = ptr.offset(1);
+                    // Since the loop executes user code which can panic we have to bump the pointer
+                    // after each step.
                     // NB can't overflow since we would have had to alloc the address space
                     local_len.increment_len(1);
                 });
diff --git a/library/alloc/tests/binary_heap.rs b/library/alloc/tests/binary_heap.rs
index a7913dcd287..f32118bb563 100644
--- a/library/alloc/tests/binary_heap.rs
+++ b/library/alloc/tests/binary_heap.rs
@@ -408,7 +408,7 @@ fn test_retain() {
 // old binaryheap failed this test
 //
 // Integrity means that all elements are present after a comparison panics,
-// even if the order may not be correct.
+// even if the order might not be correct.
 //
 // Destructors must be called exactly once per element.
 // FIXME: re-enable emscripten once it can unwind again
diff --git a/library/alloc/tests/const_fns.rs b/library/alloc/tests/const_fns.rs
new file mode 100644
index 00000000000..da58ae92e11
--- /dev/null
+++ b/library/alloc/tests/const_fns.rs
@@ -0,0 +1,53 @@
+// Test const functions in the library
+
+use core::cmp::Ordering;
+
+// FIXME remove this struct once we put `K: ?const Ord` on BTreeMap::new.
+#[derive(PartialEq, Eq, PartialOrd)]
+pub struct MyType;
+
+impl const Ord for MyType {
+    fn cmp(&self, _: &Self) -> Ordering {
+        Ordering::Equal
+    }
+
+    fn max(self, _: Self) -> Self {
+        Self
+    }
+
+    fn min(self, _: Self) -> Self {
+        Self
+    }
+
+    fn clamp(self, _: Self, _: Self) -> Self {
+        Self
+    }
+}
+
+pub const MY_VEC: Vec<usize> = Vec::new();
+pub const MY_VEC2: Vec<usize> = Default::default();
+
+pub const MY_STRING: String = String::new();
+pub const MY_STRING2: String = Default::default();
+
+use std::collections::{BTreeMap, BTreeSet};
+
+pub const MY_BTREEMAP: BTreeMap<MyType, MyType> = BTreeMap::new();
+pub const MAP: &'static BTreeMap<MyType, MyType> = &MY_BTREEMAP;
+pub const MAP_LEN: usize = MAP.len();
+pub const MAP_IS_EMPTY: bool = MAP.is_empty();
+
+pub const MY_BTREESET: BTreeSet<MyType> = BTreeSet::new();
+pub const SET: &'static BTreeSet<MyType> = &MY_BTREESET;
+pub const SET_LEN: usize = SET.len();
+pub const SET_IS_EMPTY: bool = SET.is_empty();
+
+#[test]
+fn test_const() {
+    assert_eq!(MY_VEC, MY_VEC2);
+    assert_eq!(MY_STRING, MY_STRING2);
+
+    assert_eq!(MAP_LEN, 0);
+    assert_eq!(SET_LEN, 0);
+    assert!(MAP_IS_EMPTY && SET_IS_EMPTY);
+}
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 3143afa269d..5767108d423 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -1,4 +1,5 @@
 #![feature(allocator_api)]
+#![feature(assert_matches)]
 #![feature(box_syntax)]
 #![feature(cow_is_borrowed)]
 #![feature(const_cow_is_borrowed)]
@@ -8,6 +9,7 @@
 #![feature(pattern)]
 #![feature(trusted_len)]
 #![feature(try_reserve)]
+#![feature(try_reserve_kind)]
 #![feature(unboxed_closures)]
 #![feature(associated_type_bounds)]
 #![feature(binary_heap_into_iter_sorted)]
@@ -21,6 +23,9 @@
 #![feature(slice_partition_dedup)]
 #![feature(vec_spare_capacity)]
 #![feature(string_remove_matches)]
+#![feature(const_btree_new)]
+#![feature(const_default_impls)]
+#![feature(const_trait_impl)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
@@ -30,6 +35,7 @@ mod binary_heap;
 mod borrow;
 mod boxed;
 mod btree_set_hash;
+mod const_fns;
 mod cow_str;
 mod fmt;
 mod heap;
diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs
index 1fb4a51acfd..13b8c059e37 100644
--- a/library/alloc/tests/slice.rs
+++ b/library/alloc/tests/slice.rs
@@ -1,6 +1,7 @@
 use std::cell::Cell;
 use std::cmp::Ordering::{self, Equal, Greater, Less};
 use std::convert::identity;
+use std::fmt;
 use std::mem;
 use std::panic;
 use std::rc::Rc;
@@ -994,6 +995,66 @@ fn test_rsplitnator() {
 }
 
 #[test]
+fn test_split_iterators_size_hint() {
+    #[derive(Copy, Clone)]
+    enum Bounds {
+        Lower,
+        Upper,
+    }
+    fn assert_tight_size_hints(mut it: impl Iterator, which: Bounds, ctx: impl fmt::Display) {
+        match which {
+            Bounds::Lower => {
+                let mut lower_bounds = vec![it.size_hint().0];
+                while let Some(_) = it.next() {
+                    lower_bounds.push(it.size_hint().0);
+                }
+                let target: Vec<_> = (0..lower_bounds.len()).rev().collect();
+                assert_eq!(lower_bounds, target, "lower bounds incorrect or not tight: {}", ctx);
+            }
+            Bounds::Upper => {
+                let mut upper_bounds = vec![it.size_hint().1];
+                while let Some(_) = it.next() {
+                    upper_bounds.push(it.size_hint().1);
+                }
+                let target: Vec<_> = (0..upper_bounds.len()).map(Some).rev().collect();
+                assert_eq!(upper_bounds, target, "upper bounds incorrect or not tight: {}", ctx);
+            }
+        }
+    }
+
+    for len in 0..=2 {
+        let mut v: Vec<u8> = (0..len).collect();
+
+        // p: predicate, b: bound selection
+        for (p, b) in [
+            // with a predicate always returning false, the split*-iterators
+            // become maximally short, so the size_hint lower bounds are tight
+            ((|_| false) as fn(&_) -> _, Bounds::Lower),
+            // with a predicate always returning true, the split*-iterators
+            // become maximally long, so the size_hint upper bounds are tight
+            ((|_| true) as fn(&_) -> _, Bounds::Upper),
+        ] {
+            use assert_tight_size_hints as a;
+            use format_args as f;
+
+            a(v.split(p), b, "split");
+            a(v.split_mut(p), b, "split_mut");
+            a(v.split_inclusive(p), b, "split_inclusive");
+            a(v.split_inclusive_mut(p), b, "split_inclusive_mut");
+            a(v.rsplit(p), b, "rsplit");
+            a(v.rsplit_mut(p), b, "rsplit_mut");
+
+            for n in 0..=3 {
+                a(v.splitn(n, p), b, f!("splitn, n = {}", n));
+                a(v.splitn_mut(n, p), b, f!("splitn_mut, n = {}", n));
+                a(v.rsplitn(n, p), b, f!("rsplitn, n = {}", n));
+                a(v.rsplitn_mut(n, p), b, f!("rsplitn_mut, n = {}", n));
+            }
+        }
+    }
+}
+
+#[test]
 fn test_windowsator() {
     let v = &[1, 2, 3, 4];
 
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index 6df8d8c2f35..d3a87c056cf 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -534,7 +534,7 @@ mod slice_index {
     #[test]
     #[should_panic]
     fn test_slice_fail() {
-        &"中华Việt Nam"[0..2];
+        let _ = &"中华Việt Nam"[0..2];
     }
 
     panic_cases! {
@@ -714,13 +714,13 @@ mod slice_index {
     #[test]
     #[should_panic(expected = "byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
     fn test_slice_fail_truncated_1() {
-        &LOREM_PARAGRAPH[..1024];
+        let _ = &LOREM_PARAGRAPH[..1024];
     }
     // check the truncation in the panic message
     #[test]
     #[should_panic(expected = "luctus, im`[...]")]
     fn test_slice_fail_truncated_2() {
-        &LOREM_PARAGRAPH[..1024];
+        let _ = &LOREM_PARAGRAPH[..1024];
     }
 }
 
@@ -735,7 +735,7 @@ fn test_str_slice_rangetoinclusive_ok() {
 #[should_panic]
 fn test_str_slice_rangetoinclusive_notok() {
     let s = "abcαβγ";
-    &s[..=3];
+    let _ = &s[..=3];
 }
 
 #[test]
@@ -751,7 +751,7 @@ fn test_str_slicemut_rangetoinclusive_ok() {
 fn test_str_slicemut_rangetoinclusive_notok() {
     let mut s = "abcαβγ".to_owned();
     let s: &mut str = &mut s;
-    &mut s[..=3];
+    let _ = &mut s[..=3];
 }
 
 #[test]
@@ -1873,6 +1873,47 @@ mod pattern {
         "* \t",
         [Reject(0, 1), Reject(1, 2), Reject(2, 3),]
     );
+
+    // See #85462
+    #[test]
+    fn str_searcher_empty_needle_after_done() {
+        // Empty needle and haystack
+        {
+            let mut searcher = "".into_searcher("");
+
+            assert_eq!(searcher.next(), SearchStep::Match(0, 0));
+            assert_eq!(searcher.next(), SearchStep::Done);
+            assert_eq!(searcher.next(), SearchStep::Done);
+            assert_eq!(searcher.next(), SearchStep::Done);
+
+            let mut searcher = "".into_searcher("");
+
+            assert_eq!(searcher.next_back(), SearchStep::Match(0, 0));
+            assert_eq!(searcher.next_back(), SearchStep::Done);
+            assert_eq!(searcher.next_back(), SearchStep::Done);
+            assert_eq!(searcher.next_back(), SearchStep::Done);
+        }
+        // Empty needle and non-empty haystack
+        {
+            let mut searcher = "".into_searcher("a");
+
+            assert_eq!(searcher.next(), SearchStep::Match(0, 0));
+            assert_eq!(searcher.next(), SearchStep::Reject(0, 1));
+            assert_eq!(searcher.next(), SearchStep::Match(1, 1));
+            assert_eq!(searcher.next(), SearchStep::Done);
+            assert_eq!(searcher.next(), SearchStep::Done);
+            assert_eq!(searcher.next(), SearchStep::Done);
+
+            let mut searcher = "".into_searcher("a");
+
+            assert_eq!(searcher.next_back(), SearchStep::Match(1, 1));
+            assert_eq!(searcher.next_back(), SearchStep::Reject(0, 1));
+            assert_eq!(searcher.next_back(), SearchStep::Match(0, 0));
+            assert_eq!(searcher.next_back(), SearchStep::Done);
+            assert_eq!(searcher.next_back(), SearchStep::Done);
+            assert_eq!(searcher.next_back(), SearchStep::Done);
+        }
+    }
 }
 
 macro_rules! generate_iterator_test {
diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs
index 9ec0ee97ab9..7be137131ff 100644
--- a/library/alloc/tests/string.rs
+++ b/library/alloc/tests/string.rs
@@ -1,6 +1,7 @@
+use std::assert_matches::assert_matches;
 use std::borrow::Cow;
 use std::cell::Cell;
-use std::collections::TryReserveError::*;
+use std::collections::TryReserveErrorKind::*;
 use std::ops::Bound;
 use std::ops::Bound::*;
 use std::ops::RangeBounds;
@@ -703,38 +704,42 @@ fn test_try_reserve() {
         let mut empty_string: String = String::new();
 
         // Check isize::MAX doesn't count as an overflow
-        if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         // Play it again, frank! (just to be sure)
-        if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
         if guards_against_isize {
             // Check isize::MAX + 1 does count as overflow
-            if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
 
             // Check usize::MAX does count as overflow
-            if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
         } else {
             // Check isize::MAX + 1 is an OOM
-            if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_string.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
 
             // Check usize::MAX is an OOM
-            if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_string.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
         }
     }
 
@@ -742,28 +747,31 @@ fn test_try_reserve() {
         // Same basic idea, but with non-zero len
         let mut ten_bytes: String = String::from("0123456789");
 
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
         // Should always overflow in the add-to-len
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!")
-        }
+        assert_matches!(
+            ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 }
 
@@ -782,60 +790,73 @@ fn test_try_reserve_exact() {
     {
         let mut empty_string: String = String::new();
 
-        if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
         if guards_against_isize {
-            if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!")
-            }
-
-            if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
-
-            if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+
+            assert_matches!(
+                empty_string.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
         }
     }
 
     {
         let mut ten_bytes: String = String::from("0123456789");
 
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) =
+            ten_bytes.try_reserve_exact(MAX_CAP - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) =
+            ten_bytes.try_reserve_exact(MAX_CAP - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
-        } else {
-            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
-        }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            panic!("usize::MAX should trigger an overflow!")
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
+        assert_matches!(
+            ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 }
 
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index c203cdafecb..c2df50b48f5 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1,6 +1,7 @@
+use std::assert_matches::assert_matches;
 use std::borrow::Cow;
 use std::cell::Cell;
-use std::collections::TryReserveError::*;
+use std::collections::TryReserveErrorKind::*;
 use std::fmt::Debug;
 use std::iter::InPlaceIterable;
 use std::mem::{size_of, swap};
@@ -542,35 +543,35 @@ fn test_index_out_of_bounds() {
 #[should_panic]
 fn test_slice_out_of_bounds_1() {
     let x = vec![1, 2, 3, 4, 5];
-    &x[!0..];
+    let _ = &x[!0..];
 }
 
 #[test]
 #[should_panic]
 fn test_slice_out_of_bounds_2() {
     let x = vec![1, 2, 3, 4, 5];
-    &x[..6];
+    let _ = &x[..6];
 }
 
 #[test]
 #[should_panic]
 fn test_slice_out_of_bounds_3() {
     let x = vec![1, 2, 3, 4, 5];
-    &x[!0..4];
+    let _ = &x[!0..4];
 }
 
 #[test]
 #[should_panic]
 fn test_slice_out_of_bounds_4() {
     let x = vec![1, 2, 3, 4, 5];
-    &x[1..6];
+    let _ = &x[1..6];
 }
 
 #[test]
 #[should_panic]
 fn test_slice_out_of_bounds_5() {
     let x = vec![1, 2, 3, 4, 5];
-    &x[3..2];
+    let _ = &x[3..2];
 }
 
 #[test]
@@ -1478,38 +1479,42 @@ fn test_try_reserve() {
         let mut empty_bytes: Vec<u8> = Vec::new();
 
         // Check isize::MAX doesn't count as an overflow
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         // Play it again, frank! (just to be sure)
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
         if guards_against_isize {
             // Check isize::MAX + 1 does count as overflow
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
 
             // Check usize::MAX does count as overflow
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
         } else {
             // Check isize::MAX + 1 is an OOM
-            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
 
             // Check usize::MAX is an OOM
-            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
         }
     }
 
@@ -1517,56 +1522,64 @@ fn test_try_reserve() {
         // Same basic idea, but with non-zero len
         let mut ten_bytes: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
         // Should always overflow in the add-to-len
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!")
-        }
+        assert_matches!(
+            ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 
     {
         // Same basic idea, but with interesting type size
         let mut ten_u32s: Vec<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
         // Should fail in the mul-by-size
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!");
-        }
+        assert_matches!(
+            ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 }
 
@@ -1585,86 +1598,106 @@ fn test_try_reserve_exact() {
     {
         let mut empty_bytes: Vec<u8> = Vec::new();
 
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
         if guards_against_isize {
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!")
-            }
-
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
 
-            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "usize::MAX should trigger an OOM!"
+            );
         }
     }
 
     {
         let mut ten_bytes: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) =
+            ten_bytes.try_reserve_exact(MAX_CAP - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) =
+            ten_bytes.try_reserve_exact(MAX_CAP - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
-        }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!")
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
+        assert_matches!(
+            ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 
     {
         let mut ten_u32s: Vec<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) =
+            ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) =
+            ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
-        }
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!")
-        }
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
+        assert_matches!(
+            ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 }
 
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index d7140cf9759..ddfb4c00c26 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -1,4 +1,5 @@
-use std::collections::TryReserveError::*;
+use std::assert_matches::assert_matches;
+use std::collections::TryReserveErrorKind::*;
 use std::collections::{vec_deque::Drain, VecDeque};
 use std::fmt::Debug;
 use std::mem::size_of;
@@ -1171,35 +1172,38 @@ fn test_try_reserve() {
         let mut empty_bytes: VecDeque<u8> = VecDeque::new();
 
         // Check isize::MAX doesn't count as an overflow
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         // Play it again, frank! (just to be sure)
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
         if guards_against_isize {
             // Check isize::MAX + 1 does count as overflow
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
 
             // Check usize::MAX does count as overflow
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
         } else {
             // Check isize::MAX is an OOM
             // VecDeque starts with capacity 7, always adds 1 to the capacity
             // and also rounds the number to next power of 2 so this is the
             // furthest we can go without triggering CapacityOverflow
-            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
     }
 
@@ -1207,56 +1211,64 @@ fn test_try_reserve() {
         // Same basic idea, but with non-zero len
         let mut ten_bytes: VecDeque<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
 
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
         // Should always overflow in the add-to-len
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!")
-        }
+        assert_matches!(
+            ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 
     {
         // Same basic idea, but with interesting type size
         let mut ten_u32s: VecDeque<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
 
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
         // Should fail in the mul-by-size
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!");
-        }
+        assert_matches!(
+            ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 }
 
@@ -1275,85 +1287,104 @@ fn test_try_reserve_exact() {
     {
         let mut empty_bytes: VecDeque<u8> = VecDeque::new();
 
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) {
+        if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
         if guards_against_isize {
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!")
-            }
-
-            if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
-            } else {
-                panic!("usize::MAX should trigger an overflow!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
         } else {
             // Check isize::MAX is an OOM
             // VecDeque starts with capacity 7, always adds 1 to the capacity
             // and also rounds the number to next power of 2 so this is the
             // furthest we can go without triggering CapacityOverflow
-            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
     }
 
     {
         let mut ten_bytes: VecDeque<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
 
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) =
+            ten_bytes.try_reserve_exact(MAX_CAP - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) {
+        if let Err(CapacityOverflow) =
+            ten_bytes.try_reserve_exact(MAX_CAP - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
-        }
-        if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
-        } else {
-            panic!("usize::MAX should trigger an overflow!")
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
+        assert_matches!(
+            ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 
     {
         let mut ten_u32s: VecDeque<u32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect();
 
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) =
+            ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) {
+        if let Err(CapacityOverflow) =
+            ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10).map_err(|e| e.kind())
+        {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
         if guards_against_isize {
-            if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an overflow!");
-            }
-        } else {
-            if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) {
-            } else {
-                panic!("isize::MAX + 1 should trigger an OOM!")
-            }
-        }
-        if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
         } else {
-            panic!("usize::MAX should trigger an overflow!")
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
         }
+        assert_matches!(
+            ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
+            Err(CapacityOverflow),
+            "usize::MAX should trigger an overflow!"
+        );
     }
 }
 
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index b6aaf078cf0..6f10b9e4342 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "core"
 version = "0.0.0"
 license = "MIT OR Apache-2.0"
diff --git a/library/core/benches/iter.rs b/library/core/benches/iter.rs
index f2169914ac9..24257ba9878 100644
--- a/library/core/benches/iter.rs
+++ b/library/core/benches/iter.rs
@@ -45,7 +45,7 @@ fn bench_max_by_key(b: &mut Bencher) {
     })
 }
 
-// http://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
+// https://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
 #[bench]
 fn bench_max_by_key2(b: &mut Bencher) {
     fn max_index_iter(array: &[i32]) -> usize {
diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs
index 6dcc110f153..8839a69d119 100644
--- a/library/core/src/alloc/global.rs
+++ b/library/core/src/alloc/global.rs
@@ -20,24 +20,69 @@ use crate::ptr;
 ///
 /// # Example
 ///
-/// ```no_run
-/// use std::alloc::{GlobalAlloc, Layout, alloc};
+/// ```
+/// use std::alloc::{GlobalAlloc, Layout};
+/// use std::cell::UnsafeCell;
 /// use std::ptr::null_mut;
+/// use std::sync::atomic::{
+///     AtomicUsize,
+///     Ordering::{Acquire, SeqCst},
+/// };
 ///
-/// struct MyAllocator;
-///
-/// unsafe impl GlobalAlloc for MyAllocator {
-///     unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
-///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// const ARENA_SIZE: usize = 128 * 1024;
+/// const MAX_SUPPORTED_ALIGN: usize = 4096;
+/// #[repr(C, align(4096))] // 4096 == MAX_SUPPORTED_ALIGN
+/// struct SimpleAllocator {
+///     arena: UnsafeCell<[u8; ARENA_SIZE]>,
+///     remaining: AtomicUsize, // we allocate from the top, counting down
 /// }
 ///
 /// #[global_allocator]
-/// static A: MyAllocator = MyAllocator;
+/// static ALLOCATOR: SimpleAllocator = SimpleAllocator {
+///     arena: UnsafeCell::new([0x55; ARENA_SIZE]),
+///     remaining: AtomicUsize::new(ARENA_SIZE),
+/// };
 ///
-/// fn main() {
-///     unsafe {
-///         assert!(alloc(Layout::new::<u32>()).is_null())
+/// unsafe impl Sync for SimpleAllocator {}
+///
+/// unsafe impl GlobalAlloc for SimpleAllocator {
+///     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+///         let size = layout.size();
+///         let align = layout.align();
+///
+///         // `Layout` contract forbids making a `Layout` with align=0, or align not power of 2.
+///         // So we can safely use a mask to ensure alignment without worrying about UB.
+///         let align_mask_to_round_down = !(align - 1);
+///
+///         if align > MAX_SUPPORTED_ALIGN {
+///             return null_mut();
+///         }
+///
+///         let mut allocated = 0;
+///         if self
+///             .remaining
+///             .fetch_update(SeqCst, SeqCst, |mut remaining| {
+///                 if size > remaining {
+///                     return None;
+///                 }
+///                 remaining -= size;
+///                 remaining &= align_mask_to_round_down;
+///                 allocated = remaining;
+///                 Some(remaining)
+///             })
+///             .is_err()
+///         {
+///             return null_mut();
+///         };
+///         (self.arena.get() as *mut u8).add(allocated)
 ///     }
+///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// }
+///
+/// fn main() {
+///     let _s = format!("allocating a string!");
+///     let currently = ALLOCATOR.remaining.load(Acquire);
+///     println!("allocated so far: {}", ARENA_SIZE - currently);
 /// }
 /// ```
 ///
@@ -54,7 +99,7 @@ use crate::ptr;
 ///   this trait are allowed to rely on the contracts defined on each method,
 ///   and implementors must ensure such contracts remain true.
 ///
-/// * You may not rely on allocations actually happening, even if there are explicit
+/// * You must not rely on allocations actually happening, even if there are explicit
 ///   heap allocations in the source. The optimizer may detect unused allocations that it can either
 ///   eliminate entirely or move to the stack and thus never invoke the allocator. The
 ///   optimizer may further assume that allocation is infallible, so code that used to fail due
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 0e7667dd89e..ccf6e420de7 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -60,7 +60,7 @@ impl Layout {
     #[inline]
     pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {
         if !align.is_power_of_two() {
-            return Err(LayoutError { private: () });
+            return Err(LayoutError);
         }
 
         // (power-of-two implies align != 0.)
@@ -78,7 +78,7 @@ impl Layout {
         // Above implies that checking for summation overflow is both
         // necessary and sufficient.
         if size > usize::MAX - (align - 1) {
-            return Err(LayoutError { private: () });
+            return Err(LayoutError);
         }
 
         // SAFETY: the conditions for `from_size_align_unchecked` have been
@@ -288,7 +288,7 @@ impl Layout {
         // > must not overflow (i.e., the rounded value must be less than
         // > `usize::MAX`)
         let padded_size = self.size() + self.padding_needed_for(self.align());
-        let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError { private: () })?;
+        let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?;
 
         // SAFETY: self.align is already known to be valid and alloc_size has been
         // padded already.
@@ -346,8 +346,8 @@ impl Layout {
         let new_align = cmp::max(self.align(), next.align());
         let pad = self.padding_needed_for(next.align());
 
-        let offset = self.size().checked_add(pad).ok_or(LayoutError { private: () })?;
-        let new_size = offset.checked_add(next.size()).ok_or(LayoutError { private: () })?;
+        let offset = self.size().checked_add(pad).ok_or(LayoutError)?;
+        let new_size = offset.checked_add(next.size()).ok_or(LayoutError)?;
 
         let layout = Layout::from_size_align(new_size, new_align)?;
         Ok((layout, offset))
@@ -368,7 +368,7 @@ impl Layout {
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[inline]
     pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
-        let size = self.size().checked_mul(n).ok_or(LayoutError { private: () })?;
+        let size = self.size().checked_mul(n).ok_or(LayoutError)?;
         Layout::from_size_align(size, self.align())
     }
 
@@ -381,7 +381,7 @@ impl Layout {
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[inline]
     pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
-        let new_size = self.size().checked_add(next.size()).ok_or(LayoutError { private: () })?;
+        let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
         Layout::from_size_align(new_size, self.align())
     }
 
@@ -409,10 +409,9 @@ pub type LayoutErr = LayoutError;
 /// or some other `Layout` constructor
 /// do not satisfy its documented constraints.
 #[stable(feature = "alloc_layout_error", since = "1.50.0")]
+#[non_exhaustive]
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub struct LayoutError {
-    private: (),
-}
+pub struct LayoutError;
 
 // (we need this for downstream impl of trait Error)
 #[stable(feature = "alloc_layout", since = "1.28.0")]
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index 06a761531b6..1f1033b0437 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -338,9 +338,9 @@ pub unsafe trait Allocator {
         Ok(new_ptr)
     }
 
-    /// Creates a "by reference" adaptor for this instance of `Allocator`.
+    /// Creates a "by reference" adapter for this instance of `Allocator`.
     ///
-    /// The returned adaptor also implements `Allocator` and will simply borrow this.
+    /// The returned adapter also implements `Allocator` and will simply borrow this.
     #[inline(always)]
     fn by_ref(&self) -> &Self
     where
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 5e1725cfc7a..19652106b3d 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -108,6 +108,7 @@ use crate::intrinsics;
 // unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
 // but we would likely want to indicate as such in documentation).
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Any")]
 pub trait Any: 'static {
     /// Gets the `TypeId` of `self`.
     ///
diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs
new file mode 100644
index 00000000000..a882d18b151
--- /dev/null
+++ b/library/core/src/array/equality.rs
@@ -0,0 +1,155 @@
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N]
+where
+    A: PartialEq<B>,
+{
+    #[inline]
+    fn eq(&self, other: &[B; N]) -> bool {
+        SpecArrayEq::spec_eq(self, other)
+    }
+    #[inline]
+    fn ne(&self, other: &[B; N]) -> bool {
+        SpecArrayEq::spec_ne(self, other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[B]> for [A; N]
+where
+    A: PartialEq<B>,
+{
+    #[inline]
+    fn eq(&self, other: &[B]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[B]) -> bool {
+        self[..] != other[..]
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[A; N]> for [B]
+where
+    B: PartialEq<A>,
+{
+    #[inline]
+    fn eq(&self, other: &[A; N]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[A; N]) -> bool {
+        self[..] != other[..]
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<&[B]> for [A; N]
+where
+    A: PartialEq<B>,
+{
+    #[inline]
+    fn eq(&self, other: &&[B]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &&[B]) -> bool {
+        self[..] != other[..]
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[A; N]> for &[B]
+where
+    B: PartialEq<A>,
+{
+    #[inline]
+    fn eq(&self, other: &[A; N]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[A; N]) -> bool {
+        self[..] != other[..]
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<&mut [B]> for [A; N]
+where
+    A: PartialEq<B>,
+{
+    #[inline]
+    fn eq(&self, other: &&mut [B]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &&mut [B]) -> bool {
+        self[..] != other[..]
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A, B, const N: usize> PartialEq<[A; N]> for &mut [B]
+where
+    B: PartialEq<A>,
+{
+    #[inline]
+    fn eq(&self, other: &[A; N]) -> bool {
+        self[..] == other[..]
+    }
+    #[inline]
+    fn ne(&self, other: &[A; N]) -> bool {
+        self[..] != other[..]
+    }
+}
+
+// NOTE: some less important impls are omitted to reduce code bloat
+// __impl_slice_eq2! { [A; $N], &'b [B; $N] }
+// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Eq, const N: usize> Eq for [T; N] {}
+
+trait SpecArrayEq<Other, const N: usize>: Sized {
+    fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool;
+    fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool;
+}
+
+impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T {
+    default fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool {
+        a[..] == b[..]
+    }
+    default fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool {
+        a[..] != b[..]
+    }
+}
+
+impl<T: PartialEq<U> + IsRawEqComparable<U>, U, const N: usize> SpecArrayEq<U, N> for T {
+    fn spec_eq(a: &[T; N], b: &[U; N]) -> bool {
+        // SAFETY: This is why `IsRawEqComparable` is an `unsafe trait`.
+        unsafe {
+            let b = &*b.as_ptr().cast::<[T; N]>();
+            crate::intrinsics::raw_eq(a, b)
+        }
+    }
+    fn spec_ne(a: &[T; N], b: &[U; N]) -> bool {
+        !Self::spec_eq(a, b)
+    }
+}
+
+/// `U` exists on here mostly because `min_specialization` didn't let me
+/// repeat the `T` type parameter in the above specialization, so instead
+/// the `T == U` constraint comes from the impls on this.
+/// # Safety
+/// - Neither `Self` nor `U` has any padding.
+/// - `Self` and `U` have the same layout.
+/// - `Self: PartialEq<U>` is byte-wise (this means no floats, among other things)
+#[rustc_specialization_trait]
+unsafe trait IsRawEqComparable<U> {}
+
+macro_rules! is_raw_comparable {
+    ($($t:ty),+) => {$(
+        unsafe impl IsRawEqComparable<$t> for $t {}
+    )+};
+}
+is_raw_comparable!(bool, char, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index aedbeab6610..f6616399610 100644
--- a/library/core/src/array/iter.rs
+++ b/library/core/src/array/iter.rs
@@ -2,7 +2,7 @@
 
 use crate::{
     fmt,
-    iter::{self, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess},
+    iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
     mem::{self, MaybeUninit},
     ops::Range,
     ptr,
@@ -123,6 +123,27 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
         (len, Some(len))
     }
 
+    #[inline]
+    fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let data = &mut self.data;
+        // FIXME: This uses try_fold(&mut iter) instead of fold(iter) because the latter
+        //  would go through the blanket `impl Iterator for &mut I` implementation
+        //  which lacks inline annotations on its methods and adding those would be a larger
+        //  perturbation than using try_fold here.
+        //  Whether it would be beneficial to add those annotations should be investigated separately.
+        (&mut self.alive)
+            .try_fold::<_, _, Result<_, !>>(init, |acc, idx| {
+                // SAFETY: idx is obtained by folding over the `alive` range, which implies the
+                // value is currently considered alive but as the range is being consumed each value
+                // we read here will only be read once and then considered dead.
+                Ok(fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() }))
+            })
+            .unwrap()
+    }
+
     fn count(self) -> usize {
         self.len()
     }
@@ -130,18 +151,6 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
     fn last(mut self) -> Option<Self::Item> {
         self.next_back()
     }
-
-    #[inline]
-    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
-    where
-        Self: TrustedRandomAccess,
-    {
-        // SAFETY: Callers are only allowed to pass an index that is in bounds
-        // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
-        // multiple repeated reads of the same index would be safe and the
-        // values are !Drop, thus won't suffer from double drops.
-        unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
-    }
 }
 
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
@@ -196,17 +205,6 @@ impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
 unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}
 
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
-// and thus we can't implement drop-handling
-unsafe impl<T, const N: usize> TrustedRandomAccess for IntoIter<T, N>
-where
-    T: Copy,
-{
-    const MAY_HAVE_SIDE_EFFECT: bool = false;
-}
-
 #[stable(feature = "array_value_iter_impls", since = "1.40.0")]
 impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
     fn clone(&self) -> Self {
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 37af3557fdd..3c638e655dc 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -14,6 +14,7 @@ use crate::mem::{self, MaybeUninit};
 use crate::ops::{Index, IndexMut};
 use crate::slice::{Iter, IterMut};
 
+mod equality;
 mod iter;
 
 #[stable(feature = "array_value_iter", since = "1.51.0")]
@@ -139,6 +140,18 @@ impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
     }
 }
 
+/// The hash of an array is the same as that of the corresponding slice,
+/// as required by the `Borrow` implementation.
+///
+/// ```
+/// #![feature(build_hasher_simple_hash_one)]
+/// use std::hash::BuildHasher;
+///
+/// let b = std::collections::hash_map::RandomState::new();
+/// let a: [u8; 3] = [0xa8, 0x3c, 0x09];
+/// let s: &[u8] = &[0xa8, 0x3c, 0x09];
+/// assert_eq!(b.hash_one(a), b.hash_one(s));
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Hash, const N: usize> Hash for [T; N] {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
@@ -219,118 +232,6 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N]
-where
-    A: PartialEq<B>,
-{
-    #[inline]
-    fn eq(&self, other: &[B; N]) -> bool {
-        self[..] == other[..]
-    }
-    #[inline]
-    fn ne(&self, other: &[B; N]) -> bool {
-        self[..] != other[..]
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, const N: usize> PartialEq<[B]> for [A; N]
-where
-    A: PartialEq<B>,
-{
-    #[inline]
-    fn eq(&self, other: &[B]) -> bool {
-        self[..] == other[..]
-    }
-    #[inline]
-    fn ne(&self, other: &[B]) -> bool {
-        self[..] != other[..]
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, const N: usize> PartialEq<[A; N]> for [B]
-where
-    B: PartialEq<A>,
-{
-    #[inline]
-    fn eq(&self, other: &[A; N]) -> bool {
-        self[..] == other[..]
-    }
-    #[inline]
-    fn ne(&self, other: &[A; N]) -> bool {
-        self[..] != other[..]
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, const N: usize> PartialEq<&[B]> for [A; N]
-where
-    A: PartialEq<B>,
-{
-    #[inline]
-    fn eq(&self, other: &&[B]) -> bool {
-        self[..] == other[..]
-    }
-    #[inline]
-    fn ne(&self, other: &&[B]) -> bool {
-        self[..] != other[..]
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, const N: usize> PartialEq<[A; N]> for &[B]
-where
-    B: PartialEq<A>,
-{
-    #[inline]
-    fn eq(&self, other: &[A; N]) -> bool {
-        self[..] == other[..]
-    }
-    #[inline]
-    fn ne(&self, other: &[A; N]) -> bool {
-        self[..] != other[..]
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, const N: usize> PartialEq<&mut [B]> for [A; N]
-where
-    A: PartialEq<B>,
-{
-    #[inline]
-    fn eq(&self, other: &&mut [B]) -> bool {
-        self[..] == other[..]
-    }
-    #[inline]
-    fn ne(&self, other: &&mut [B]) -> bool {
-        self[..] != other[..]
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, const N: usize> PartialEq<[A; N]> for &mut [B]
-where
-    B: PartialEq<A>,
-{
-    #[inline]
-    fn eq(&self, other: &[A; N]) -> bool {
-        self[..] == other[..]
-    }
-    #[inline]
-    fn ne(&self, other: &[A; N]) -> bool {
-        self[..] != other[..]
-    }
-}
-
-// NOTE: some less important impls are omitted to reduce code bloat
-// __impl_slice_eq2! { [A; $N], &'b [B; $N] }
-// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Eq, const N: usize> Eq for [T; N] {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialOrd, const N: usize> PartialOrd for [T; N] {
     #[inline]
     fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> {
@@ -379,7 +280,8 @@ macro_rules! array_impl_default {
     };
     {$n:expr,} => {
         #[stable(since = "1.4.0", feature = "array_default")]
-        impl<T> Default for [T; $n] {
+        #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+        impl<T> const Default for [T; $n] {
             fn default() -> [T; $n] { [] }
         }
     };
@@ -392,10 +294,31 @@ impl<T, const N: usize> [T; N] {
     /// Returns an array of the same size as `self`, with function `f` applied to each element
     /// in order.
     ///
+    /// If you don't necessarily need a new fixed-size array, consider using
+    /// [`Iterator::map`] instead.
+    ///
+    ///
+    /// # Note on performance and stack usage
+    ///
+    /// Unfortunately, usages of this method are currently not always optimized
+    /// as well as they could be. This mainly concerns large arrays, as mapping
+    /// over small arrays seem to be optimized just fine. Also note that in
+    /// debug mode (i.e. without any optimizations), this method can use a lot
+    /// of stack space (a few times the size of the array or more).
+    ///
+    /// Therefore, in performance-critical code, try to avoid using this method
+    /// on large arrays or check the emitted code. Also try to avoid chained
+    /// maps (e.g. `arr.map(...).map(...)`).
+    ///
+    /// In many cases, you can instead use [`Iterator::map`] by calling `.iter()`
+    /// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you
+    /// really need a new array of the same size as the result. Rust's lazy
+    /// iterators tend to get optimized very well.
+    ///
+    ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(array_map)]
     /// let x = [1, 2, 3];
     /// let y = x.map(|v| v + 1);
     /// assert_eq!(y, [2, 3, 4]);
@@ -409,7 +332,7 @@ impl<T, const N: usize> [T; N] {
     /// let y = x.map(|v| v.len());
     /// assert_eq!(y, [6, 9, 3, 3]);
     /// ```
-    #[unstable(feature = "array_map", issue = "75243")]
+    #[stable(feature = "array_map", since = "1.55.0")]
     pub fn map<F, U>(self, f: F) -> [U; N]
     where
         F: FnMut(T) -> U,
@@ -476,7 +399,7 @@ impl<T, const N: usize> [T; N] {
     /// array if its elements are not `Copy`.
     ///
     /// ```
-    /// #![feature(array_methods, array_map)]
+    /// #![feature(array_methods)]
     ///
     /// let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()];
     /// let is_ascii = strings.each_ref().map(|s| s.is_ascii());
diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs
index 00164c631b3..dcafaae2f5b 100644
--- a/library/core/src/bool.rs
+++ b/library/core/src/bool.rs
@@ -12,7 +12,7 @@ impl bool {
     /// assert_eq!(false.then_some(0), None);
     /// assert_eq!(true.then_some(0), Some(0));
     /// ```
-    #[unstable(feature = "bool_to_option", issue = "64260")]
+    #[unstable(feature = "bool_to_option", issue = "80967")]
     #[inline]
     pub fn then_some<T>(self, t: T) -> Option<T> {
         if self { Some(t) } else { None }
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index f88a6e418c7..f0c934edf39 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -488,6 +488,13 @@ impl<T: ?Sized> Cell<T> {
     /// This call borrows `Cell` mutably (at compile-time) which guarantees
     /// that we possess the only reference.
     ///
+    /// However be cautious: this method expects `self` to be mutable, which is
+    /// generally not the case when using a `Cell`. If you require interior
+    /// mutability by reference, consider using `RefCell` which provides
+    /// run-time checked mutable borrows through its [`borrow_mut`] method.
+    ///
+    /// [`borrow_mut`]: RefCell::borrow_mut()
+    ///
     /// # Examples
     ///
     /// ```
@@ -576,9 +583,9 @@ impl<T> Cell<[T]> {
 pub struct RefCell<T: ?Sized> {
     borrow: Cell<BorrowFlag>,
     // Stores the location of the earliest currently active borrow.
-    // This gets updated whenver we go from having zero borrows
+    // This gets updated whenever we go from having zero borrows
     // to having a single borrow. When a borrow occurs, this gets included
-    // in the generated `BorroeError/`BorrowMutError`
+    // in the generated `BorrowError/`BorrowMutError`
     #[cfg(feature = "debug_refcell")]
     borrowed_at: Cell<Option<&'static crate::panic::Location<'static>>>,
     value: UnsafeCell<T>,
@@ -586,8 +593,8 @@ pub struct RefCell<T: ?Sized> {
 
 /// An error returned by [`RefCell::try_borrow`].
 #[stable(feature = "try_borrow", since = "1.13.0")]
+#[non_exhaustive]
 pub struct BorrowError {
-    _private: (),
     #[cfg(feature = "debug_refcell")]
     location: &'static crate::panic::Location<'static>,
 }
@@ -613,8 +620,8 @@ impl Display for BorrowError {
 
 /// An error returned by [`RefCell::try_borrow_mut`].
 #[stable(feature = "try_borrow", since = "1.13.0")]
+#[non_exhaustive]
 pub struct BorrowMutError {
-    _private: (),
     #[cfg(feature = "debug_refcell")]
     location: &'static crate::panic::Location<'static>,
 }
@@ -865,7 +872,6 @@ impl<T: ?Sized> RefCell<T> {
                 Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b })
             }
             None => Err(BorrowError {
-                _private: (),
                 // If a borrow occured, then we must already have an outstanding borrow,
                 // so `borrowed_at` will be `Some`
                 #[cfg(feature = "debug_refcell")]
@@ -951,7 +957,6 @@ impl<T: ?Sized> RefCell<T> {
                 Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b })
             }
             None => Err(BorrowMutError {
-                _private: (),
                 // If a borrow occured, then we must already have an outstanding borrow,
                 // so `borrowed_at` will be `Some`
                 #[cfg(feature = "debug_refcell")]
@@ -1073,7 +1078,6 @@ impl<T: ?Sized> RefCell<T> {
             Ok(unsafe { &*self.value.get() })
         } else {
             Err(BorrowError {
-                _private: (),
                 // If a borrow occured, then we must already have an outstanding borrow,
                 // so `borrowed_at` will be `Some`
                 #[cfg(feature = "debug_refcell")]
diff --git a/library/core/src/char/decode.rs b/library/core/src/char/decode.rs
index 5e7784730e3..4784418f98c 100644
--- a/library/core/src/char/decode.rs
+++ b/library/core/src/char/decode.rs
@@ -5,6 +5,11 @@ use crate::fmt;
 use super::from_u32_unchecked;
 
 /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
+///
+/// This `struct` is created by the [`decode_utf16`] method on [`char`]. See its
+/// documentation for more.
+///
+/// [`decode_utf16`]: char::decode_utf16
 #[stable(feature = "decode_utf16", since = "1.9.0")]
 #[derive(Clone, Debug)]
 pub struct DecodeUtf16<I>
@@ -16,6 +21,8 @@ where
 }
 
 /// An error that can be returned when decoding UTF-16 code points.
+///
+/// This `struct` is created when using the [`DecodeUtf16`] type.
 #[stable(feature = "decode_utf16", since = "1.9.0")]
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct DecodeUtf16Error {
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index 2da3d6a72fb..e5af22c8fbb 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -1,6 +1,5 @@
 //! impl char {}
 
-use crate::intrinsics::likely;
 use crate::slice;
 use crate::str::from_utf8_unchecked_mut;
 use crate::unicode::printable::is_printable;
@@ -16,8 +15,8 @@ impl char {
     /// Point], but only ones within a certain range. `MAX` is the highest valid
     /// code point that's a valid [Unicode Scalar Value].
     ///
-    /// [Unicode Scalar Value]: http://www.unicode.org/glossary/#unicode_scalar_value
-    /// [Code Point]: http://www.unicode.org/glossary/#code_point
+    /// [Unicode Scalar Value]: https://www.unicode.org/glossary/#unicode_scalar_value
+    /// [Code Point]: https://www.unicode.org/glossary/#code_point
     #[stable(feature = "assoc_char_consts", since = "1.52.0")]
     pub const MAX: char = '\u{10ffff}';
 
@@ -29,7 +28,7 @@ impl char {
     #[stable(feature = "assoc_char_consts", since = "1.52.0")]
     pub const REPLACEMENT_CHARACTER: char = '\u{FFFD}';
 
-    /// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
+    /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
     /// `char` and `str` methods are based on.
     ///
     /// New versions of Unicode are released regularly and subsequently all methods
@@ -332,21 +331,16 @@ impl char {
     #[inline]
     pub fn to_digit(self, radix: u32) -> Option<u32> {
         assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
-        // the code is split up here to improve execution speed for cases where
-        // the `radix` is constant and 10 or smaller
-        let val = if likely(radix <= 10) {
-            // If not a digit, a number greater than radix will be created.
-            (self as u32).wrapping_sub('0' as u32)
-        } else {
-            match self {
-                '0'..='9' => self as u32 - '0' as u32,
-                'a'..='z' => self as u32 - 'a' as u32 + 10,
-                'A'..='Z' => self as u32 - 'A' as u32 + 10,
-                _ => return None,
+        // If not a digit, a number greater than radix will be created.
+        let mut digit = (self as u32).wrapping_sub('0' as u32);
+        if radix > 10 {
+            if digit < 10 {
+                return Some(digit);
             }
-        };
-
-        if val < radix { Some(val) } else { None }
+            // Force the 6th bit to be set to ensure ascii is lower case.
+            digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
+        }
+        (digit < radix).then_some(digit)
     }
 
     /// Returns an iterator that yields the hexadecimal Unicode escape of a
@@ -1500,8 +1494,8 @@ impl char {
     /// before using this function.
     ///
     /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
-    /// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
-    /// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
+    /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
+    /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
     ///
     /// # Examples
     ///
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index 25a7c1de9de..0728523d0a4 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -5,8 +5,8 @@
 //! scalar value]', which is similar to, but not the same as, a '[Unicode code
 //! point]'.
 //!
-//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
-//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
+//! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
+//! [Unicode code point]: https://www.unicode.org/glossary/#code_point
 //!
 //! This module exists for technical reasons, the primary documentation for
 //! `char` is directly on [the `char` primitive type][char] itself.
@@ -95,8 +95,8 @@ const MAX_THREE_B: u32 = 0x10000;
 /// Point], but only ones within a certain range. `MAX` is the highest valid
 /// code point that's a valid [Unicode Scalar Value].
 ///
-/// [Unicode Scalar Value]: http://www.unicode.org/glossary/#unicode_scalar_value
-/// [Code Point]: http://www.unicode.org/glossary/#code_point
+/// [Unicode Scalar Value]: https://www.unicode.org/glossary/#unicode_scalar_value
+/// [Code Point]: https://www.unicode.org/glossary/#code_point
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const MAX: char = char::MAX;
 
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 51a2dc03de3..19faf9cddac 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -38,7 +38,7 @@
 
 /// A common trait for the ability to explicitly duplicate an object.
 ///
-/// Differs from [`Copy`] in that [`Copy`] is implicit and extremely inexpensive, while
+/// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while
 /// `Clone` is always explicit and may or may not be expensive. In order to enforce
 /// these characteristics, Rust does not allow you to reimplement [`Copy`], but you
 /// may reimplement `Clone` and run arbitrary code.
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index ecea898504d..79610bb409d 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -27,12 +27,25 @@ use self::Ordering::*;
 /// Trait for equality comparisons which are [partial equivalence
 /// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
 ///
+/// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
+/// We use the easier-to-read infix notation in the remainder of this documentation.
+///
 /// This trait allows for partial equality, for types that do not have a full
 /// equivalence relation. For example, in floating point numbers `NaN != NaN`,
 /// so floating point types implement `PartialEq` but not [`trait@Eq`].
 ///
-/// Formally, the equality must be (for all `a`, `b`, `c` of type `A`, `B`,
-/// `C`):
+/// Implementations must ensure that `eq` and `ne` are consistent with each other:
+///
+/// - `a != b` if and only if `!(a == b)`
+///   (ensured by the default implementation).
+///
+/// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also
+/// be consistent with `PartialEq` (see the documentation of those traits for the exact
+/// requirements). It's easy to accidentally make them disagree by deriving some of the traits and
+/// manually implementing others.
+///
+/// The equality relation `==` must satisfy the following conditions
+/// (for all `a`, `b`, `c` of type `A`, `B`, `C`):
 ///
 /// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
 ///   implies `b == a`**; and
@@ -53,15 +66,6 @@ use self::Ordering::*;
 ///
 /// ## How can I implement `PartialEq`?
 ///
-/// `PartialEq` only requires the [`eq`] method to be implemented; [`ne`] is defined
-/// in terms of it by default. Any manual implementation of [`ne`] *must* respect
-/// the rule that [`eq`] is a strict inverse of [`ne`]; that is, `!(a == b)` if and
-/// only if `a != b`.
-///
-/// Implementations of `PartialEq`, [`PartialOrd`], and [`Ord`] *must* agree with
-/// each other. It's easy to accidentally make them disagree by deriving some
-/// of the traits and manually implementing others.
-///
 /// An example implementation for a domain in which two books are considered
 /// the same book if their ISBN matches, even if the formats differ:
 ///
@@ -631,10 +635,25 @@ impl<T: Clone> Clone for Reverse<T> {
 
 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
 ///
-/// An order is a total order if it is (for all `a`, `b` and `c`):
+/// Implementations must be consistent with the [`PartialOrd`] implementation, and ensure
+/// `max`, `min`, and `clamp` are consistent with `cmp`:
+///
+/// - `partial_cmp(a, b) == Some(cmp(a, b))`.
+/// - `max(a, b) == max_by(a, b, cmp)` (ensured by the default implementation).
+/// - `min(a, b) == min_by(a, b, cmp)` (ensured by the default implementation).
+/// - For `a.clamp(min, max)`, see the [method docs](#method.clamp)
+///   (ensured by the default implementation).
+///
+/// It's easy to accidentally make `cmp` and `partial_cmp` disagree by
+/// deriving some of the traits and manually implementing others.
+///
+/// ## Corollaries
+///
+/// From the above and the requirements of `PartialOrd`, it follows that `<` defines a strict total order.
+/// This means that for all `a`, `b` and `c`:
 ///
-/// - total and asymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
-/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
+/// - exactly one of `a < b`, `a == b` or `a > b` is true; and
+/// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
 ///
 /// ## Derivable
 ///
@@ -659,12 +678,6 @@ impl<T: Clone> Clone for Reverse<T> {
 /// Then you must define an implementation for [`cmp`]. You may find it useful to use
 /// [`cmp`] on your type's fields.
 ///
-/// Implementations of [`PartialEq`], [`PartialOrd`], and `Ord` *must*
-/// agree with each other. That is, `a.cmp(b) == Ordering::Equal` if
-/// and only if `a == b` and `Some(a.cmp(b)) == a.partial_cmp(b)` for
-/// all `a` and `b`. It's easy to accidentally make them disagree by
-/// deriving some of the traits and manually implementing others.
-///
 /// Here's an example where you want to sort people by height only, disregarding `id`
 /// and `name`:
 ///
@@ -824,15 +837,45 @@ impl PartialOrd for Ordering {
 
 /// Trait for values that can be compared for a sort-order.
 ///
+/// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
+/// the `<`, `<=`, `>`, and `>=` operators, respectively.
+///
+/// The methods of this trait must be consistent with each other and with those of `PartialEq` in
+/// the following sense:
+///
+/// - `a == b` if and only if `partial_cmp(a, b) == Some(Equal)`.
+/// - `a < b` if and only if `partial_cmp(a, b) == Some(Less)`
+///   (ensured by the default implementation).
+/// - `a > b` if and only if `partial_cmp(a, b) == Some(Greater)`
+///   (ensured by the default implementation).
+/// - `a <= b` if and only if `a < b || a == b`
+///   (ensured by the default implementation).
+/// - `a >= b` if and only if `a > b || a == b`
+///   (ensured by the default implementation).
+/// - `a != b` if and only if `!(a == b)` (already part of `PartialEq`).
+///
+/// If [`Ord`] is also implemented for `Self` and `Rhs`, it must also be consistent with
+/// `partial_cmp` (see the documentation of that trait for the exact requirements). It's
+/// easy to accidentally make them disagree by deriving some of the traits and manually
+/// implementing others.
+///
 /// The comparison must satisfy, for all `a`, `b` and `c`:
 ///
-/// - asymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and
 /// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
+/// - duality: `a < b` if and only if `b > a`.
 ///
 /// Note that these requirements mean that the trait itself must be implemented symmetrically and
 /// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
 /// PartialOrd<V>`.
 ///
+/// ## Corollaries
+///
+/// The following corollaries follow from the above requirements:
+///
+/// - irreflexivity of `<` and `>`: `!(a < a)`, `!(a > a)`
+/// - transitivity of `>`: if `a > b` and `b > c` then `a > c`
+/// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)`
+///
 /// ## Derivable
 ///
 /// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
@@ -850,10 +893,6 @@ impl PartialOrd for Ordering {
 ///
 /// `PartialOrd` requires your type to be [`PartialEq`].
 ///
-/// Implementations of [`PartialEq`], `PartialOrd`, and [`Ord`] *must* agree with each other. It's
-/// easy to accidentally make them disagree by deriving some of the traits and manually
-/// implementing others.
-///
 /// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]:
 ///
 /// ```
@@ -1065,6 +1104,7 @@ pub macro PartialOrd($item:item) {
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")]
 pub fn min<T: Ord>(v1: T, v2: T) -> T {
     v1.min(v2)
 }
@@ -1127,6 +1167,7 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")]
 pub fn max<T: Ord>(v1: T, v2: T) -> T {
     v1.max(v2)
 }
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 65af8508a68..1e512af4805 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -152,6 +152,7 @@ pub const fn identity<T>(x: T) -> T {
 /// is_hello(s);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")]
 pub trait AsRef<T: ?Sized> {
     /// Performs the conversion.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -193,6 +194,7 @@ pub trait AsRef<T: ?Sized> {
 ///
 /// [`Box<T>`]: ../../std/boxed/struct.Box.html
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")]
 pub trait AsMut<T: ?Sized> {
     /// Performs the conversion.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs
index a522b7da3bd..75ef873abc9 100644
--- a/library/core/src/convert/num.rs
+++ b/library/core/src/convert/num.rs
@@ -45,7 +45,8 @@ impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
 macro_rules! impl_from {
     ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => {
         #[$attr]
-        impl From<$Small> for $Large {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const From<$Small> for $Large {
             // Rustdocs on the impl block show a "[+] show undocumented items" toggle.
             // Rustdocs on functions do not.
             #[doc = $doc]
@@ -145,7 +146,7 @@ impl_from! { i16, isize, #[stable(feature = "lossless_iusize_conv", since = "1.2
 
 // CHERI proposes 256-bit “capabilities”. Unclear if this would be relevant to usize/isize.
 // https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/20171017a-cheri-poster.pdf
-// http://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf
+// https://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf
 
 // Note: integers can only be represented with full precision in a float if
 // they fit in the significand, which is 24 bits in f32 and 53 bits in f64.
@@ -172,7 +173,8 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
 macro_rules! try_from_unbounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
@@ -190,7 +192,8 @@ macro_rules! try_from_unbounded {
 macro_rules! try_from_lower_bounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
@@ -212,7 +215,8 @@ macro_rules! try_from_lower_bounded {
 macro_rules! try_from_upper_bounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
@@ -234,7 +238,8 @@ macro_rules! try_from_upper_bounded {
 macro_rules! try_from_both_bounded {
     ($source:ty, $($target:ty),*) => {$(
         #[stable(feature = "try_from", since = "1.34.0")]
-        impl TryFrom<$source> for $target {
+        #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
+        impl const TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
             /// Try to create the target number type from a source
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index fd7159d35fa..0ee8cd59ba4 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -161,7 +161,7 @@ pub fn default<T: Default>() -> T {
 }
 
 /// Derive macro generating an impl of the trait `Default`.
-#[rustc_builtin_macro]
+#[rustc_builtin_macro(Default, attributes(default))]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro Default($item:item) {
@@ -171,7 +171,8 @@ pub macro Default($item:item) {
 macro_rules! default_impl {
     ($t:ty, $v:expr, $doc:tt) => {
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl Default for $t {
+        #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+        impl const Default for $t {
             #[inline]
             #[doc = $doc]
             fn default() -> $t {
diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs
index b660788c051..8e7b03d02f1 100644
--- a/library/core/src/fmt/builders.rs
+++ b/library/core/src/fmt/builders.rs
@@ -23,10 +23,7 @@ impl<'buf, 'state> PadAdapter<'buf, 'state> {
         slot: &'slot mut Option<Self>,
         state: &'state mut PadAdapterState,
     ) -> fmt::Formatter<'slot> {
-        fmt.wrap_buf(move |buf| {
-            *slot = Some(PadAdapter { buf, state });
-            slot.as_mut().unwrap()
-        })
+        fmt.wrap_buf(move |buf| slot.insert(PadAdapter { buf, state }))
     }
 }
 
diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs
index ece3cde0015..ba65f0fadbd 100644
--- a/library/core/src/fmt/float.rs
+++ b/library/core/src/fmt/float.rs
@@ -1,6 +1,7 @@
 use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
 use crate::mem::MaybeUninit;
 use crate::num::flt2dec;
+use crate::num::fmt as numfmt;
 
 // Don't inline this so callers don't use the stack space this function
 // requires unless they have to.
@@ -15,7 +16,7 @@ where
     T: flt2dec::DecodableFloat,
 {
     let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
-    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
+    let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array();
     let formatted = flt2dec::to_exact_fixed_str(
         flt2dec::strategy::grisu::format_exact,
         *num,
@@ -41,7 +42,7 @@ where
 {
     // enough for f32 and f64
     let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
-    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 4] = MaybeUninit::uninit_array();
+    let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array();
     let formatted = flt2dec::to_shortest_str(
         flt2dec::strategy::grisu::format_shortest,
         *num,
@@ -85,7 +86,7 @@ where
     T: flt2dec::DecodableFloat,
 {
     let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64
-    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
+    let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array();
     let formatted = flt2dec::to_exact_exp_str(
         flt2dec::strategy::grisu::format_exact,
         *num,
@@ -112,7 +113,7 @@ where
 {
     // enough for f32 and f64
     let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array();
-    let mut parts: [MaybeUninit<flt2dec::Part<'_>>; 6] = MaybeUninit::uninit_array();
+    let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array();
     let formatted = flt2dec::to_shortest_exp_str(
         flt2dec::strategy::grisu::format_shortest,
         *num,
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 02ac4fb8006..6ad10990840 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -7,13 +7,16 @@ use crate::char::EscapeDebugExtArgs;
 use crate::iter;
 use crate::marker::PhantomData;
 use crate::mem;
-use crate::num::flt2dec;
+use crate::num::fmt as numfmt;
 use crate::ops::Deref;
 use crate::result;
 use crate::str;
 
 mod builders;
+#[cfg(not(no_fp_fmt_parse))]
 mod float;
+#[cfg(no_fp_fmt_parse)]
+mod nofloat;
 mod num;
 
 #[stable(feature = "fmt_flags_align", since = "1.28.0")]
@@ -334,7 +337,8 @@ impl<'a> Arguments<'a> {
     #[doc(hidden)]
     #[inline]
     #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
-    pub fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
+    #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
+    pub const fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
         Arguments { pieces, fmt: None, args }
     }
 
@@ -347,7 +351,8 @@ impl<'a> Arguments<'a> {
     #[doc(hidden)]
     #[inline]
     #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
-    pub fn new_v1_formatted(
+    #[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
+    pub const fn new_v1_formatted(
         pieces: &'a [&'static str],
         args: &'a [ArgumentV1<'a>],
         fmt: &'a [rt::v1::Argument],
@@ -444,8 +449,9 @@ impl<'a> Arguments<'a> {
     /// assert_eq!(format_args!("{}", 1).as_str(), None);
     /// ```
     #[stable(feature = "fmt_as_str", since = "1.52.0")]
+    #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "none")]
     #[inline]
-    pub fn as_str(&self) -> Option<&'static str> {
+    pub const fn as_str(&self) -> Option<&'static str> {
         match (self.pieces, self.args) {
             ([], []) => Some(""),
             ([s], []) => Some(s),
@@ -564,7 +570,7 @@ impl Display for Arguments<'_> {
     on(
         crate_local,
         label = "`{Self}` cannot be formatted using `{{:?}}`",
-        note = "add `#[derive(Debug)]` or manually implement `{Debug}`"
+        note = "add `#[derive(Debug)]` to `{Self}` or manually `impl {Debug} for {Self}`"
     ),
     message = "`{Self}` doesn't implement `{Debug}`",
     label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`"
@@ -662,6 +668,7 @@ pub use macros::Debug;
     note = "in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead"
 )]
 #[doc(alias = "{}")]
+#[rustc_diagnostic_item = "display_trait"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Display {
     /// Formats the value using the given formatter.
@@ -1421,7 +1428,7 @@ impl<'a> Formatter<'a> {
     /// Takes the formatted parts and applies the padding.
     /// Assumes that the caller already has rendered the parts with required precision,
     /// so that `self.precision` can be ignored.
-    fn pad_formatted_parts(&mut self, formatted: &flt2dec::Formatted<'_>) -> Result {
+    fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
         if let Some(mut width) = self.width {
             // for the sign-aware zero padding, we render the sign first and
             // behave as if we had no sign from the beginning.
@@ -1461,14 +1468,14 @@ impl<'a> Formatter<'a> {
         }
     }
 
-    fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted<'_>) -> Result {
+    fn write_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result {
         fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result {
-            // SAFETY: This is used for `flt2dec::Part::Num` and `flt2dec::Part::Copy`.
-            // It's safe to use for `flt2dec::Part::Num` since every char `c` is between
+            // SAFETY: This is used for `numfmt::Part::Num` and `numfmt::Part::Copy`.
+            // It's safe to use for `numfmt::Part::Num` since every char `c` is between
             // `b'0'` and `b'9'`, which means `s` is valid UTF-8.
-            // It's also probably safe in practice to use for `flt2dec::Part::Copy(buf)`
+            // It's also probably safe in practice to use for `numfmt::Part::Copy(buf)`
             // since `buf` should be plain ASCII, but it's possible for someone to pass
-            // in a bad value for `buf` into `flt2dec::to_shortest_str` since it is a
+            // in a bad value for `buf` into `numfmt::to_shortest_str` since it is a
             // public function.
             // FIXME: Determine whether this could result in UB.
             buf.write_str(unsafe { str::from_utf8_unchecked(s) })
@@ -1479,7 +1486,7 @@ impl<'a> Formatter<'a> {
         }
         for part in formatted.parts {
             match *part {
-                flt2dec::Part::Zero(mut nzeroes) => {
+                numfmt::Part::Zero(mut nzeroes) => {
                     const ZEROES: &str = // 64 zeroes
                         "0000000000000000000000000000000000000000000000000000000000000000";
                     while nzeroes > ZEROES.len() {
@@ -1490,7 +1497,7 @@ impl<'a> Formatter<'a> {
                         self.buf.write_str(&ZEROES[..nzeroes])?;
                     }
                 }
-                flt2dec::Part::Num(mut v) => {
+                numfmt::Part::Num(mut v) => {
                     let mut s = [0; 5];
                     let len = part.len();
                     for c in s[..len].iter_mut().rev() {
@@ -1499,7 +1506,7 @@ impl<'a> Formatter<'a> {
                     }
                     write_bytes(self.buf, &s[..len])?;
                 }
-                flt2dec::Part::Copy(buf) => {
+                numfmt::Part::Copy(buf) => {
                     write_bytes(self.buf, buf)?;
                 }
             }
diff --git a/library/core/src/fmt/nofloat.rs b/library/core/src/fmt/nofloat.rs
new file mode 100644
index 00000000000..cfb94cd9de5
--- /dev/null
+++ b/library/core/src/fmt/nofloat.rs
@@ -0,0 +1,15 @@
+use crate::fmt::{Debug, Formatter, Result};
+
+macro_rules! floating {
+    ($ty:ident) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Debug for $ty {
+            fn fmt(&self, _fmt: &mut Formatter<'_>) -> Result {
+                panic!("floating point support is turned off");
+            }
+        }
+    };
+}
+
+floating! { f32 }
+floating! { f64 }
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index cdd731fdd4d..db45640df48 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -2,7 +2,7 @@
 
 use crate::fmt;
 use crate::mem::MaybeUninit;
-use crate::num::flt2dec;
+use crate::num::fmt as numfmt;
 use crate::ops::{Div, Rem, Sub};
 use crate::ptr;
 use crate::slice;
@@ -406,9 +406,9 @@ macro_rules! impl_Exp {
             };
 
             let parts = &[
-                flt2dec::Part::Copy(buf_slice),
-                flt2dec::Part::Zero(added_precision),
-                flt2dec::Part::Copy(exp_slice)
+                numfmt::Part::Copy(buf_slice),
+                numfmt::Part::Zero(added_precision),
+                numfmt::Part::Copy(exp_slice)
             ];
             let sign = if !is_nonnegative {
                 "-"
@@ -417,7 +417,7 @@ macro_rules! impl_Exp {
             } else {
                 ""
             };
-            let formatted = flt2dec::Formatted{sign, parts};
+            let formatted = numfmt::Formatted{sign, parts};
             f.pad_formatted_parts(&formatted)
         }
 
diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs
index 15952c6806f..09d8a2aac26 100644
--- a/library/core/src/future/future.rs
+++ b/library/core/src/future/future.rs
@@ -7,7 +7,7 @@ use crate::task::{Context, Poll};
 
 /// A future represents an asynchronous computation.
 ///
-/// A future is a value that may not have finished computing yet. This kind of
+/// A future is a value that might not have finished computing yet. This kind of
 /// "asynchronous value" makes it possible for a thread to continue doing useful
 /// work while it waits for the value to become available.
 ///
@@ -111,11 +111,11 @@ impl<F: ?Sized + Future + Unpin> Future for &mut F {
 #[stable(feature = "futures_api", since = "1.36.0")]
 impl<P> Future for Pin<P>
 where
-    P: Unpin + ops::DerefMut<Target: Future>,
+    P: ops::DerefMut<Target: Future>,
 {
     type Output = <<P as ops::Deref>::Target as Future>::Output;
 
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-        Pin::get_mut(self).as_mut().poll(cx)
+        <P::Target as Future>::poll(self.as_deref_mut(), cx)
     }
 }
diff --git a/library/core/src/future/ready.rs b/library/core/src/future/ready.rs
index b0c7fbb1d7a..cc905d288f9 100644
--- a/library/core/src/future/ready.rs
+++ b/library/core/src/future/ready.rs
@@ -20,7 +20,7 @@ impl<T> Future for Ready<T> {
 
     #[inline]
     fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
-        Poll::Ready(self.0.take().expect("Ready polled after completion"))
+        Poll::Ready(self.0.take().expect("`Ready` polled after completion"))
     }
 }
 
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 77d3a35b268..77161e961e7 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -481,6 +481,53 @@ pub trait BuildHasher {
     /// ```
     #[stable(since = "1.7.0", feature = "build_hasher")]
     fn build_hasher(&self) -> Self::Hasher;
+
+    /// Calculates the hash of a single value.
+    ///
+    /// This is intended as a convenience for code which *consumes* hashes, such
+    /// as the implementation of a hash table or in unit tests that check
+    /// whether a custom [`Hash`] implementation behaves as expected.
+    ///
+    /// This must not be used in any code which *creates* hashes, such as in an
+    /// implementation of [`Hash`].  The way to create a combined hash of
+    /// multiple values is to call [`Hash::hash`] multiple times using the same
+    /// [`Hasher`], not to call this method repeatedly and combine the results.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(build_hasher_simple_hash_one)]
+    ///
+    /// use std::cmp::{max, min};
+    /// use std::hash::{BuildHasher, Hash, Hasher};
+    /// struct OrderAmbivalentPair<T: Ord>(T, T);
+    /// impl<T: Ord + Hash> Hash for OrderAmbivalentPair<T> {
+    ///     fn hash<H: Hasher>(&self, hasher: &mut H) {
+    ///         min(&self.0, &self.1).hash(hasher);
+    ///         max(&self.0, &self.1).hash(hasher);
+    ///     }
+    /// }
+    ///
+    /// // Then later, in a `#[test]` for the type...
+    /// let bh = std::collections::hash_map::RandomState::new();
+    /// assert_eq!(
+    ///     bh.hash_one(OrderAmbivalentPair(1, 2)),
+    ///     bh.hash_one(OrderAmbivalentPair(2, 1))
+    /// );
+    /// assert_eq!(
+    ///     bh.hash_one(OrderAmbivalentPair(10, 2)),
+    ///     bh.hash_one(&OrderAmbivalentPair(2, 10))
+    /// );
+    /// ```
+    #[unstable(feature = "build_hasher_simple_hash_one", issue = "86161")]
+    fn hash_one<T: Hash>(&self, x: T) -> u64
+    where
+        Self: Sized,
+    {
+        let mut hasher = self.build_hasher();
+        x.hash(&mut hasher);
+        hasher.finish()
+    }
 }
 
 /// Used to create a default [`BuildHasher`] instance for types that implement
@@ -555,7 +602,8 @@ impl<H> Clone for BuildHasherDefault<H> {
 }
 
 #[stable(since = "1.7.0", feature = "build_hasher")]
-impl<H> Default for BuildHasherDefault<H> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<H> const Default for BuildHasherDefault<H> {
     fn default() -> BuildHasherDefault<H> {
         BuildHasherDefault(marker::PhantomData)
     }
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index a0b65399da2..ba878ff66a0 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -152,23 +152,20 @@ pub fn spin_loop() {
 /// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
 ///
 /// [`std::convert::identity`]: crate::convert::identity
-#[cfg_attr(not(miri), inline)]
-#[cfg_attr(miri, inline(never))]
+#[inline]
 #[unstable(feature = "bench_black_box", issue = "64102")]
-#[cfg_attr(miri, allow(unused_mut))]
+#[cfg_attr(not(bootstrap), allow(unused_mut))]
+#[cfg_attr(bootstrap, allow(deprecated))]
 pub fn black_box<T>(mut dummy: T) -> T {
-    // We need to "use" the argument in some way LLVM can't introspect, and on
-    // targets that support it we can typically leverage inline assembly to do
-    // this. LLVM's interpretation of inline assembly is that it's, well, a black
-    // box. This isn't the greatest implementation since it probably deoptimizes
-    // more than we want, but it's so far good enough.
-
-    #[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri.
+    #[cfg(bootstrap)]
     // SAFETY: the inline assembly is a no-op.
     unsafe {
-        // FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures.
         llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+        dummy
     }
 
-    dummy
+    #[cfg(not(bootstrap))]
+    {
+        crate::intrinsics::black_box(dummy)
+    }
 }
diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs
index 4ea7dfc0735..be12f904640 100644
--- a/library/core/src/internal_macros.rs
+++ b/library/core/src/internal_macros.rs
@@ -77,7 +77,6 @@ macro_rules! forward_ref_op_assign {
 }
 
 /// Create a zero-size type similar to a closure type, but named.
-#[unstable(feature = "std_internals", issue = "none")]
 macro_rules! impl_fn_for_zst {
     ($(
         $( #[$attr: meta] )*
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 0034de9ad1b..272b1e3a1d7 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -25,7 +25,7 @@
 //! across other volatile intrinsics. See the LLVM documentation on
 //! [[volatile]].
 //!
-//! [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses
+//! [volatile]: https://llvm.org/docs/LangRef.html#volatile-memory-accesses
 //!
 //! # Atomics
 //!
@@ -33,7 +33,7 @@
 //! words, with multiple possible memory orderings. They obey the same
 //! semantics as C++11. See the LLVM documentation on [[atomics]].
 //!
-//! [atomics]: http://llvm.org/docs/Atomics.html
+//! [atomics]: https://llvm.org/docs/Atomics.html
 //!
 //! A quick refresher on memory ordering:
 //!
@@ -712,8 +712,19 @@ extern "rust-intrinsic" {
 
     /// Aborts the execution of the process.
     ///
-    /// A more user-friendly and stable version of this operation is
-    /// [`std::process::abort`](../../std/process/fn.abort.html).
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
+    /// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible,
+    /// as its behavior is more user-friendly and more stable.
+    ///
+    /// The current implementation of `intrinsics::abort` is to invoke an invalid instruction,
+    /// on most platforms.
+    /// On Unix, the
+    /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
+    /// `SIGBUS`.  The precise behaviour is not guaranteed and not stable.
     pub fn abort() -> !;
 
     /// Informs the optimizer that this point in the code is not reachable,
@@ -745,6 +756,11 @@ extern "rust-intrinsic" {
     ///
     /// Any use other than with `if` statements will probably not have an effect.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_unstable(feature = "const_likely", issue = "none")]
     pub fn likely(b: bool) -> bool;
@@ -754,6 +770,11 @@ extern "rust-intrinsic" {
     ///
     /// Any use other than with `if` statements will probably not have an effect.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// This intrinsic does not have a stable counterpart.
     #[rustc_const_unstable(feature = "const_likely", issue = "none")]
     pub fn unlikely(b: bool) -> bool;
@@ -765,6 +786,11 @@ extern "rust-intrinsic" {
 
     /// The size of a type in bytes.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// More specifically, this is the offset in bytes between successive
     /// items of the same type, including alignment padding.
     ///
@@ -774,6 +800,11 @@ extern "rust-intrinsic" {
 
     /// The minimum alignment of a type.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is [`core::mem::align_of`].
     #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
     pub fn min_align_of<T>() -> usize;
@@ -796,6 +827,11 @@ extern "rust-intrinsic" {
 
     /// Gets a static string slice containing the name of a type.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is [`core::any::type_name`].
     #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
     pub fn type_name<T: ?Sized>() -> &'static str;
@@ -804,6 +840,11 @@ extern "rust-intrinsic" {
     /// function will return the same value for a type regardless of whichever
     /// crate it is invoked in.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
     #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
     pub fn type_id<T: ?Sized + 'static>() -> u64;
@@ -829,6 +870,11 @@ extern "rust-intrinsic" {
 
     /// Gets a reference to a static `Location` indicating where it was called.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// Consider using [`core::panic::Location::caller`] instead.
     #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
     pub fn caller_location() -> &'static crate::panic::Location<'static>;
@@ -837,6 +883,11 @@ extern "rust-intrinsic" {
     ///
     /// This exists solely for [`mem::forget_unsized`]; normal `forget` uses
     /// `ManuallyDrop` instead.
+    ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
     #[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")]
     pub fn forget<T: ?Sized>(_: T);
 
@@ -860,6 +911,9 @@ extern "rust-intrinsic" {
     /// cause [undefined behavior][ub] with this function. `transmute` should be
     /// the absolute last resort.
     ///
+    /// Transmuting pointers to integers in a `const` context is [undefined behavior][ub].
+    /// Any attempt to use the resulting value for integer operations will abort const-evaluation.
+    ///
     /// The [nomicon](../../nomicon/transmutes.html) has additional
     /// documentation.
     ///
@@ -1077,8 +1131,6 @@ extern "rust-intrinsic" {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    // NOTE: While this makes the intrinsic const stable, we have some custom code in const fn
-    // checks that prevent its use within `const fn`.
     #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
     #[rustc_diagnostic_item = "transmute"]
     pub fn transmute<T, U>(e: T) -> U;
@@ -1090,6 +1142,11 @@ extern "rust-intrinsic" {
     /// If the actual type neither requires drop glue nor implements
     /// `Copy`, then the return value of this function is unspecified.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
     #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
     pub fn needs_drop<T>() -> bool;
@@ -1310,21 +1367,41 @@ extern "rust-intrinsic" {
 
     /// Returns the minimum of two `f32` values.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is
     /// [`f32::min`]
     pub fn minnumf32(x: f32, y: f32) -> f32;
     /// Returns the minimum of two `f64` values.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is
     /// [`f64::min`]
     pub fn minnumf64(x: f64, y: f64) -> f64;
     /// Returns the maximum of two `f32` values.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is
     /// [`f32::max`]
     pub fn maxnumf32(x: f32, y: f32) -> f32;
     /// Returns the maximum of two `f64` values.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is
     /// [`f64::max`]
     pub fn maxnumf64(x: f64, y: f64) -> f64;
@@ -1438,6 +1515,11 @@ extern "rust-intrinsic" {
 
     /// Returns the number of bits set in an integer type `T`
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `count_ones` method. For example,
     /// [`u32::count_ones`]
@@ -1446,6 +1528,11 @@ extern "rust-intrinsic" {
 
     /// Returns the number of leading unset bits (zeroes) in an integer type `T`.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `leading_zeros` method. For example,
     /// [`u32::leading_zeros`]
@@ -1497,6 +1584,11 @@ extern "rust-intrinsic" {
 
     /// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `trailing_zeros` method. For example,
     /// [`u32::trailing_zeros`]
@@ -1548,6 +1640,11 @@ extern "rust-intrinsic" {
 
     /// Reverses the bytes in an integer type `T`.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `swap_bytes` method. For example,
     /// [`u32::swap_bytes`]
@@ -1556,6 +1653,11 @@ extern "rust-intrinsic" {
 
     /// Reverses the bits in an integer type `T`.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `reverse_bits` method. For example,
     /// [`u32::reverse_bits`]
@@ -1564,6 +1666,11 @@ extern "rust-intrinsic" {
 
     /// Performs checked integer addition.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `overflowing_add` method. For example,
     /// [`u32::overflowing_add`]
@@ -1572,6 +1679,11 @@ extern "rust-intrinsic" {
 
     /// Performs checked integer subtraction
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `overflowing_sub` method. For example,
     /// [`u32::overflowing_sub`]
@@ -1580,6 +1692,11 @@ extern "rust-intrinsic" {
 
     /// Performs checked integer multiplication
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `overflowing_mul` method. For example,
     /// [`u32::overflowing_mul`]
@@ -1649,6 +1766,11 @@ extern "rust-intrinsic" {
 
     /// Performs rotate left.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `rotate_left` method. For example,
     /// [`u32::rotate_left`]
@@ -1657,6 +1779,11 @@ extern "rust-intrinsic" {
 
     /// Performs rotate right.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `rotate_right` method. For example,
     /// [`u32::rotate_right`]
@@ -1665,6 +1792,11 @@ extern "rust-intrinsic" {
 
     /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_add` method. For example,
     /// [`u32::wrapping_add`]
@@ -1672,6 +1804,11 @@ extern "rust-intrinsic" {
     pub fn wrapping_add<T: Copy>(a: T, b: T) -> T;
     /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_sub` method. For example,
     /// [`u32::wrapping_sub`]
@@ -1679,6 +1816,11 @@ extern "rust-intrinsic" {
     pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
     /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_mul` method. For example,
     /// [`u32::wrapping_mul`]
@@ -1687,6 +1829,11 @@ extern "rust-intrinsic" {
 
     /// Computes `a + b`, saturating at numeric bounds.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `saturating_add` method. For example,
     /// [`u32::saturating_add`]
@@ -1694,6 +1841,11 @@ extern "rust-intrinsic" {
     pub fn saturating_add<T: Copy>(a: T, b: T) -> T;
     /// Computes `a - b`, saturating at numeric bounds.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `saturating_sub` method. For example,
     /// [`u32::saturating_sub`]
@@ -1703,6 +1855,11 @@ extern "rust-intrinsic" {
     /// Returns the value of the discriminant for the variant in 'v';
     /// if `T` has no discriminant, returns `0`.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The stabilized version of this intrinsic is [`core::mem::discriminant`].
     #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
     pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
@@ -1710,6 +1867,11 @@ extern "rust-intrinsic" {
     /// Returns the number of variants of the type `T` cast to a `usize`;
     /// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
     ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
+    ///
     /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`].
     #[rustc_const_unstable(feature = "variant_count", issue = "73662")]
     pub fn variant_count<T>() -> usize;
@@ -1732,10 +1894,20 @@ extern "rust-intrinsic" {
     pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
 
     /// See documentation of `<*const T>::guaranteed_eq` for details.
+    ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
     pub fn ptr_guaranteed_eq<T>(ptr: *const T, other: *const T) -> bool;
 
     /// See documentation of `<*const T>::guaranteed_ne` for details.
+    ///
+    /// Note that, unlike most intrinsics, this is safe to call;
+    /// it does not require an `unsafe` block.
+    /// Therefore, implementations must not require the user to uphold
+    /// any safety invariants.
     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
     pub fn ptr_guaranteed_ne<T>(ptr: *const T, other: *const T) -> bool;
 
@@ -1743,156 +1915,30 @@ extern "rust-intrinsic" {
     #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
     pub fn const_allocate(size: usize, align: usize) -> *mut u8;
 
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination must *not* overlap.
+    /// Determines whether the raw bytes of the two values are equal.
     ///
-    /// For regions of memory which might overlap, use [`copy`] instead.
+    /// The is particularly handy for arrays, since it allows things like just
+    /// comparing `i96`s instead of forcing `alloca`s for `[6 x i16]`.
     ///
-    /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
-    /// with the argument order swapped.
-    ///
-    /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
+    /// Above some backend-decided threshold this will emit calls to `memcmp`,
+    /// like slice equality does, instead of causing massive code size.
     ///
     /// # Safety
     ///
-    /// Behavior is undefined if any of the following conditions are violated:
-    ///
-    /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * Both `src` and `dst` must be properly aligned.
+    /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized.
+    /// Note that this is a stricter criterion than just the *values* being
+    /// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
     ///
-    /// * The region of memory beginning at `src` with a size of `count *
-    ///   size_of::<T>()` bytes must *not* overlap with the region of memory
-    ///   beginning at `dst` with the same size.
-    ///
-    /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
-    /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
-    /// in the region beginning at `*src` and the region beginning at `*dst` can
-    /// [violate memory safety][read-ownership].
-    ///
-    /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
-    /// `0`, the pointers must be non-null and properly aligned.
-    ///
-    /// [`read`]: crate::ptr::read
-    /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
-    /// [valid]: crate::ptr#safety
-    ///
-    /// # Examples
-    ///
-    /// Manually implement [`Vec::append`]:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
-    /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
-    ///     let src_len = src.len();
-    ///     let dst_len = dst.len();
-    ///
-    ///     // Ensure that `dst` has enough capacity to hold all of `src`.
-    ///     dst.reserve(src_len);
-    ///
-    ///     unsafe {
-    ///         // The call to offset is always safe because `Vec` will never
-    ///         // allocate more than `isize::MAX` bytes.
-    ///         let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
-    ///         let src_ptr = src.as_ptr();
-    ///
-    ///         // Truncate `src` without dropping its contents. We do this first,
-    ///         // to avoid problems in case something further down panics.
-    ///         src.set_len(0);
-    ///
-    ///         // The two regions cannot overlap because mutable references do
-    ///         // not alias, and two different vectors cannot own the same
-    ///         // memory.
-    ///         ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
-    ///
-    ///         // Notify `dst` that it now holds the contents of `src`.
-    ///         dst.set_len(dst_len + src_len);
-    ///     }
-    /// }
-    ///
-    /// let mut a = vec!['r'];
-    /// let mut b = vec!['u', 's', 't'];
-    ///
-    /// append(&mut a, &mut b);
-    ///
-    /// assert_eq!(a, &['r', 'u', 's', 't']);
-    /// assert!(b.is_empty());
-    /// ```
-    ///
-    /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
-    #[doc(alias = "memcpy")]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
-    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    /// (The implementation is allowed to branch on the results of comparisons,
+    /// which is UB if any of their inputs are `undef`.)
+    #[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")]
+    pub fn raw_eq<T>(a: &T, b: &T) -> bool;
 
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination may overlap.
+    /// See documentation of [`std::hint::black_box`] for details.
     ///
-    /// If the source and destination will *never* overlap,
-    /// [`copy_nonoverlapping`] can be used instead.
-    ///
-    /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
-    /// order swapped. Copying takes place as if the bytes were copied from `src`
-    /// to a temporary array and then copied from the array to `dst`.
-    ///
-    /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
-    ///
-    /// # Safety
-    ///
-    /// Behavior is undefined if any of the following conditions are violated:
-    ///
-    /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * Both `src` and `dst` must be properly aligned.
-    ///
-    /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
-    /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
-    /// in the region beginning at `*src` and the region beginning at `*dst` can
-    /// [violate memory safety][read-ownership].
-    ///
-    /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
-    /// `0`, the pointers must be non-null and properly aligned.
-    ///
-    /// [`read`]: crate::ptr::read
-    /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
-    /// [valid]: crate::ptr#safety
-    ///
-    /// # Examples
-    ///
-    /// Efficiently create a Rust vector from an unsafe buffer:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// /// # Safety
-    /// ///
-    /// /// * `ptr` must be correctly aligned for its type and non-zero.
-    /// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
-    /// /// * Those elements must not be used after calling this function unless `T: Copy`.
-    /// # #[allow(dead_code)]
-    /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
-    ///     let mut dst = Vec::with_capacity(elts);
-    ///
-    ///     // SAFETY: Our precondition ensures the source is aligned and valid,
-    ///     // and `Vec::with_capacity` ensures that we have usable space to write them.
-    ///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
-    ///
-    ///     // SAFETY: We created it with this much capacity earlier,
-    ///     // and the previous `copy` has initialized these elements.
-    ///     dst.set_len(elts);
-    ///     dst
-    /// }
-    /// ```
-    #[doc(alias = "memmove")]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
-    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
+    /// [`std::hint::black_box`]: crate::hint::black_box
+    #[cfg(not(bootstrap))]
+    pub fn black_box<T>(dummy: T) -> T;
 }
 
 // Some functions are defined here because they accidentally got made
@@ -1906,6 +1952,192 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
     !ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
 }
 
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination must *not* overlap.
+///
+/// For regions of memory which might overlap, use [`copy`] instead.
+///
+/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
+/// with the argument order swapped.
+///
+/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// * The region of memory beginning at `src` with a size of `count *
+///   size_of::<T>()` bytes must *not* overlap with the region of memory
+///   beginning at `dst` with the same size.
+///
+/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-null and properly aligned.
+///
+/// [`read`]: crate::ptr::read
+/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
+/// [valid]: crate::ptr#safety
+///
+/// # Examples
+///
+/// Manually implement [`Vec::append`]:
+///
+/// ```
+/// use std::ptr;
+///
+/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
+/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
+///     let src_len = src.len();
+///     let dst_len = dst.len();
+///
+///     // Ensure that `dst` has enough capacity to hold all of `src`.
+///     dst.reserve(src_len);
+///
+///     unsafe {
+///         // The call to offset is always safe because `Vec` will never
+///         // allocate more than `isize::MAX` bytes.
+///         let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
+///         let src_ptr = src.as_ptr();
+///
+///         // Truncate `src` without dropping its contents. We do this first,
+///         // to avoid problems in case something further down panics.
+///         src.set_len(0);
+///
+///         // The two regions cannot overlap because mutable references do
+///         // not alias, and two different vectors cannot own the same
+///         // memory.
+///         ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
+///
+///         // Notify `dst` that it now holds the contents of `src`.
+///         dst.set_len(dst_len + src_len);
+///     }
+/// }
+///
+/// let mut a = vec!['r'];
+/// let mut b = vec!['u', 's', 't'];
+///
+/// append(&mut a, &mut b);
+///
+/// assert_eq!(a, &['r', 'u', 's', 't']);
+/// assert!(b.is_empty());
+/// ```
+///
+/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
+#[doc(alias = "memcpy")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+#[inline]
+pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
+    // FIXME: Perform these checks only at run time
+    /*if cfg!(debug_assertions)
+        && !(is_aligned_and_not_null(src)
+            && is_aligned_and_not_null(dst)
+            && is_nonoverlapping(src, dst, count))
+    {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }*/
+
+    // SAFETY: the safety contract for `copy_nonoverlapping` must be
+    // upheld by the caller.
+    unsafe { copy_nonoverlapping(src, dst, count) }
+}
+
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination may overlap.
+///
+/// If the source and destination will *never* overlap,
+/// [`copy_nonoverlapping`] can be used instead.
+///
+/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
+/// order swapped. Copying takes place as if the bytes were copied from `src`
+/// to a temporary array and then copied from the array to `dst`.
+///
+/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-null and properly aligned.
+///
+/// [`read`]: crate::ptr::read
+/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
+/// [valid]: crate::ptr#safety
+///
+/// # Examples
+///
+/// Efficiently create a Rust vector from an unsafe buffer:
+///
+/// ```
+/// use std::ptr;
+///
+/// /// # Safety
+/// ///
+/// /// * `ptr` must be correctly aligned for its type and non-zero.
+/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
+/// /// * Those elements must not be used after calling this function unless `T: Copy`.
+/// # #[allow(dead_code)]
+/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
+///     let mut dst = Vec::with_capacity(elts);
+///
+///     // SAFETY: Our precondition ensures the source is aligned and valid,
+///     // and `Vec::with_capacity` ensures that we have usable space to write them.
+///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
+///
+///     // SAFETY: We created it with this much capacity earlier,
+///     // and the previous `copy` has initialized these elements.
+///     dst.set_len(elts);
+///     dst
+/// }
+/// ```
+#[doc(alias = "memmove")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+#[inline]
+pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        fn copy<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
+    // FIXME: Perform these checks only at run time
+    /*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }*/
+
+    // SAFETY: the safety contract for `copy` must be upheld by the caller.
+    unsafe { copy(src, dst, count) }
+}
+
 /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
 /// `val`.
 ///
diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs
index 7efc155175c..71a5a4ea831 100644
--- a/library/core/src/iter/adapters/cloned.rs
+++ b/library/core/src/iter/adapters/cloned.rs
@@ -1,4 +1,6 @@
-use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
+use crate::iter::adapters::{
+    zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
+};
 use crate::iter::{FusedIterator, TrustedLen};
 use crate::ops::Try;
 
@@ -58,9 +60,10 @@ where
         self.it.map(T::clone).fold(init, f)
     }
 
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         // SAFETY: the caller must uphold the contract for
         // `Iterator::__iterator_get_unchecked`.
@@ -120,9 +123,13 @@ where
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I> TrustedRandomAccess for Cloned<I>
+unsafe impl<I> TrustedRandomAccess for Cloned<I> where I: TrustedRandomAccess {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I> TrustedRandomAccessNoCoerce for Cloned<I>
 where
-    I: TrustedRandomAccess,
+    I: TrustedRandomAccessNoCoerce,
 {
     const MAY_HAVE_SIDE_EFFECT: bool = true;
 }
diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs
index def24089275..3d3c8da678b 100644
--- a/library/core/src/iter/adapters/copied.rs
+++ b/library/core/src/iter/adapters/copied.rs
@@ -1,4 +1,6 @@
-use crate::iter::adapters::{zip::try_get_unchecked, TrustedRandomAccess};
+use crate::iter::adapters::{
+    zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
+};
 use crate::iter::{FusedIterator, TrustedLen};
 use crate::ops::Try;
 
@@ -74,9 +76,10 @@ where
         self.it.count()
     }
 
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         // SAFETY: the caller must uphold the contract for
         // `Iterator::__iterator_get_unchecked`.
@@ -136,9 +139,13 @@ where
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I> TrustedRandomAccess for Copied<I>
+unsafe impl<I> TrustedRandomAccess for Copied<I> where I: TrustedRandomAccess {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I> TrustedRandomAccessNoCoerce for Copied<I>
 where
-    I: TrustedRandomAccess,
+    I: TrustedRandomAccessNoCoerce,
 {
     const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
 }
diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs
index 91722a4b62a..3478a0cd408 100644
--- a/library/core/src/iter/adapters/enumerate.rs
+++ b/library/core/src/iter/adapters/enumerate.rs
@@ -1,4 +1,6 @@
-use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
+use crate::iter::adapters::{
+    zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
+};
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
 use crate::ops::Try;
 
@@ -111,9 +113,10 @@ where
     }
 
     #[rustc_inherit_overflow_checks]
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         // SAFETY: the caller must uphold the contract for
         // `Iterator::__iterator_get_unchecked`.
@@ -206,9 +209,13 @@ where
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I> TrustedRandomAccess for Enumerate<I>
+unsafe impl<I> TrustedRandomAccess for Enumerate<I> where I: TrustedRandomAccess {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I> TrustedRandomAccessNoCoerce for Enumerate<I>
 where
-    I: TrustedRandomAccess,
+    I: TrustedRandomAccessNoCoerce,
 {
     const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
 }
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 3315d346596..48880a4d91a 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -1,5 +1,5 @@
 use crate::fmt;
-use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
+use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
 use crate::ops::Try;
 
 /// An iterator that maps each element to an iterator, and yields the elements
@@ -114,6 +114,30 @@ where
 {
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T, I, F, const N: usize> TrustedLen for FlatMap<I, [T; N], F>
+where
+    I: TrustedLen,
+    F: FnMut(I::Item) -> [T; N],
+{
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a [T; N], F>
+where
+    I: TrustedLen,
+    F: FnMut(I::Item) -> &'a [T; N],
+{
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a mut [T; N], F>
+where
+    I: TrustedLen,
+    F: FnMut(I::Item) -> &'a mut [T; N],
+{
+}
+
 /// An iterator that flattens one level of nesting in an iterator of things
 /// that can be turned into iterators.
 ///
@@ -230,6 +254,14 @@ where
 {
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I> TrustedLen for Flatten<I>
+where
+    I: TrustedLen,
+    <I as Iterator>::Item: TrustedConstSize,
+{
+}
+
 /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
 /// this type.
 #[derive(Clone, Debug)]
@@ -282,6 +314,17 @@ where
         let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
         let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
         let lo = flo.saturating_add(blo);
+
+        if let Some(fixed_size) = <<I as Iterator>::Item as ConstSizeIntoIterator>::size() {
+            let (lower, upper) = self.iter.size_hint();
+
+            let lower = lower.saturating_mul(fixed_size).saturating_add(lo);
+            let upper =
+                try { fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?)? };
+
+            return (lower, upper);
+        }
+
         match (self.iter.size_hint(), fhi, bhi) {
             ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
             _ => (lo, None),
@@ -444,3 +487,52 @@ where
         init
     }
 }
+
+trait ConstSizeIntoIterator: IntoIterator {
+    // FIXME(#31844): convert to an associated const once specialization supports that
+    fn size() -> Option<usize>;
+}
+
+impl<T> ConstSizeIntoIterator for T
+where
+    T: IntoIterator,
+{
+    #[inline]
+    default fn size() -> Option<usize> {
+        None
+    }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for [T; N] {
+    #[inline]
+    fn size() -> Option<usize> {
+        Some(N)
+    }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for &[T; N] {
+    #[inline]
+    fn size() -> Option<usize> {
+        Some(N)
+    }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
+    #[inline]
+    fn size() -> Option<usize> {
+        Some(N)
+    }
+}
+
+#[doc(hidden)]
+#[unstable(feature = "std_internals", issue = "none")]
+// FIXME(#20400): Instead of this helper trait there should be multiple impl TrustedLen for Flatten<>
+//   blocks with different bounds on Iterator::Item but the compiler erroneously considers them overlapping
+pub unsafe trait TrustedConstSize: IntoIterator {}
+
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for [T; N] {}
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for &'_ [T; N] {}
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for &'_ mut [T; N] {}
diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs
index aff48b1b220..fbf752c6f20 100644
--- a/library/core/src/iter/adapters/fuse.rs
+++ b/library/core/src/iter/adapters/fuse.rs
@@ -1,7 +1,8 @@
 use crate::intrinsics;
-use crate::iter::adapters::{zip::try_get_unchecked, InPlaceIterable, SourceIter};
+use crate::iter::adapters::zip::try_get_unchecked;
 use crate::iter::{
     DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess,
+    TrustedRandomAccessNoCoerce,
 };
 use crate::ops::Try;
 
@@ -14,7 +15,9 @@ use crate::ops::Try;
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Fuse<I> {
-    // NOTE: for `I: FusedIterator`, this is always assumed `Some`!
+    // NOTE: for `I: FusedIterator`, we never bother setting `None`, but
+    // we still have to be prepared for that state due to variance.
+    // See rust-lang/rust#85863
     iter: Option<I>,
 }
 impl<I> Fuse<I> {
@@ -42,19 +45,19 @@ macro_rules! fuse {
     };
 }
 
-// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
-// Implementing this as a directly-expanded macro helps codegen performance.
-macro_rules! unchecked {
-    ($self:ident) => {
-        match $self {
-            Fuse { iter: Some(iter) } => iter,
-            // SAFETY: the specialized iterator never sets `None`
-            Fuse { iter: None } => unsafe { intrinsics::unreachable() },
+/// Specialized macro that doesn't check if the expression is `None`.
+/// (We trust that a `FusedIterator` will fuse itself.)
+macro_rules! spec {
+    ($self:ident . iter . $($call:tt)+) => {
+        match $self.iter {
+            Some(ref mut iter) => iter.$($call)+,
+            None => None,
         }
     };
 }
 
-// Any implementation here is made internal to avoid exposing default fns outside this trait
+// Any specialized implementation here is made internal
+// to avoid exposing default fns outside this trait.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> Iterator for Fuse<I>
 where
@@ -74,17 +77,26 @@ where
 
     #[inline]
     fn last(self) -> Option<Self::Item> {
-        FuseImpl::last(self)
+        match self.iter {
+            Some(iter) => iter.last(),
+            None => None,
+        }
     }
 
     #[inline]
     fn count(self) -> usize {
-        FuseImpl::count(self)
+        match self.iter {
+            Some(iter) => iter.count(),
+            None => 0,
+        }
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        FuseImpl::size_hint(self)
+        match self.iter {
+            Some(ref iter) => iter.size_hint(),
+            None => (0, Some(0)),
+        }
     }
 
     #[inline]
@@ -98,11 +110,14 @@ where
     }
 
     #[inline]
-    fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        FuseImpl::fold(self, acc, fold)
+        if let Some(iter) = self.iter {
+            acc = iter.fold(acc, fold);
+        }
+        acc
     }
 
     #[inline]
@@ -114,9 +129,10 @@ where
     }
 
     #[inline]
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         match self.iter {
             // SAFETY: the caller must uphold the contract for
@@ -154,11 +170,14 @@ where
     }
 
     #[inline]
-    fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
-        FuseImpl::rfold(self, acc, fold)
+        if let Some(iter) = self.iter {
+            acc = iter.rfold(acc, fold);
+        }
+        acc
     }
 
     #[inline]
@@ -176,11 +195,17 @@ where
     I: ExactSizeIterator,
 {
     fn len(&self) -> usize {
-        FuseImpl::len(self)
+        match self.iter {
+            Some(ref iter) => iter.len(),
+            None => 0,
+        }
     }
 
     fn is_empty(&self) -> bool {
-        FuseImpl::is_empty(self)
+        match self.iter {
+            Some(ref iter) => iter.is_empty(),
+            None => true,
+        }
     }
 }
 
@@ -197,14 +222,21 @@ unsafe impl<I> TrustedLen for Fuse<I> where I: TrustedLen {}
 //
 // This is safe to implement as `Fuse` is just forwarding these to the wrapped iterator `I`, which
 // preserves these properties.
-unsafe impl<I> TrustedRandomAccess for Fuse<I>
+unsafe impl<I> TrustedRandomAccess for Fuse<I> where I: TrustedRandomAccess {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I> TrustedRandomAccessNoCoerce for Fuse<I>
 where
-    I: TrustedRandomAccess,
+    I: TrustedRandomAccessNoCoerce,
 {
     const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
 }
 
-// Fuse specialization trait
+/// Fuse specialization trait
+///
+/// We only need to worry about `&mut self` methods, which
+/// may exhaust the iterator without consuming it.
 #[doc(hidden)]
 trait FuseImpl<I> {
     type Item;
@@ -212,17 +244,11 @@ trait FuseImpl<I> {
     // Functions specific to any normal Iterators
     fn next(&mut self) -> Option<Self::Item>;
     fn nth(&mut self, n: usize) -> Option<Self::Item>;
-    fn last(self) -> Option<Self::Item>;
-    fn count(self) -> usize;
-    fn size_hint(&self) -> (usize, Option<usize>);
     fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>;
-    fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc;
     fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool;
@@ -240,25 +266,13 @@ trait FuseImpl<I> {
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
         I: DoubleEndedIterator;
-    fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-        I: DoubleEndedIterator;
     fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
         I: DoubleEndedIterator;
-
-    // Functions specific to ExactSizeIterator
-    fn len(&self) -> usize
-    where
-        I: ExactSizeIterator;
-    fn is_empty(&self) -> bool
-    where
-        I: ExactSizeIterator;
 }
 
-// General Fuse impl
+/// General `Fuse` impl which sets `iter = None` when exhausted.
 #[doc(hidden)]
 impl<I> FuseImpl<I> for Fuse<I>
 where
@@ -277,30 +291,6 @@ where
     }
 
     #[inline]
-    default fn last(self) -> Option<I::Item> {
-        match self.iter {
-            Some(iter) => iter.last(),
-            None => None,
-        }
-    }
-
-    #[inline]
-    default fn count(self) -> usize {
-        match self.iter {
-            Some(iter) => iter.count(),
-            None => 0,
-        }
-    }
-
-    #[inline]
-    default fn size_hint(&self) -> (usize, Option<usize>) {
-        match self.iter {
-            Some(ref iter) => iter.size_hint(),
-            None => (0, Some(0)),
-        }
-    }
-
-    #[inline]
     default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
@@ -315,17 +305,6 @@ where
     }
 
     #[inline]
-    default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        if let Some(iter) = self.iter {
-            acc = iter.fold(acc, fold);
-        }
-        acc
-    }
-
-    #[inline]
     default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
@@ -365,18 +344,6 @@ where
     }
 
     #[inline]
-    default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-        I: DoubleEndedIterator,
-    {
-        if let Some(iter) = self.iter {
-            acc = iter.rfold(acc, fold);
-        }
-        acc
-    }
-
-    #[inline]
     default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
@@ -384,30 +351,10 @@ where
     {
         fuse!(self.iter.rfind(predicate))
     }
-
-    #[inline]
-    default fn len(&self) -> usize
-    where
-        I: ExactSizeIterator,
-    {
-        match self.iter {
-            Some(ref iter) => iter.len(),
-            None => 0,
-        }
-    }
-
-    #[inline]
-    default fn is_empty(&self) -> bool
-    where
-        I: ExactSizeIterator,
-    {
-        match self.iter {
-            Some(ref iter) => iter.is_empty(),
-            None => true,
-        }
-    }
 }
 
+/// Specialized `Fuse` impl which doesn't bother clearing `iter` when exhausted.
+/// However, we must still be prepared for the possibility that it was already cleared!
 #[doc(hidden)]
 impl<I> FuseImpl<I> for Fuse<I>
 where
@@ -415,45 +362,25 @@ where
 {
     #[inline]
     fn next(&mut self) -> Option<<I as Iterator>::Item> {
-        unchecked!(self).next()
+        spec!(self.iter.next())
     }
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<I::Item> {
-        unchecked!(self).nth(n)
-    }
-
-    #[inline]
-    fn last(self) -> Option<I::Item> {
-        unchecked!(self).last()
+        spec!(self.iter.nth(n))
     }
 
     #[inline]
-    fn count(self) -> usize {
-        unchecked!(self).count()
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        unchecked!(self).size_hint()
-    }
-
-    #[inline]
-    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+    fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
     {
-        unchecked!(self).try_fold(init, fold)
-    }
-
-    #[inline]
-    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-    {
-        unchecked!(self).fold(init, fold)
+        if let Some(ref mut iter) = self.iter {
+            acc = iter.try_fold(acc, fold)?;
+        }
+        try { acc }
     }
 
     #[inline]
@@ -461,7 +388,7 @@ where
     where
         P: FnMut(&Self::Item) -> bool,
     {
-        unchecked!(self).find(predicate)
+        spec!(self.iter.find(predicate))
     }
 
     #[inline]
@@ -469,7 +396,7 @@ where
     where
         I: DoubleEndedIterator,
     {
-        unchecked!(self).next_back()
+        spec!(self.iter.next_back())
     }
 
     #[inline]
@@ -477,27 +404,21 @@ where
     where
         I: DoubleEndedIterator,
     {
-        unchecked!(self).nth_back(n)
+        spec!(self.iter.nth_back(n))
     }
 
     #[inline]
-    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
+    fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
     where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Output = Acc>,
         I: DoubleEndedIterator,
     {
-        unchecked!(self).try_rfold(init, fold)
-    }
-
-    #[inline]
-    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
-    where
-        Fold: FnMut(Acc, Self::Item) -> Acc,
-        I: DoubleEndedIterator,
-    {
-        unchecked!(self).rfold(init, fold)
+        if let Some(ref mut iter) = self.iter {
+            acc = iter.try_rfold(acc, fold)?;
+        }
+        try { acc }
     }
 
     #[inline]
@@ -506,43 +427,6 @@ where
         P: FnMut(&Self::Item) -> bool,
         I: DoubleEndedIterator,
     {
-        unchecked!(self).rfind(predicate)
-    }
-
-    #[inline]
-    fn len(&self) -> usize
-    where
-        I: ExactSizeIterator,
-    {
-        unchecked!(self).len()
-    }
-
-    #[inline]
-    fn is_empty(&self) -> bool
-    where
-        I: ExactSizeIterator,
-    {
-        unchecked!(self).is_empty()
+        spec!(self.iter.rfind(predicate))
     }
 }
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
-where
-    I: SourceIter<Source = S>,
-{
-    type Source = S;
-
-    #[inline]
-    unsafe fn as_inner(&mut self) -> &mut S {
-        match self.iter {
-            // SAFETY: unsafe function forwarding to unsafe function with the same requirements
-            Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
-            // SAFETY: the specialized iterator never sets `None`
-            None => unsafe { intrinsics::unreachable() },
-        }
-    }
-}
-
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}
diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs
index 0bf9f4b0327..763e253e75a 100644
--- a/library/core/src/iter/adapters/map.rs
+++ b/library/core/src/iter/adapters/map.rs
@@ -1,5 +1,7 @@
 use crate::fmt;
-use crate::iter::adapters::{zip::try_get_unchecked, SourceIter, TrustedRandomAccess};
+use crate::iter::adapters::{
+    zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
+};
 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
 use crate::ops::Try;
 
@@ -122,9 +124,10 @@ where
         self.iter.fold(init, map_fold(self.f, g))
     }
 
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         // SAFETY: the caller must uphold the contract for
         // `Iterator::__iterator_get_unchecked`.
@@ -186,9 +189,13 @@ where
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I, F> TrustedRandomAccess for Map<I, F>
+unsafe impl<I, F> TrustedRandomAccess for Map<I, F> where I: TrustedRandomAccess {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<I, F> TrustedRandomAccessNoCoerce for Map<I, F>
 where
-    I: TrustedRandomAccess,
+    I: TrustedRandomAccessNoCoerce,
 {
     const MAY_HAVE_SIDE_EFFECT: bool = true;
 }
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index 9fdd4fca04c..056ccca1d01 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -51,10 +51,13 @@ pub use self::map_while::MapWhile;
 #[unstable(feature = "trusted_random_access", issue = "none")]
 pub use self::zip::TrustedRandomAccess;
 
+#[unstable(feature = "trusted_random_access", issue = "none")]
+pub use self::zip::TrustedRandomAccessNoCoerce;
+
 #[unstable(feature = "iter_zip", issue = "83574")]
 pub use self::zip::zip;
 
-/// This trait provides transitive access to source-stage in an interator-adapter pipeline
+/// This trait provides transitive access to source-stage in an iterator-adapter pipeline
 /// under the conditions that
 /// * the iterator source `S` itself implements `SourceIter<Source = S>`
 /// * there is a delegating implementation of this trait for each adapter in the pipeline between
diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs
index 69bd2996efe..91fa1a9ad35 100644
--- a/library/core/src/iter/adapters/peekable.rs
+++ b/library/core/src/iter/adapters/peekable.rs
@@ -130,7 +130,6 @@ where
     }
 
     #[inline]
-    #[cfg(not(bootstrap))]
     fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
     where
         Self: Sized,
@@ -151,28 +150,6 @@ where
     }
 
     #[inline]
-    #[cfg(bootstrap)]
-    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
-    where
-        Self: Sized,
-        F: FnMut(B, Self::Item) -> R,
-        R: Try<Output = B>,
-    {
-        let _use_the_import: ControlFlow<()>;
-        match self.peeked.take() {
-            Some(None) => try { init },
-            Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
-                Ok(acc) => f(acc, v),
-                Err(e) => {
-                    self.peeked = Some(Some(v));
-                    R::from_error(e)
-                }
-            },
-            None => self.iter.try_rfold(init, f),
-        }
-    }
-
-    #[inline]
     fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs
index 92f82ae2325..beda8c32c6b 100644
--- a/library/core/src/iter/adapters/take.rs
+++ b/library/core/src/iter/adapters/take.rs
@@ -1,8 +1,5 @@
 use crate::cmp;
-use crate::iter::{
-    adapters::zip::try_get_unchecked, adapters::SourceIter, FusedIterator, InPlaceIterable,
-    TrustedLen, TrustedRandomAccess,
-};
+use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
 use crate::ops::{ControlFlow, Try};
 
 /// An iterator that only iterates over the first `n` iterations of `iter`.
@@ -114,15 +111,6 @@ where
 
         self.try_fold(init, ok(fold)).unwrap()
     }
-
-    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <I as Iterator>::Item
-    where
-        Self: TrustedRandomAccess,
-    {
-        // SAFETY: the caller must uphold the contract for
-        // `Iterator::__iterator_get_unchecked`.
-        unsafe { try_get_unchecked(&mut self.iter, idx) }
-    }
 }
 
 #[unstable(issue = "none", feature = "inplace_iteration")]
@@ -219,12 +207,3 @@ impl<I> FusedIterator for Take<I> where I: FusedIterator {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
 unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
-
-#[doc(hidden)]
-#[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<I> TrustedRandomAccess for Take<I>
-where
-    I: TrustedRandomAccess,
-{
-    const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
-}
diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs
index c95324c80ba..c7e69e922c1 100644
--- a/library/core/src/iter/adapters/zip.rs
+++ b/library/core/src/iter/adapters/zip.rs
@@ -88,9 +88,10 @@ where
     }
 
     #[inline]
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         // SAFETY: `ZipImpl::__iterator_get_unchecked` has same safety
         // requirements as `Iterator::__iterator_get_unchecked`.
@@ -125,7 +126,66 @@ trait ZipImpl<A, B> {
     // This has the same safety requirements as `Iterator::__iterator_get_unchecked`
     unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
     where
-        Self: Iterator + TrustedRandomAccess;
+        Self: Iterator + TrustedRandomAccessNoCoerce;
+}
+
+// Work around limitations of specialization, requiring `default` impls to be repeated
+// in intermediary impls.
+macro_rules! zip_impl_general_defaults {
+    () => {
+        default fn new(a: A, b: B) -> Self {
+            Zip {
+                a,
+                b,
+                index: 0, // unused
+                len: 0,   // unused
+                a_len: 0, // unused
+            }
+        }
+
+        #[inline]
+        default fn next(&mut self) -> Option<(A::Item, B::Item)> {
+            let x = self.a.next()?;
+            let y = self.b.next()?;
+            Some((x, y))
+        }
+
+        #[inline]
+        default fn nth(&mut self, n: usize) -> Option<Self::Item> {
+            self.super_nth(n)
+        }
+
+        #[inline]
+        default fn next_back(&mut self) -> Option<(A::Item, B::Item)>
+        where
+            A: DoubleEndedIterator + ExactSizeIterator,
+            B: DoubleEndedIterator + ExactSizeIterator,
+        {
+            // The function body below only uses `self.a/b.len()` and `self.a/b.next_back()`
+            // and doesn’t call `next_back` too often, so this implementation is safe in
+            // the `TrustedRandomAccessNoCoerce` specialization
+
+            let a_sz = self.a.len();
+            let b_sz = self.b.len();
+            if a_sz != b_sz {
+                // Adjust a, b to equal length
+                if a_sz > b_sz {
+                    for _ in 0..a_sz - b_sz {
+                        self.a.next_back();
+                    }
+                } else {
+                    for _ in 0..b_sz - a_sz {
+                        self.b.next_back();
+                    }
+                }
+            }
+            match (self.a.next_back(), self.b.next_back()) {
+                (Some(x), Some(y)) => Some((x, y)),
+                (None, None) => None,
+                _ => unreachable!(),
+            }
+        }
+    };
 }
 
 // General Zip impl
@@ -136,54 +196,8 @@ where
     B: Iterator,
 {
     type Item = (A::Item, B::Item);
-    default fn new(a: A, b: B) -> Self {
-        Zip {
-            a,
-            b,
-            index: 0, // unused
-            len: 0,   // unused
-            a_len: 0, // unused
-        }
-    }
 
-    #[inline]
-    default fn next(&mut self) -> Option<(A::Item, B::Item)> {
-        let x = self.a.next()?;
-        let y = self.b.next()?;
-        Some((x, y))
-    }
-
-    #[inline]
-    default fn nth(&mut self, n: usize) -> Option<Self::Item> {
-        self.super_nth(n)
-    }
-
-    #[inline]
-    default fn next_back(&mut self) -> Option<(A::Item, B::Item)>
-    where
-        A: DoubleEndedIterator + ExactSizeIterator,
-        B: DoubleEndedIterator + ExactSizeIterator,
-    {
-        let a_sz = self.a.len();
-        let b_sz = self.b.len();
-        if a_sz != b_sz {
-            // Adjust a, b to equal length
-            if a_sz > b_sz {
-                for _ in 0..a_sz - b_sz {
-                    self.a.next_back();
-                }
-            } else {
-                for _ in 0..b_sz - a_sz {
-                    self.b.next_back();
-                }
-            }
-        }
-        match (self.a.next_back(), self.b.next_back()) {
-            (Some(x), Some(y)) => Some((x, y)),
-            (None, None) => None,
-            _ => unreachable!(),
-        }
-    }
+    zip_impl_general_defaults! {}
 
     #[inline]
     default fn size_hint(&self) -> (usize, Option<usize>) {
@@ -204,7 +218,7 @@ where
 
     default unsafe fn get_unchecked(&mut self, _idx: usize) -> <Self as Iterator>::Item
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         unreachable!("Always specialized");
     }
@@ -213,6 +227,29 @@ where
 #[doc(hidden)]
 impl<A, B> ZipImpl<A, B> for Zip<A, B>
 where
+    A: TrustedRandomAccessNoCoerce + Iterator,
+    B: TrustedRandomAccessNoCoerce + Iterator,
+{
+    zip_impl_general_defaults! {}
+
+    #[inline]
+    default fn size_hint(&self) -> (usize, Option<usize>) {
+        let size = cmp::min(self.a.size(), self.b.size());
+        (size, Some(size))
+    }
+
+    #[inline]
+    unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item {
+        let idx = self.index + idx;
+        // SAFETY: the caller must uphold the contract for
+        // `Iterator::__iterator_get_unchecked`.
+        unsafe { (self.a.__iterator_get_unchecked(idx), self.b.__iterator_get_unchecked(idx)) }
+    }
+}
+
+#[doc(hidden)]
+impl<A, B> ZipImpl<A, B> for Zip<A, B>
+where
     A: TrustedRandomAccess + Iterator,
     B: TrustedRandomAccess + Iterator,
 {
@@ -226,6 +263,8 @@ where
     fn next(&mut self) -> Option<(A::Item, B::Item)> {
         if self.index < self.len {
             let i = self.index;
+            // since get_unchecked executes code which can panic we increment the counters beforehand
+            // so that the same index won't be accessed twice, as required by TrustedRandomAccess
             self.index += 1;
             // SAFETY: `i` is smaller than `self.len`, thus smaller than `self.a.len()` and `self.b.len()`
             unsafe {
@@ -233,6 +272,7 @@ where
             }
         } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a_len {
             let i = self.index;
+            // as above, increment before executing code that may panic
             self.index += 1;
             self.len += 1;
             // match the base implementation's potential side effects
@@ -258,6 +298,8 @@ where
         let end = self.index + delta;
         while self.index < end {
             let i = self.index;
+            // since get_unchecked executes code which can panic we increment the counters beforehand
+            // so that the same index won't be accessed twice, as required by TrustedRandomAccess
             self.index += 1;
             if A::MAY_HAVE_SIDE_EFFECT {
                 // SAFETY: the usage of `cmp::min` to calculate `delta`
@@ -294,9 +336,12 @@ where
                 let sz_a = self.a.size();
                 if A::MAY_HAVE_SIDE_EFFECT && sz_a > self.len {
                     for _ in 0..sz_a - self.len {
+                        // since next_back() may panic we increment the counters beforehand
+                        // to keep Zip's state in sync with the underlying iterator source
+                        self.a_len -= 1;
                         self.a.next_back();
                     }
-                    self.a_len = self.len;
+                    debug_assert_eq!(self.a_len, self.len);
                 }
                 let sz_b = self.b.size();
                 if B::MAY_HAVE_SIDE_EFFECT && sz_b > self.len {
@@ -307,6 +352,8 @@ where
             }
         }
         if self.index < self.len {
+            // since get_unchecked executes code which can panic we increment the counters beforehand
+            // so that the same index won't be accessed twice, as required by TrustedRandomAccess
             self.len -= 1;
             self.a_len -= 1;
             let i = self.len;
@@ -319,14 +366,6 @@ where
             None
         }
     }
-
-    #[inline]
-    unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item {
-        let idx = self.index + idx;
-        // SAFETY: the caller must uphold the contract for
-        // `Iterator::__iterator_get_unchecked`.
-        unsafe { (self.a.__iterator_get_unchecked(idx), self.b.__iterator_get_unchecked(idx)) }
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -344,6 +383,15 @@ where
     A: TrustedRandomAccess,
     B: TrustedRandomAccess,
 {
+}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<A, B> TrustedRandomAccessNoCoerce for Zip<A, B>
+where
+    A: TrustedRandomAccessNoCoerce,
+    B: TrustedRandomAccessNoCoerce,
+{
     const MAY_HAVE_SIDE_EFFECT: bool = A::MAY_HAVE_SIDE_EFFECT || B::MAY_HAVE_SIDE_EFFECT;
 }
 
@@ -406,7 +454,9 @@ impl<A: Debug, B: Debug> ZipFmt<A, B> for Zip<A, B> {
     }
 }
 
-impl<A: Debug + TrustedRandomAccess, B: Debug + TrustedRandomAccess> ZipFmt<A, B> for Zip<A, B> {
+impl<A: Debug + TrustedRandomAccessNoCoerce, B: Debug + TrustedRandomAccessNoCoerce> ZipFmt<A, B>
+    for Zip<A, B>
+{
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // It's *not safe* to call fmt on the contained iterators, since once
         // we start iterating they're in strange, potentially unsafe, states.
@@ -420,34 +470,70 @@ impl<A: Debug + TrustedRandomAccess, B: Debug + TrustedRandomAccess> ZipFmt<A, B
 ///
 /// The iterator's `size_hint` must be exact and cheap to call.
 ///
-/// `size` may not be overridden.
+/// `TrustedRandomAccessNoCoerce::size` may not be overridden.
+///
+/// All subtypes and all supertypes of `Self` must also implement `TrustedRandomAccess`.
+/// In particular, this means that types with non-invariant parameters usually can not have
+/// an impl for `TrustedRandomAccess` that depends on any trait bounds on such parameters, except
+/// for bounds that come from the respective struct/enum definition itself, or bounds involving
+/// traits that themselves come with a guarantee similar to this one.
+///
+/// If `Self: ExactSizeIterator` then `self.len()` must always produce results consistent
+/// with `self.size()`.
 ///
-/// `<Self as Iterator>::__iterator_get_unchecked` must be safe to call
-/// provided the following conditions are met.
+/// If `Self: Iterator`, then `<Self as Iterator>::__iterator_get_unchecked(&mut self, idx)`
+/// must be safe to call provided the following conditions are met.
 ///
 /// 1. `0 <= idx` and `idx < self.size()`.
-/// 2. If `self: !Clone`, then `get_unchecked` is never called with the same
+/// 2. If `Self: !Clone`, then `self.__iterator_get_unchecked(idx)` is never called with the same
 ///    index on `self` more than once.
-/// 3. After `self.get_unchecked(idx)` has been called then `next_back` will
-///    only be called at most `self.size() - idx - 1` times.
-/// 4. After `get_unchecked` is called, then only the following methods will be
-///    called on `self`:
-///     * `std::clone::Clone::clone()`
-///     * `std::iter::Iterator::size_hint()`
-///     * `std::iter::DoubleEndedIterator::next_back()`
-///     * `std::iter::Iterator::__iterator_get_unchecked()`
-///     * `std::iter::TrustedRandomAccess::size()`
+/// 3. After `self.__iterator_get_unchecked(idx)` has been called, then `self.next_back()` will
+///    only be called at most `self.size() - idx - 1` times. If `Self: Clone` and `self` is cloned,
+///    then this number is calculated for `self` and its clone individually,
+///    but `self.next_back()` calls that happened before the cloning count for both `self` and the clone.
+/// 4. After `self.__iterator_get_unchecked(idx)` has been called, then only the following methods
+///    will be called on `self` or on any new clones of `self`:
+///     * `std::clone::Clone::clone`
+///     * `std::iter::Iterator::size_hint`
+///     * `std::iter::DoubleEndedIterator::next_back`
+///     * `std::iter::ExactSizeIterator::len`
+///     * `std::iter::Iterator::__iterator_get_unchecked`
+///     * `std::iter::TrustedRandomAccessNoCoerce::size`
+/// 5. If `T` is a subtype of `Self`, then `self` is allowed to be coerced
+///    to `T`. If `self` is coerced to `T` after `self.__iterator_get_unchecked(idx)` has already
+///    been called, then no methods except for the ones listed under 4. are allowed to be called
+///    on the resulting value of type `T`, either. Multiple such coercion steps are allowed.
+///    Regarding 2. and 3., the number of times `__iterator_get_unchecked(idx)` or `next_back()` is
+///    called on `self` and the resulting value of type `T` (and on further coercion results with
+///    sub-subtypes) are added together and their sums must not exceed the specified bounds.
 ///
 /// Further, given that these conditions are met, it must guarantee that:
 ///
 /// * It does not change the value returned from `size_hint`
 /// * It must be safe to call the methods listed above on `self` after calling
-///   `get_unchecked`, assuming that the required traits are implemented.
-/// * It must also be safe to drop `self` after calling `get_unchecked`.
+///   `self.__iterator_get_unchecked(idx)`, assuming that the required traits are implemented.
+/// * It must also be safe to drop `self` after calling `self.__iterator_get_unchecked(idx)`.
+/// * If `T` is a subtype of `Self`, then it must be safe to coerce `self` to `T`.
+//
+// FIXME: Clarify interaction with SourceIter/InPlaceIterable. Calling `SouceIter::as_inner`
+// after `__iterator_get_unchecked` is supposed to be allowed.
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+#[rustc_specialization_trait]
+pub unsafe trait TrustedRandomAccess: TrustedRandomAccessNoCoerce {}
+
+/// Like [`TrustedRandomAccess`] but without any of the requirements / guarantees around
+/// coercions to subtypes after `__iterator_get_unchecked` (they aren’t allowed here!), and
+/// without the requirement that subtypes / supertypes implement `TrustedRandomAccessNoCoerce`.
+///
+/// This trait was created in PR #85874 to fix soundness issue #85873 without performance regressions.
+/// It is subject to change as we might want to build a more generally useful (for performance
+/// optimizations) and more sophisticated trait or trait hierarchy that replaces or extends
+/// [`TrustedRandomAccess`] and `TrustedRandomAccessNoCoerce`.
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
 #[rustc_specialization_trait]
-pub unsafe trait TrustedRandomAccess: Sized {
+pub unsafe trait TrustedRandomAccessNoCoerce: Sized {
     // Convenience method.
     fn size(&self) -> usize
     where
@@ -488,7 +574,7 @@ unsafe impl<I: Iterator> SpecTrustedRandomAccess for I {
     }
 }
 
-unsafe impl<I: Iterator + TrustedRandomAccess> SpecTrustedRandomAccess for I {
+unsafe impl<I: Iterator + TrustedRandomAccessNoCoerce> SpecTrustedRandomAccess for I {
     unsafe fn try_get_unchecked(&mut self, index: usize) -> Self::Item {
         // SAFETY: the caller must uphold the contract for
         // `Iterator::__iterator_get_unchecked`.
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index bfb27da505e..7fb80f954ff 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -336,7 +336,7 @@
 //! This will print the numbers `0` through `4`, each on their own line.
 //!
 //! Bear in mind that methods on infinite iterators, even those for which a
-//! result can be determined mathematically in finite time, may not terminate.
+//! result can be determined mathematically in finite time, might not terminate.
 //! Specifically, methods such as [`min`], which in the general case require
 //! traversing every element in the iterator, are likely not to return
 //! successfully for any infinite iterators.
@@ -407,6 +407,8 @@ pub use self::adapters::SourceIter;
 pub use self::adapters::StepBy;
 #[unstable(feature = "trusted_random_access", issue = "none")]
 pub use self::adapters::TrustedRandomAccess;
+#[unstable(feature = "trusted_random_access", issue = "none")]
+pub use self::adapters::TrustedRandomAccessNoCoerce;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::adapters::{
     Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan,
diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs
index de5d77e96ee..f7ed811e447 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -3,7 +3,9 @@ use crate::convert::TryFrom;
 use crate::mem;
 use crate::ops::{self, Try};
 
-use super::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedStep};
+use super::{
+    FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep,
+};
 
 // Safety: All invariants are upheld.
 macro_rules! unsafe_impl_trusted_step {
@@ -30,7 +32,7 @@ pub trait Step: Clone + PartialOrd + Sized {
     /// For any `a`, `b`, and `n`:
     ///
     /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward_checked(&a, n) == Some(b)`
-    /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&a, n) == Some(a)`
+    /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&b, n) == Some(a)`
     /// * `steps_between(&a, &b) == Some(n)` only if `a <= b`
     ///   * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b`
     ///   * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`;
@@ -275,7 +277,7 @@ macro_rules! step_integer_impls {
                         //
                         // Casting to isize extends the width but preserves the sign.
                         // Use wrapping_sub in isize space and cast to usize to compute
-                        // the difference that may not fit inside the range of isize.
+                        // the difference that might not fit inside the range of isize.
                         Some((*end as isize).wrapping_sub(*start as isize) as usize)
                     } else {
                         None
@@ -495,7 +497,11 @@ macro_rules! unsafe_range_trusted_random_access_impl {
     ($($t:ty)*) => ($(
         #[doc(hidden)]
         #[unstable(feature = "trusted_random_access", issue = "none")]
-        unsafe impl TrustedRandomAccess for ops::Range<$t> {
+        unsafe impl TrustedRandomAccess for ops::Range<$t> {}
+
+        #[doc(hidden)]
+        #[unstable(feature = "trusted_random_access", issue = "none")]
+        unsafe impl TrustedRandomAccessNoCoerce for ops::Range<$t> {
             const MAY_HAVE_SIDE_EFFECT: bool = false;
         }
     )*)
@@ -667,9 +673,10 @@ impl<A: Step> Iterator for ops::Range<A> {
     }
 
     #[inline]
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         // SAFETY: The TrustedRandomAccess contract requires that callers only  pass an index
         // that is in bounds.
diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs
index 919c564f287..a7d4646f5c5 100644
--- a/library/core/src/iter/sources/empty.rs
+++ b/library/core/src/iter/sources/empty.rs
@@ -85,7 +85,8 @@ impl<T> Clone for Empty<T> {
 // not #[derive] because that adds a Default bound on T,
 // which isn't necessary.
 #[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> Default for Empty<T> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> const Default for Empty<T> {
     fn default() -> Empty<T> {
         Empty(marker::PhantomData)
     }
diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs
index a9478041c69..733142ed011 100644
--- a/library/core/src/iter/sources/repeat.rs
+++ b/library/core/src/iter/sources/repeat.rs
@@ -51,6 +51,7 @@ use crate::iter::{FusedIterator, TrustedLen};
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "iter_repeat")]
 pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
     Repeat { element: elt }
 }
diff --git a/library/core/src/iter/traits/accum.rs b/library/core/src/iter/traits/accum.rs
index 0a4210a78e3..c2e837df5ff 100644
--- a/library/core/src/iter/traits/accum.rs
+++ b/library/core/src/iter/traits/accum.rs
@@ -3,12 +3,11 @@ use crate::num::Wrapping;
 
 /// Trait to represent types that can be created by summing up an iterator.
 ///
-/// This trait is used to implement the [`sum()`] method on iterators. Types which
-/// implement the trait can be generated by the [`sum()`] method. Like
-/// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::sum()`].
+/// This trait is used to implement [`Iterator::sum()`]. Types which implement
+/// this trait can be generated by using the [`sum()`] method on an iterator.
+/// Like [`FromIterator`], this trait should rarely be called directly.
 ///
-/// [`sum()`]: Sum::sum
+/// [`sum()`]: Iterator::sum
 /// [`FromIterator`]: iter::FromIterator
 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
 pub trait Sum<A = Self>: Sized {
@@ -21,12 +20,11 @@ pub trait Sum<A = Self>: Sized {
 /// Trait to represent types that can be created by multiplying elements of an
 /// iterator.
 ///
-/// This trait is used to implement the [`product()`] method on iterators. Types
-/// which implement the trait can be generated by the [`product()`] method. Like
-/// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::product()`].
+/// This trait is used to implement [`Iterator::product()`]. Types which implement
+/// this trait can be generated by using the [`product()`] method on an iterator.
+/// Like [`FromIterator`], this trait should rarely be called directly.
 ///
-/// [`product()`]: Product::product
+/// [`product()`]: Iterator::product
 /// [`FromIterator`]: iter::FromIterator
 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
 pub trait Product<A = Self>: Sized {
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index e2a407509b1..aa91346851f 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -89,6 +89,7 @@
                over elements of type `{A}`",
     label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
 )]
+#[rustc_diagnostic_item = "FromIterator"]
 pub trait FromIterator<A>: Sized {
     /// Creates a value from an iterator.
     ///
@@ -238,6 +239,7 @@ impl<I: Iterator> IntoIterator for I {
     type Item = I::Item;
     type IntoIter = I;
 
+    #[inline]
     fn into_iter(self) -> I {
         self
     }
@@ -358,3 +360,61 @@ impl Extend<()> for () {
     }
     fn extend_one(&mut self, _item: ()) {}
 }
+
+#[stable(feature = "extend_for_tuple", since = "1.56.0")]
+impl<A, B, ExtendA, ExtendB> Extend<(A, B)> for (ExtendA, ExtendB)
+where
+    ExtendA: Extend<A>,
+    ExtendB: Extend<B>,
+{
+    /// Allows to `extend` a tuple of collections that also implement `Extend`.
+    ///
+    /// See also: [`Iterator::unzip`]
+    ///
+    /// # Examples
+    /// ```
+    /// let mut tuple = (vec![0], vec![1]);
+    /// tuple.extend(vec![(2, 3), (4, 5), (6, 7)]);
+    /// assert_eq!(tuple.0, vec![0, 2, 4, 6]);
+    /// assert_eq!(tuple.1, vec![1, 3, 5, 7]);
+    ///
+    /// // also allows for arbitrarily nested tuples
+    /// let mut nested_tuple = (vec![(1, -1)], vec![(2, -2)]);
+    /// nested_tuple.extend(vec![((3, -3), (4, -4)), ((5, -5), (6, -6))]);
+    ///
+    /// assert_eq!(nested_tuple.0, vec![(1, -1), (3, -3), (5, -5)]);
+    /// assert_eq!(nested_tuple.1, vec![(2, -2), (4, -4), (6, -6)]);
+    /// ```
+    fn extend<T: IntoIterator<Item = (A, B)>>(&mut self, into_iter: T) {
+        let (a, b) = self;
+        let iter = into_iter.into_iter();
+
+        fn extend<'a, A, B>(
+            a: &'a mut impl Extend<A>,
+            b: &'a mut impl Extend<B>,
+        ) -> impl FnMut((), (A, B)) + 'a {
+            move |(), (t, u)| {
+                a.extend_one(t);
+                b.extend_one(u);
+            }
+        }
+
+        let (lower_bound, _) = iter.size_hint();
+        if lower_bound > 0 {
+            a.extend_reserve(lower_bound);
+            b.extend_reserve(lower_bound);
+        }
+
+        iter.fold((), extend(a, b));
+    }
+
+    fn extend_one(&mut self, item: (A, B)) {
+        self.0.extend_one(item.0);
+        self.1.extend_one(item.1);
+    }
+
+    fn extend_reserve(&mut self, additional: usize) {
+        self.0.extend_reserve(additional);
+        self.1.extend_reserve(additional);
+    }
+}
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index c302502b3b7..9a9cf200770 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -36,6 +36,7 @@ use crate::ops::{ControlFlow, Try};
 /// assert_eq!(None, iter.next_back());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "DoubleEndedIterator")]
 pub trait DoubleEndedIterator: Iterator {
     /// Removes and returns an element from the end of the iterator.
     ///
@@ -248,6 +249,11 @@ pub trait DoubleEndedIterator: Iterator {
     /// Folding is useful whenever you have a collection of something, and want
     /// to produce a single value from it.
     ///
+    /// Note: `rfold()` combines elements in a *right-associative* fashion. For associative
+    /// operators like `+`, the order the elements are combined in is not important, but for non-associative
+    /// operators like `-` the order will affect the final result.
+    /// For a *left-associative* version of `rfold()`, see [`Iterator::fold()`].
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -262,7 +268,8 @@ pub trait DoubleEndedIterator: Iterator {
     /// assert_eq!(sum, 6);
     /// ```
     ///
-    /// This example builds a string, starting with an initial value
+    /// This example demonstrates the right-associative nature of `rfold()`:
+    /// it builds a string, starting with an initial value
     /// and continuing with each element from the back until the front:
     ///
     /// ```
@@ -276,6 +283,7 @@ pub trait DoubleEndedIterator: Iterator {
     ///
     /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
     /// ```
+    #[doc(alias = "foldr")]
     #[inline]
     #[stable(feature = "iter_rfold", since = "1.27.0")]
     fn rfold<B, F>(mut self, init: B, mut f: F) -> B
diff --git a/library/core/src/iter/traits/exact_size.rs b/library/core/src/iter/traits/exact_size.rs
index 167db3359f2..a476799b70d 100644
--- a/library/core/src/iter/traits/exact_size.rs
+++ b/library/core/src/iter/traits/exact_size.rs
@@ -97,7 +97,6 @@ pub trait ExactSizeIterator: Iterator {
     ///
     /// assert_eq!(5, five.len());
     /// ```
-    #[doc(alias = "length")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn len(&self) -> usize {
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 96b924f6e2a..524d8f857e2 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -1,11 +1,7 @@
-// ignore-tidy-filelength
-// This file almost exclusively consists of the definition of `Iterator`. We
-// can't split that into multiple files.
-
 use crate::cmp::{self, Ordering};
 use crate::ops::{ControlFlow, Try};
 
-use super::super::TrustedRandomAccess;
+use super::super::TrustedRandomAccessNoCoerce;
 use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
 use super::super::{FlatMap, Flatten};
 use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip};
@@ -138,7 +134,7 @@ pub trait Iterator {
     /// A more complex example:
     ///
     /// ```
-    /// // The even numbers from zero to ten.
+    /// // The even numbers in the range of zero to nine.
     /// let iter = (0..10).filter(|x| x % 2 == 0);
     ///
     /// // We might iterate from zero to ten times. Knowing that it's five
@@ -333,21 +329,22 @@ pub trait Iterator {
     /// regardless of the step given.
     ///
     /// Note 2: The time at which ignored elements are pulled is not fixed.
-    /// `StepBy` behaves like the sequence `next(), nth(step-1), nth(step-1), …`,
-    /// but is also free to behave like the sequence
-    /// `advance_n_and_return_first(step), advance_n_and_return_first(step), …`
+    /// `StepBy` behaves like the sequence `self.next()`, `self.nth(step-1)`,
+    /// `self.nth(step-1)`, …, but is also free to behave like the sequence
+    /// `advance_n_and_return_first(&mut self, step)`,
+    /// `advance_n_and_return_first(&mut self, step)`, …
     /// Which way is used may change for some iterators for performance reasons.
     /// The second way will advance the iterator earlier and may consume more items.
     ///
     /// `advance_n_and_return_first` is the equivalent of:
     /// ```
-    /// fn advance_n_and_return_first<I>(iter: &mut I, total_step: usize) -> Option<I::Item>
+    /// fn advance_n_and_return_first<I>(iter: &mut I, n: usize) -> Option<I::Item>
     /// where
     ///     I: Iterator,
     /// {
     ///     let next = iter.next();
-    ///     if total_step > 1 {
-    ///         iter.nth(total_step-2);
+    ///     if n > 1 {
+    ///         iter.nth(n - 2);
     ///     }
     ///     next
     /// }
@@ -693,7 +690,7 @@ pub trait Iterator {
     /// more idiomatic to use a `for` loop, but `for_each` may be more legible
     /// when processing items at the end of longer iterator chains. In some
     /// cases `for_each` may also be faster than a loop, because it will use
-    /// internal iteration on adaptors like `Chain`.
+    /// internal iteration on adapters like `Chain`.
     ///
     /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
     ///
@@ -1292,7 +1289,7 @@ pub trait Iterator {
         Take::new(self, n)
     }
 
-    /// An iterator adaptor similar to [`fold`] that holds internal state and
+    /// An iterator adapter similar to [`fold`] that holds internal state and
     /// produces a new iterator.
     ///
     /// [`fold`]: Iterator::fold
@@ -1603,7 +1600,7 @@ pub trait Iterator {
 
     /// Borrows an iterator, rather than consuming it.
     ///
-    /// This is useful to allow applying iterator adaptors while still
+    /// This is useful to allow applying iterator adapters while still
     /// retaining ownership of the original iterator.
     ///
     /// # Examples
@@ -1959,6 +1956,31 @@ pub trait Iterator {
     /// assert_eq!(it.len(), 2);
     /// assert_eq!(it.next(), Some(&40));
     /// ```
+    ///
+    /// While you cannot `break` from a closure, the [`crate::ops::ControlFlow`]
+    /// type allows a similar idea:
+    ///
+    /// ```
+    /// use std::ops::ControlFlow;
+    ///
+    /// let triangular = (1..30).try_fold(0_i8, |prev, x| {
+    ///     if let Some(next) = prev.checked_add(x) {
+    ///         ControlFlow::Continue(next)
+    ///     } else {
+    ///         ControlFlow::Break(prev)
+    ///     }
+    /// });
+    /// assert_eq!(triangular, ControlFlow::Break(120));
+    ///
+    /// let triangular = (1..30).try_fold(0_u64, |prev, x| {
+    ///     if let Some(next) = prev.checked_add(x) {
+    ///         ControlFlow::Continue(next)
+    ///     } else {
+    ///         ControlFlow::Break(prev)
+    ///     }
+    /// });
+    /// assert_eq!(triangular, ControlFlow::Continue(435));
+    /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
@@ -2001,6 +2023,22 @@ pub trait Iterator {
     /// // It short-circuited, so the remaining items are still in the iterator:
     /// assert_eq!(it.next(), Some("stale_bread.json"));
     /// ```
+    ///
+    /// The [`crate::ops::ControlFlow`] type can be used with this method for the
+    /// situations in which you'd use `break` and `continue` in a normal loop:
+    ///
+    /// ```
+    /// use std::ops::ControlFlow;
+    ///
+    /// let r = (2..100).try_for_each(|x| {
+    ///     if 323 % x == 0 {
+    ///         return ControlFlow::Break(x)
+    ///     }
+    ///
+    ///     ControlFlow::Continue(())
+    /// });
+    /// assert_eq!(r, ControlFlow::Break(17));
+    /// ```
     #[inline]
     #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     fn try_for_each<F, R>(&mut self, f: F) -> R
@@ -2036,12 +2074,17 @@ pub trait Iterator {
     /// to produce a single value from it.
     ///
     /// Note: `fold()`, and similar methods that traverse the entire iterator,
-    /// may not terminate for infinite iterators, even on traits for which a
+    /// might not terminate for infinite iterators, even on traits for which a
     /// result is determinable in finite time.
     ///
     /// Note: [`reduce()`] can be used to use the first element as the initial
     /// value, if the accumulator type and item type is the same.
     ///
+    /// Note: `fold()` combines elements in a *left-associative* fashion. For associative
+    /// operators like `+`, the order the elements are combined in is not important, but for non-associative
+    /// operators like `-` the order will affect the final result.
+    /// For a *right-associative* version of `fold()`, see [`DoubleEndedIterator::rfold()`].
+    ///
     /// # Note to Implementors
     ///
     /// Several of the other (forward) methods have default implementations in
@@ -2075,6 +2118,21 @@ pub trait Iterator {
     ///
     /// And so, our final result, `6`.
     ///
+    /// This example demonstrates the left-associative nature of `fold()`:
+    /// it builds a string, starting with an initial value
+    /// and continuing with each element from the front until the back:
+    ///
+    /// ```
+    /// let numbers = [1, 2, 3, 4, 5];
+    ///
+    /// let zero = "0".to_string();
+    ///
+    /// let result = numbers.iter().fold(zero, |acc, &x| {
+    ///     format!("({} + {})", acc, x)
+    /// });
+    ///
+    /// assert_eq!(result, "(((((0 + 1) + 2) + 3) + 4) + 5)");
+    /// ```
     /// It's common for people who haven't used iterators a lot to
     /// use a `for` loop with a list of things to build up a result. Those
     /// can be turned into `fold()`s:
@@ -2099,7 +2157,7 @@ pub trait Iterator {
     /// ```
     ///
     /// [`reduce()`]: Iterator::reduce
-    #[doc(alias = "inject")]
+    #[doc(alias = "inject", alias = "foldl")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn fold<B, F>(mut self, init: B, mut f: F) -> B
@@ -2193,7 +2251,6 @@ pub trait Iterator {
     /// // we can still use `iter`, as there are more elements.
     /// assert_eq!(iter.next(), Some(&3));
     /// ```
-    #[doc(alias = "every")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn all<F>(&mut self, f: F) -> bool
@@ -2378,7 +2435,6 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "try_find", reason = "new API", issue = "63178")]
-    #[cfg(not(bootstrap))]
     fn try_find<F, R, E>(&mut self, f: F) -> Result<Option<Self::Item>, E>
     where
         Self: Sized,
@@ -2405,32 +2461,6 @@ pub trait Iterator {
         self.try_fold((), check(f)).break_value().transpose()
     }
 
-    /// We're bootstrapping.
-    #[inline]
-    #[unstable(feature = "try_find", reason = "new API", issue = "63178")]
-    #[cfg(bootstrap)]
-    fn try_find<F, R>(&mut self, f: F) -> Result<Option<Self::Item>, R::Error>
-    where
-        Self: Sized,
-        F: FnMut(&Self::Item) -> R,
-        R: Try<Output = bool>,
-    {
-        #[inline]
-        fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<Result<T, R::Error>>
-        where
-            F: FnMut(&T) -> R,
-            R: Try<Output = bool>,
-        {
-            move |(), x| match f(&x).into_result() {
-                Ok(false) => ControlFlow::CONTINUE,
-                Ok(true) => ControlFlow::Break(Ok(x)),
-                Err(x) => ControlFlow::Break(Err(x)),
-            }
-        }
-
-        self.try_fold((), check(f)).break_value().transpose()
-    }
-
     /// Searches for an element in an iterator, returning its index.
     ///
     /// `position()` takes a closure that returns `true` or `false`. It applies
@@ -2811,6 +2841,14 @@ pub trait Iterator {
     ///
     /// assert_eq!(left, [1, 3]);
     /// assert_eq!(right, [2, 4]);
+    ///
+    /// // you can also unzip multiple nested tuples at once
+    /// let a = [(1, (2, 3)), (4, (5, 6))];
+    ///
+    /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip();
+    /// assert_eq!(x, [1, 4]);
+    /// assert_eq!(y, [2, 5]);
+    /// assert_eq!(z, [3, 6]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
@@ -2819,28 +2857,9 @@ pub trait Iterator {
         FromB: Default + Extend<B>,
         Self: Sized + Iterator<Item = (A, B)>,
     {
-        fn extend<'a, A, B>(
-            ts: &'a mut impl Extend<A>,
-            us: &'a mut impl Extend<B>,
-        ) -> impl FnMut((), (A, B)) + 'a {
-            move |(), (t, u)| {
-                ts.extend_one(t);
-                us.extend_one(u);
-            }
-        }
-
-        let mut ts: FromA = Default::default();
-        let mut us: FromB = Default::default();
-
-        let (lower_bound, _) = self.size_hint();
-        if lower_bound > 0 {
-            ts.extend_reserve(lower_bound);
-            us.extend_reserve(lower_bound);
-        }
-
-        self.fold((), extend(&mut ts, &mut us));
-
-        (ts, us)
+        let mut unzipped: (FromA, FromB) = Default::default();
+        unzipped.extend(self);
+        unzipped
     }
 
     /// Creates an iterator which copies all of its elements.
@@ -3422,7 +3441,7 @@ pub trait Iterator {
         self.map(f).is_sorted()
     }
 
-    /// See [TrustedRandomAccess]
+    /// See [TrustedRandomAccess][super::super::TrustedRandomAccess]
     // The unusual name is to avoid name collisions in method resolution
     // see #76479.
     #[inline]
@@ -3430,7 +3449,7 @@ pub trait Iterator {
     #[unstable(feature = "trusted_random_access", issue = "none")]
     unsafe fn __iterator_get_unchecked(&mut self, _idx: usize) -> Self::Item
     where
-        Self: TrustedRandomAccess,
+        Self: TrustedRandomAccessNoCoerce,
     {
         unreachable!("Always specialized");
     }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index d4e4c5b0d3e..4ab7cc24a0d 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -49,6 +49,10 @@
 //
 // This cfg won't affect doc tests.
 #![cfg(not(test))]
+// To run libcore tests without x.py without ending up with two copies of libcore, Miri needs to be
+// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
+// rustc itself never sets the feature, so this line has no affect there.
+#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
 #![stable(feature = "core", since = "1.6.0")]
 #![doc(
     html_playground_url = "https://play.rust-lang.org/",
@@ -57,61 +61,76 @@
     test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
 )]
 #![no_core]
+//
+// Lints:
+#![deny(rust_2021_incompatible_or_patterns)]
+#![deny(unsafe_op_in_unsafe_fn)]
 #![warn(deprecated_in_future)]
-#![warn(missing_docs)]
 #![warn(missing_debug_implementations)]
+#![warn(missing_docs)]
 #![allow(explicit_outlives_requirements)]
-#![feature(rustc_allow_const_fn_unstable)]
-#![feature(allow_internal_unstable)]
-#![feature(arbitrary_self_types)]
-#![feature(asm)]
-#![feature(cfg_target_has_atomic)]
-#![feature(const_heap)]
+//
+// Library features for const fns:
+#![feature(const_align_of_val)]
 #![feature(const_alloc_layout)]
+#![feature(const_arguments_as_str)]
 #![feature(const_assert_type)]
-#![feature(const_discriminant)]
+#![feature(const_caller_location)]
 #![feature(const_cell_into_inner)]
-#![feature(const_intrinsic_copy)]
-#![feature(const_intrinsic_forget)]
-#![feature(const_float_classify)]
+#![feature(const_discriminant)]
 #![feature(const_float_bits_conv)]
-#![feature(const_int_unchecked_arith)]
+#![feature(const_float_classify)]
+#![feature(const_heap)]
 #![feature(const_inherent_unchecked_arith)]
-#![feature(const_mut_refs)]
-#![feature(const_refs_to_cell)]
-#![feature(const_panic)]
-#![feature(const_pin)]
-#![feature(const_fn_union)]
-#![feature(const_impl_trait)]
-#![feature(const_fn_floating_point_arithmetic)]
-#![feature(const_fn_fn_ptr_basics)]
-#![feature(const_fn_trait_bound)]
-#![cfg_attr(bootstrap, feature(const_fn))]
+#![feature(const_int_unchecked_arith)]
+#![feature(const_intrinsic_copy)]
+#![feature(const_intrinsic_forget)]
+#![feature(const_likely)]
+#![feature(const_maybe_uninit_as_ptr)]
+#![feature(const_maybe_uninit_assume_init)]
 #![feature(const_option)]
-#![feature(const_precise_live_drops)]
+#![feature(const_pin)]
 #![feature(const_ptr_offset)]
 #![feature(const_ptr_offset_from)]
 #![feature(const_ptr_read)]
 #![feature(const_ptr_write)]
 #![feature(const_raw_ptr_comparison)]
-#![feature(const_raw_ptr_deref)]
+#![feature(const_size_of_val)]
 #![feature(const_slice_from_raw_parts)]
 #![feature(const_slice_ptr_len)]
-#![feature(const_size_of_val)]
 #![feature(const_swap)]
-#![feature(const_align_of_val)]
+#![feature(const_trait_impl)]
 #![feature(const_type_id)]
 #![feature(const_type_name)]
-#![feature(const_likely)]
 #![feature(const_unreachable_unchecked)]
-#![feature(const_maybe_uninit_assume_init)]
-#![feature(const_maybe_uninit_as_ptr)]
-#![feature(custom_inner_attributes)]
+#![feature(const_default_impls)]
+#![feature(duration_consts_2)]
+#![feature(ptr_metadata)]
+#![feature(slice_ptr_get)]
+#![feature(variant_count)]
+//
+// Language features:
+#![feature(abi_unadjusted)]
+#![feature(allow_internal_unstable)]
+#![feature(asm)]
+#![feature(associated_type_bounds)]
+#![feature(auto_traits)]
+#![feature(cfg_target_has_atomic)]
+#![feature(const_fn_floating_point_arithmetic)]
+#![feature(const_fn_fn_ptr_basics)]
+#![feature(const_fn_trait_bound)]
+#![cfg_attr(bootstrap, feature(const_fn_transmute))]
+#![cfg_attr(bootstrap, feature(const_fn_union))]
+#![feature(const_impl_trait)]
+#![feature(const_mut_refs)]
+#![feature(const_panic)]
+#![feature(const_precise_live_drops)]
+#![feature(const_raw_ptr_deref)]
+#![feature(const_refs_to_cell)]
 #![feature(decl_macro)]
 #![feature(doc_cfg)]
 #![feature(doc_notable_trait)]
-#![feature(duration_consts_2)]
-#![cfg_attr(bootstrap, feature(extended_key_value_attributes))]
+#![feature(exhaustive_patterns)]
 #![feature(extern_types)]
 #![feature(fundamental)]
 #![feature(intra_doc_pointers)]
@@ -119,54 +138,40 @@
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
 #![feature(llvm_asm)]
+#![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(never_type)]
-#![feature(nll)]
-#![feature(exhaustive_patterns)]
 #![feature(no_core)]
-#![feature(auto_traits)]
+#![feature(no_coverage)] // rust-lang/rust#84605
+#![feature(no_niche)] // rust-lang/rust#68303
+#![feature(platform_intrinsics)]
 #![feature(prelude_import)]
-#![feature(ptr_metadata)]
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd)]
+#![feature(rustc_allow_const_fn_unstable)]
 #![feature(rustc_attrs)]
 #![feature(simd_ffi)]
-#![feature(min_specialization)]
 #![feature(staged_api)]
-#![feature(std_internals)]
 #![feature(stmt_expr_attributes)]
-#![feature(str_split_as_str)]
-#![feature(str_split_inclusive_as_str)]
-#![feature(char_indices_offset)]
 #![feature(trait_alias)]
 #![feature(transparent_unions)]
 #![feature(try_blocks)]
 #![feature(unboxed_closures)]
 #![feature(unsized_fn_params)]
-#![feature(unwind_attributes)]
-#![feature(variant_count)]
-#![feature(tbm_target_feature)]
-#![feature(sse4a_target_feature)]
-#![feature(arm_target_feature)]
-#![feature(powerpc_target_feature)]
-#![feature(mips_target_feature)]
+//
+// Target features:
 #![feature(aarch64_target_feature)]
-#![feature(wasm_target_feature)]
+#![feature(adx_target_feature)]
+#![feature(arm_target_feature)]
 #![feature(avx512_target_feature)]
 #![feature(cmpxchg16b_target_feature)]
-#![feature(rtm_target_feature)]
 #![feature(f16c_target_feature)]
 #![feature(hexagon_target_feature)]
-#![feature(const_fn_transmute)]
-#![feature(abi_unadjusted)]
-#![feature(adx_target_feature)]
-#![feature(associated_type_bounds)]
-#![feature(const_caller_location)]
-#![feature(slice_ptr_get)]
-#![feature(no_niche)] // rust-lang/rust#68303
-#![feature(no_coverage)] // rust-lang/rust#84605
-#![feature(int_error_matching)]
-#![deny(unsafe_op_in_unsafe_fn)]
-#![deny(or_patterns_back_compat)]
+#![feature(mips_target_feature)]
+#![feature(powerpc_target_feature)]
+#![feature(rtm_target_feature)]
+#![feature(sse4a_target_feature)]
+#![feature(tbm_target_feature)]
+#![feature(wasm_target_feature)]
 
 // allow using `core::` in intra-doc links
 #[allow(unused_extern_crates)]
@@ -180,6 +185,16 @@ use prelude::v1::*;
 #[macro_use]
 mod macros;
 
+// We don't export this through #[macro_export] for now, to avoid breakage.
+// See https://github.com/rust-lang/rust/issues/82913
+#[cfg(not(test))]
+#[unstable(feature = "assert_matches", issue = "82775")]
+/// Unstable module containing the unstable `assert_matches` macro.
+pub mod assert_matches {
+    #[unstable(feature = "assert_matches", issue = "82775")]
+    pub use crate::macros::{assert_matches, debug_assert_matches};
+}
+
 #[macro_use]
 mod internal_macros;
 
@@ -257,7 +272,6 @@ pub mod option;
 pub mod panic;
 pub mod panicking;
 pub mod pin;
-pub mod raw;
 pub mod result;
 #[unstable(feature = "async_stream", issue = "79024")]
 pub mod stream;
@@ -308,5 +322,35 @@ pub mod primitive;
 #[unstable(feature = "stdsimd", issue = "48556")]
 mod core_arch;
 
+#[doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")]
 #[stable(feature = "simd_arch", since = "1.27.0")]
-pub use core_arch::arch;
+pub mod arch {
+    #[stable(feature = "simd_arch", since = "1.27.0")]
+    pub use crate::core_arch::arch::*;
+
+    /// Inline assembly.
+    ///
+    /// Read the [unstable book] for the usage.
+    ///
+    /// [unstable book]: ../../unstable-book/library-features/asm.html
+    #[unstable(
+        feature = "asm",
+        issue = "72016",
+        reason = "inline assembly is not stable enough for use and is subject to change"
+    )]
+    #[rustc_builtin_macro]
+    pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
+        /* compiler built-in */
+    }
+
+    /// Module-level inline assembly.
+    #[unstable(
+        feature = "global_asm",
+        issue = "35119",
+        reason = "`global_asm!` is not stable enough for use and is subject to change"
+    )]
+    #[rustc_builtin_macro]
+    pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
+        /* compiler built-in */
+    }
+}
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 7eb65483b99..476f37699ee 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1,6 +1,6 @@
 #[doc = include_str!("panic.md")]
 #[macro_export]
-#[rustc_builtin_macro = "core_panic"]
+#[rustc_builtin_macro(core_panic)]
 #[allow_internal_unstable(edition_panic)]
 #[stable(feature = "core", since = "1.6.0")]
 #[rustc_diagnostic_item = "core_panic_macro"]
@@ -126,6 +126,8 @@ macro_rules! assert_ne {
 /// ```
 /// #![feature(assert_matches)]
 ///
+/// use std::assert_matches::assert_matches;
+///
 /// let a = 1u32.checked_add(2);
 /// let b = 1u32.checked_sub(2);
 /// assert_matches!(a, Some(_));
@@ -134,11 +136,11 @@ macro_rules! assert_ne {
 /// let c = Ok("abc".to_string());
 /// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
 /// ```
-#[macro_export]
 #[unstable(feature = "assert_matches", issue = "82775")]
 #[allow_internal_unstable(core_panic)]
-macro_rules! assert_matches {
-    ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
+#[rustc_macro_transparency = "semitransparent"]
+pub macro assert_matches {
+    ($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
         match $left {
             $( $pattern )|+ $( if $guard )? => {}
             ref left_val => {
@@ -149,8 +151,8 @@ macro_rules! assert_matches {
                 );
             }
         }
-    });
-    ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
+    }),
+    ($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
         match $left {
             $( $pattern )|+ $( if $guard )? => {}
             ref left_val => {
@@ -161,7 +163,7 @@ macro_rules! assert_matches {
                 );
             }
         }
-    });
+    }),
 }
 
 /// Asserts that a boolean expression is `true` at runtime.
@@ -283,6 +285,8 @@ macro_rules! debug_assert_ne {
 /// ```
 /// #![feature(assert_matches)]
 ///
+/// use std::assert_matches::debug_assert_matches;
+///
 /// let a = 1u32.checked_add(2);
 /// let b = 1u32.checked_sub(2);
 /// debug_assert_matches!(a, Some(_));
@@ -294,8 +298,9 @@ macro_rules! debug_assert_ne {
 #[macro_export]
 #[unstable(feature = "assert_matches", issue = "82775")]
 #[allow_internal_unstable(assert_matches)]
-macro_rules! debug_assert_matches {
-    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_matches!($($arg)*); })
+#[rustc_macro_transparency = "semitransparent"]
+pub macro debug_assert_matches($($arg:tt)*) {
+    if $crate::cfg!(debug_assertions) { $crate::assert_matches::assert_matches!($($arg)*); }
 }
 
 /// Returns whether the given expression matches any of the given patterns.
@@ -315,7 +320,7 @@ macro_rules! debug_assert_matches {
 #[macro_export]
 #[stable(feature = "matches_macro", since = "1.42.0")]
 macro_rules! matches {
-    ($expression:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
+    ($expression:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
         match $expression {
             $( $pattern )|+ $( if $guard )? => true,
             _ => false
@@ -831,6 +836,31 @@ pub(crate) mod builtin {
         ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
     }
 
+    /// Same as `format_args`, but can be used in some const contexts.
+    ///
+    /// This macro is used by the panic macros for the `const_panic` feature.
+    ///
+    /// This macro will be removed once `format_args` is allowed in const contexts.
+    #[cfg(not(bootstrap))]
+    #[unstable(feature = "const_format_args", issue = "none")]
+    #[allow_internal_unstable(fmt_internals, const_fmt_arguments_new)]
+    #[rustc_builtin_macro]
+    #[macro_export]
+    macro_rules! const_format_args {
+        ($fmt:expr) => {{ /* compiler built-in */ }};
+        ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
+    }
+
+    /// Same as `format_args`, but can be used in some const contexts.
+    #[cfg(bootstrap)]
+    #[unstable(feature = "const_format_args", issue = "none")]
+    #[macro_export]
+    macro_rules! const_format_args {
+        ($($t:tt)*) => {
+            $crate::format_args!($($t)*)
+        }
+    }
+
     /// Same as `format_args`, but adds a newline in the end.
     #[unstable(
         feature = "format_args_nl",
@@ -839,6 +869,7 @@ pub(crate) mod builtin {
                   language use and is subject to change"
     )]
     #[allow_internal_unstable(fmt_internals)]
+    #[doc(hidden)]
     #[rustc_builtin_macro]
     #[macro_export]
     macro_rules! format_args_nl {
@@ -1306,27 +1337,6 @@ pub(crate) mod builtin {
         ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
     }
 
-    /// Inline assembly.
-    ///
-    /// Read the [unstable book] for the usage.
-    ///
-    /// [unstable book]: ../unstable-book/library-features/asm.html
-    #[unstable(
-        feature = "asm",
-        issue = "72016",
-        reason = "inline assembly is not stable enough for use and is subject to change"
-    )]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! asm {
-        ("assembly template",
-            $(operands,)*
-            $(options($(option),*))?
-        ) => {
-            /* compiler built-in */
-        };
-    }
-
     /// LLVM-style inline assembly.
     ///
     /// Read the [unstable book] for the usage.
@@ -1337,6 +1347,10 @@ pub(crate) mod builtin {
         issue = "70173",
         reason = "prefer using the new asm! syntax instead"
     )]
+    #[rustc_deprecated(
+        since = "1.56",
+        reason = "will be removed from the compiler, use asm! instead"
+    )]
     #[rustc_builtin_macro]
     #[macro_export]
     macro_rules! llvm_asm {
@@ -1349,23 +1363,6 @@ pub(crate) mod builtin {
         };
     }
 
-    /// Module-level inline assembly.
-    #[unstable(
-        feature = "global_asm",
-        issue = "35119",
-        reason = "`global_asm!` is not stable enough for use and is subject to change"
-    )]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! global_asm {
-        ("assembly template",
-            $(operands,)*
-            $(options($(option),*))?
-        ) => {
-            /* compiler built-in */
-        };
-    }
-
     /// Prints passed tokens into the standard output.
     #[unstable(
         feature = "log_syntax",
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 2b240455043..333f81ce4cf 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -31,7 +31,6 @@ use crate::hash::Hasher;
 /// [ub]: ../../reference/behavior-considered-undefined.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "send_trait")]
-#[cfg_attr(not(bootstrap), lang = "send")]
 #[rustc_on_unimplemented(
     message = "`{Self}` cannot be sent between threads safely",
     label = "`{Self}` cannot be sent between threads safely"
@@ -529,7 +528,8 @@ macro_rules! impls {
         }
 
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<T: ?Sized> Default for $t<T> {
+        #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+        impl<T: ?Sized> const Default for $t<T> {
             fn default() -> Self {
                 Self
             }
diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs
index 5b99f6954e6..d86939454be 100644
--- a/library/core/src/mem/manually_drop.rs
+++ b/library/core/src/mem/manually_drop.rs
@@ -44,7 +44,7 @@ use crate::ptr;
 /// [`MaybeUninit<T>`]: crate::mem::MaybeUninit
 #[stable(feature = "manually_drop", since = "1.20.0")]
 #[lang = "manually_drop"]
-#[derive(Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(transparent)]
 pub struct ManuallyDrop<T: ?Sized> {
     value: T,
@@ -160,16 +160,3 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
         &mut self.value
     }
 }
-
-#[stable(feature = "manually_drop", since = "1.20.0")]
-impl<T: Clone> Clone for ManuallyDrop<T> {
-    #[inline]
-    fn clone(&self) -> ManuallyDrop<T> {
-        ManuallyDrop { value: self.value.clone() }
-    }
-
-    #[inline]
-    fn clone_from(&mut self, other: &Self) {
-        self.value.clone_from(&other.value)
-    }
-}
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 10219201a40..9c88a623361 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -79,7 +79,7 @@ use crate::ptr;
 /// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
 /// let mut x = MaybeUninit::<&i32>::uninit();
 /// // Set it to a valid value.
-/// unsafe { x.as_mut_ptr().write(&0); }
+/// x.write(&0);
 /// // Extract the initialized data -- this is only allowed *after* properly
 /// // initializing `x`!
 /// let x = unsafe { x.assume_init() };
@@ -135,7 +135,7 @@ use crate::ptr;
 ///     // this loop, we have a memory leak, but there is no memory safety
 ///     // issue.
 ///     for elem in &mut data[..] {
-///         *elem = MaybeUninit::new(vec![42]);
+///         elem.write(vec![42]);
 ///     }
 ///
 ///     // Everything is initialized. Transmute the array to the
@@ -161,7 +161,7 @@ use crate::ptr;
 /// let mut data_len: usize = 0;
 ///
 /// for elem in &mut data[0..500] {
-///     *elem = MaybeUninit::new(String::from("hello"));
+///     elem.write(String::from("hello"));
 ///     data_len += 1;
 /// }
 ///
@@ -402,12 +402,89 @@ impl<T> MaybeUninit<T> {
         u
     }
 
-    /// Sets the value of the `MaybeUninit<T>`. This overwrites any previous value
-    /// without dropping it, so be careful not to use this twice unless you want to
-    /// skip running the destructor. For your convenience, this also returns a mutable
-    /// reference to the (now safely initialized) contents of `self`.
-    #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
-    #[rustc_const_unstable(feature = "maybe_uninit_extra", issue = "63567")]
+    /// Sets the value of the `MaybeUninit<T>`.
+    ///
+    /// This overwrites any previous value without dropping it, so be careful
+    /// not to use this twice unless you want to skip running the destructor.
+    /// For your convenience, this also returns a mutable reference to the
+    /// (now safely initialized) contents of `self`.
+    ///
+    /// As the content is stored inside a `MaybeUninit`, the destructor is not
+    /// run for the inner data if the MaybeUninit leaves scope without a call to
+    /// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
+    /// the mutable reference returned by this function needs to keep this in
+    /// mind. The safety model of Rust regards leaks as safe, but they are
+    /// usually still undesirable. This being said, the mutable reference
+    /// behaves like any other mutable reference would, so assigning a new value
+    /// to it will drop the old content.
+    ///
+    /// [`assume_init`]: Self::assume_init
+    /// [`assume_init_drop`]: Self::assume_init_drop
+    ///
+    /// # Examples
+    ///
+    /// Correct usage of this method:
+    ///
+    /// ```rust
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<Vec<u8>>::uninit();
+    ///
+    /// {
+    ///     let hello = x.write((&b"Hello, world!").to_vec());
+    ///     // Setting hello does not leak prior allocations, but drops them
+    ///     *hello = (&b"Hello").to_vec();
+    ///     hello[0] = 'h' as u8;
+    /// }
+    /// // x is initialized now:
+    /// let s = unsafe { x.assume_init() };
+    /// assert_eq!(b"hello", s.as_slice());
+    /// ```
+    ///
+    /// This usage of the method causes a leak:
+    ///
+    /// ```rust
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<String>::uninit();
+    ///
+    /// x.write("Hello".to_string());
+    /// // This leaks the contained string:
+    /// x.write("hello".to_string());
+    /// // x is initialized now:
+    /// let s = unsafe { x.assume_init() };
+    /// ```
+    ///
+    /// This method can be used to avoid unsafe in some cases. The example below
+    /// shows a part of an implementation of a fixed sized arena that lends out
+    /// pinned references.
+    /// With `write`, we can avoid the need to write through a raw pointer:
+    ///
+    /// ```rust
+    /// use core::pin::Pin;
+    /// use core::mem::MaybeUninit;
+    ///
+    /// struct PinArena<T> {
+    ///     memory: Box<[MaybeUninit<T>]>,
+    ///     len: usize,
+    /// }
+    ///
+    /// impl <T> PinArena<T> {
+    ///     pub fn capacity(&self) -> usize {
+    ///         self.memory.len()
+    ///     }
+    ///     pub fn push(&mut self, val: T) -> Pin<&mut T> {
+    ///         if self.len >= self.capacity() {
+    ///             panic!("Attempted to push to a full pin arena!");
+    ///         }
+    ///         let ref_ = self.memory[self.len].write(val);
+    ///         self.len += 1;
+    ///         unsafe { Pin::new_unchecked(ref_) }
+    ///     }
+    /// }
+    /// ```
+    #[stable(feature = "maybe_uninit_write", since = "1.55.0")]
+    #[rustc_const_unstable(feature = "const_maybe_uninit_write", issue = "63567")]
     #[inline(always)]
     pub const fn write(&mut self, val: T) -> &mut T {
         *self = MaybeUninit::new(val);
@@ -428,7 +505,7 @@ impl<T> MaybeUninit<T> {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
-    /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
+    /// x.write(vec![0, 1, 2]);
     /// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
     /// let x_vec = unsafe { &*x.as_ptr() };
     /// assert_eq!(x_vec.len(), 3);
@@ -465,7 +542,7 @@ impl<T> MaybeUninit<T> {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
-    /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
+    /// x.write(vec![0, 1, 2]);
     /// // Create a reference into the `MaybeUninit<Vec<u32>>`.
     /// // This is okay because we initialized it.
     /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
@@ -524,7 +601,7 @@ impl<T> MaybeUninit<T> {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<bool>::uninit();
-    /// unsafe { x.as_mut_ptr().write(true); }
+    /// x.write(true);
     /// let x_init = unsafe { x.assume_init() };
     /// assert_eq!(x_init, true);
     /// ```
@@ -542,6 +619,7 @@ impl<T> MaybeUninit<T> {
     #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
     #[inline(always)]
     #[rustc_diagnostic_item = "assume_init"]
+    #[track_caller]
     pub const unsafe fn assume_init(self) -> T {
         // SAFETY: the caller must guarantee that `self` is initialized.
         // This also means that `self` must be a `value` variant.
@@ -564,9 +642,11 @@ impl<T> MaybeUninit<T> {
     /// behavior. The [type-level documentation][inv] contains more information about
     /// this initialization invariant.
     ///
-    /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
-    /// multiple copies of the data (by calling `assume_init_read` multiple times, or first
-    /// calling `assume_init_read` and then [`assume_init`]), it is your responsibility
+    /// Moreover, similar to the [`ptr::read`] function, this function creates a
+    /// bitwise copy of the contents, regardless whether the contained type
+    /// implements the [`Copy`] trait or not. When using multiple copies of the
+    /// data (by calling `assume_init_read` multiple times, or first calling
+    /// `assume_init_read` and then [`assume_init`]), it is your responsibility
     /// to ensure that that data may indeed be duplicated.
     ///
     /// [inv]: #initialization-invariant
@@ -611,6 +691,7 @@ impl<T> MaybeUninit<T> {
     #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
     #[rustc_const_unstable(feature = "maybe_uninit_extra", issue = "63567")]
     #[inline(always)]
+    #[track_caller]
     pub const unsafe fn assume_init_read(&self) -> T {
         // SAFETY: the caller must guarantee that `self` is initialized.
         // Reading from `self.as_ptr()` is safe since `self` should be initialized.
@@ -622,7 +703,8 @@ impl<T> MaybeUninit<T> {
 
     /// Drops the contained value in place.
     ///
-    /// If you have ownership of the `MaybeUninit`, you can use [`assume_init`] instead.
+    /// If you have ownership of the `MaybeUninit`, you can also use
+    /// [`assume_init`] as an alternative.
     ///
     /// # Safety
     ///
@@ -632,11 +714,12 @@ impl<T> MaybeUninit<T> {
     ///
     /// On top of that, all additional invariants of the type `T` must be
     /// satisfied, as the `Drop` implementation of `T` (or its members) may
-    /// rely on this. For example, a `1`-initialized [`Vec<T>`] is considered
-    /// initialized (under the current implementation; this does not constitute
-    /// a stable guarantee) because the only requirement the compiler knows
-    /// about it is that the data pointer must be non-null. Dropping such a
-    /// `Vec<T>` however will cause undefined behaviour.
+    /// rely on this. For example, setting a [`Vec<T>`] to an invalid but
+    /// non-null address makes it initialized (under the current implementation;
+    /// this does not constitute a stable guarantee), because the only
+    /// requirement the compiler knows about it is that the data pointer must be
+    /// non-null. Dropping such a `Vec<T>` however will cause undefined
+    /// behaviour.
     ///
     /// [`assume_init`]: MaybeUninit::assume_init
     /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
@@ -665,12 +748,11 @@ impl<T> MaybeUninit<T> {
     /// ### Correct usage of this method:
     ///
     /// ```rust
-    /// #![feature(maybe_uninit_ref)]
     /// use std::mem::MaybeUninit;
     ///
     /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
     /// // Initialize `x`:
-    /// unsafe { x.as_mut_ptr().write(vec![1, 2, 3]); }
+    /// x.write(vec![1, 2, 3]);
     /// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
     /// // create a shared reference to it:
     /// let x: &Vec<u32> = unsafe {
@@ -683,7 +765,6 @@ impl<T> MaybeUninit<T> {
     /// ### *Incorrect* usages of this method:
     ///
     /// ```rust,no_run
-    /// #![feature(maybe_uninit_ref)]
     /// use std::mem::MaybeUninit;
     ///
     /// let x = MaybeUninit::<Vec<u32>>::uninit();
@@ -692,7 +773,6 @@ impl<T> MaybeUninit<T> {
     /// ```
     ///
     /// ```rust,no_run
-    /// #![feature(maybe_uninit_ref)]
     /// use std::{cell::Cell, mem::MaybeUninit};
     ///
     /// let b = MaybeUninit::<Cell<bool>>::uninit();
@@ -703,7 +783,7 @@ impl<T> MaybeUninit<T> {
     ///    // Reference to an uninitialized `Cell<bool>`: UB!
     /// }
     /// ```
-    #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
+    #[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
     #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
     #[inline(always)]
     pub const unsafe fn assume_init_ref(&self) -> &T {
@@ -733,7 +813,6 @@ impl<T> MaybeUninit<T> {
     /// ### Correct usage of this method:
     ///
     /// ```rust
-    /// #![feature(maybe_uninit_ref)]
     /// use std::mem::MaybeUninit;
     ///
     /// # unsafe extern "C" fn initialize_buffer(buf: *mut [u8; 1024]) { *buf = [0; 1024] }
@@ -769,7 +848,6 @@ impl<T> MaybeUninit<T> {
     /// You cannot use `.assume_init_mut()` to initialize a value:
     ///
     /// ```rust,no_run
-    /// #![feature(maybe_uninit_ref)]
     /// use std::mem::MaybeUninit;
     ///
     /// let mut b = MaybeUninit::<bool>::uninit();
@@ -785,7 +863,6 @@ impl<T> MaybeUninit<T> {
     /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
     ///
     /// ```rust,no_run
-    /// #![feature(maybe_uninit_ref)]
     /// use std::{io, mem::MaybeUninit};
     ///
     /// fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]>
@@ -802,7 +879,6 @@ impl<T> MaybeUninit<T> {
     /// Nor can you use direct field access to do field-by-field gradual initialization:
     ///
     /// ```rust,no_run
-    /// #![feature(maybe_uninit_ref)]
     /// use std::{mem::MaybeUninit, ptr};
     ///
     /// struct Foo {
@@ -823,10 +899,7 @@ impl<T> MaybeUninit<T> {
     ///     foo.assume_init()
     /// };
     /// ```
-    // FIXME(#76092): We currently rely on the above being incorrect, i.e., we have references
-    // to uninitialized data (e.g., in `libcore/fmt/float.rs`).  We should make
-    // a final decision about the rules before stabilization.
-    #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
+    #[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
     #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
     #[inline(always)]
     pub const unsafe fn assume_init_mut(&mut self) -> &mut T {
@@ -853,9 +926,9 @@ impl<T> MaybeUninit<T> {
     /// use std::mem::MaybeUninit;
     ///
     /// let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array();
-    /// array[0] = MaybeUninit::new(0);
-    /// array[1] = MaybeUninit::new(1);
-    /// array[2] = MaybeUninit::new(2);
+    /// array[0].write(0);
+    /// array[1].write(1);
+    /// array[2].write(2);
     ///
     /// // SAFETY: Now safe as we initialised all elements
     /// let array = unsafe {
@@ -866,6 +939,7 @@ impl<T> MaybeUninit<T> {
     /// ```
     #[unstable(feature = "maybe_uninit_array_assume_init", issue = "80908")]
     #[inline(always)]
+    #[track_caller]
     pub unsafe fn array_assume_init<const N: usize>(array: [Self; N]) -> [T; N] {
         // SAFETY:
         // * The caller guarantees that all elements of the array are initialized
@@ -936,7 +1010,7 @@ impl<T> MaybeUninit<T> {
         this.as_mut_ptr() as *mut T
     }
 
-    /// Copies the elements from `src` to `this`, returning a mutable reference to the now initalized contents of `this`.
+    /// Copies the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
     ///
     /// If `T` does not implement `Copy`, use [`write_slice_cloned`]
     ///
@@ -989,12 +1063,12 @@ impl<T> MaybeUninit<T> {
 
         this.copy_from_slice(uninit_src);
 
-        // SAFETY: Valid elements have just been copied into `this` so it is initalized
+        // SAFETY: Valid elements have just been copied into `this` so it is initialized
         unsafe { MaybeUninit::slice_assume_init_mut(this) }
     }
 
-    /// Clones the elements from `src` to `this`, returning a mutable reference to the now initalized contents of `this`.
-    /// Any already initalized elements will not be dropped.
+    /// Clones the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
+    /// Any already initialized elements will not be dropped.
     ///
     /// If `T` implements `Copy`, use [`write_slice`]
     ///
@@ -1080,7 +1154,7 @@ impl<T> MaybeUninit<T> {
 
         super::forget(guard);
 
-        // SAFETY: Valid elements have just been written into `this` so it is initalized
+        // SAFETY: Valid elements have just been written into `this` so it is initialized
         unsafe { MaybeUninit::slice_assume_init_mut(this) }
     }
 }
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 5bf47c3951d..d6eb535fd2e 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -140,6 +140,7 @@ pub use crate::intrinsics::transmute;
 #[inline]
 #[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "mem_forget")]
 pub const fn forget<T>(t: T) {
     let _ = ManuallyDrop::new(t);
 }
@@ -298,6 +299,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_promotable]
 #[rustc_const_stable(feature = "const_size_of", since = "1.24.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of")]
 pub const fn size_of<T>() -> usize {
     intrinsics::size_of::<T>()
 }
@@ -324,6 +326,7 @@ pub const fn size_of<T>() -> usize {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")]
 pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
     // SAFETY: `val` is a reference, so it's a valid raw pointer
     unsafe { intrinsics::size_of_val(val) }
@@ -619,6 +622,7 @@ pub const fn needs_drop<T>() -> bool {
 #[allow(deprecated_in_future)]
 #[allow(deprecated)]
 #[rustc_diagnostic_item = "mem_zeroed"]
+#[track_caller]
 pub unsafe fn zeroed<T>() -> T {
     // SAFETY: the caller must guarantee that an all-zero value is valid for `T`.
     unsafe {
@@ -654,6 +658,7 @@ pub unsafe fn zeroed<T>() -> T {
 #[allow(deprecated_in_future)]
 #[allow(deprecated)]
 #[rustc_diagnostic_item = "mem_uninitialized"]
+#[track_caller]
 pub unsafe fn uninitialized<T>() -> T {
     // SAFETY: the caller must guarantee that an unitialized value is valid for `T`.
     unsafe {
@@ -814,6 +819,7 @@ pub fn take<T: Default>(dest: &mut T) -> T {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[must_use = "if you don't need the old value, you can just assign the new value directly"]
 #[rustc_const_unstable(feature = "const_replace", issue = "83164")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")]
 pub const fn replace<T>(dest: &mut T, src: T) -> T {
     // SAFETY: We read from `dest` but directly write `src` into it afterwards,
     // such that the old value is not duplicated. Nothing is dropped and
@@ -888,6 +894,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
 /// [`RefCell`]: crate::cell::RefCell
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "mem_drop")]
 pub fn drop<T>(_x: T) {}
 
 /// Interprets `src` as having type `&U`, and then reads `src` without moving
@@ -934,7 +941,7 @@ pub fn drop<T>(_x: T) {}
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")]
 pub const unsafe fn transmute_copy<T, U>(src: &T) -> U {
-    // If U has a higher alignment requirement, src may not be suitably aligned.
+    // If U has a higher alignment requirement, src might not be suitably aligned.
     if align_of::<U>() > align_of::<T>() {
         // SAFETY: `src` is a reference which is guaranteed to be valid for reads.
         // The caller must guarantee that the actual transmutation is safe.
@@ -1015,6 +1022,7 @@ impl<T> fmt::Debug for Discriminant<T> {
 /// ```
 #[stable(feature = "discriminant_value", since = "1.21.0")]
 #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "mem_discriminant")]
 pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
     Discriminant(intrinsics::discriminant_value(v))
 }
diff --git a/library/core/src/num/dec2flt/algorithm.rs b/library/core/src/num/dec2flt/algorithm.rs
deleted file mode 100644
index 313b6870ac9..00000000000
--- a/library/core/src/num/dec2flt/algorithm.rs
+++ /dev/null
@@ -1,429 +0,0 @@
-//! The various algorithms from the paper.
-
-use crate::cmp::min;
-use crate::cmp::Ordering::{Equal, Greater, Less};
-use crate::num::dec2flt::num::{self, Big};
-use crate::num::dec2flt::rawfp::{self, fp_to_float, next_float, prev_float, RawFloat, Unpacked};
-use crate::num::dec2flt::table;
-use crate::num::diy_float::Fp;
-
-/// Number of significand bits in Fp
-const P: u32 = 64;
-
-// We simply store the best approximation for *all* exponents, so the variable "h" and the
-// associated conditions can be omitted. This trades performance for a couple kilobytes of space.
-
-fn power_of_ten(e: i16) -> Fp {
-    assert!(e >= table::MIN_E);
-    let i = e - table::MIN_E;
-    let sig = table::POWERS.0[i as usize];
-    let exp = table::POWERS.1[i as usize];
-    Fp { f: sig, e: exp }
-}
-
-// In most architectures, floating point operations have an explicit bit size, therefore the
-// precision of the computation is determined on a per-operation basis.
-#[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))]
-mod fpu_precision {
-    pub fn set_precision<T>() {}
-}
-
-// On x86, the x87 FPU is used for float operations if the SSE/SSE2 extensions are not available.
-// The x87 FPU operates with 80 bits of precision by default, which means that operations will
-// round to 80 bits causing double rounding to happen when values are eventually represented as
-// 32/64 bit float values. To overcome this, the FPU control word can be set so that the
-// computations are performed in the desired precision.
-#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
-mod fpu_precision {
-    use crate::mem::size_of;
-
-    /// A structure used to preserve the original value of the FPU control word, so that it can be
-    /// restored when the structure is dropped.
-    ///
-    /// The x87 FPU is a 16-bits register whose fields are as follows:
-    ///
-    /// | 12-15 | 10-11 | 8-9 | 6-7 |  5 |  4 |  3 |  2 |  1 |  0 |
-    /// |------:|------:|----:|----:|---:|---:|---:|---:|---:|---:|
-    /// |       | RC    | PC  |     | PM | UM | OM | ZM | DM | IM |
-    ///
-    /// The documentation for all of the fields is available in the IA-32 Architectures Software
-    /// Developer's Manual (Volume 1).
-    ///
-    /// The only field which is relevant for the following code is PC, Precision Control. This
-    /// field determines the precision of the operations performed by the  FPU. It can be set to:
-    ///  - 0b00, single precision i.e., 32-bits
-    ///  - 0b10, double precision i.e., 64-bits
-    ///  - 0b11, double extended precision i.e., 80-bits (default state)
-    /// The 0b01 value is reserved and should not be used.
-    pub struct FPUControlWord(u16);
-
-    fn set_cw(cw: u16) {
-        // SAFETY: the `fldcw` instruction has been audited to be able to work correctly with
-        // any `u16`
-        unsafe {
-            asm!(
-                "fldcw word ptr [{}]",
-                in(reg) &cw,
-                options(nostack),
-            )
-        }
-    }
-
-    /// Sets the precision field of the FPU to `T` and returns a `FPUControlWord`.
-    pub fn set_precision<T>() -> FPUControlWord {
-        let mut cw = 0_u16;
-
-        // Compute the value for the Precision Control field that is appropriate for `T`.
-        let cw_precision = match size_of::<T>() {
-            4 => 0x0000, // 32 bits
-            8 => 0x0200, // 64 bits
-            _ => 0x0300, // default, 80 bits
-        };
-
-        // Get the original value of the control word to restore it later, when the
-        // `FPUControlWord` structure is dropped
-        // SAFETY: the `fnstcw` instruction has been audited to be able to work correctly with
-        // any `u16`
-        unsafe {
-            asm!(
-                "fnstcw word ptr [{}]",
-                in(reg) &mut cw,
-                options(nostack),
-            )
-        }
-
-        // Set the control word to the desired precision. This is achieved by masking away the old
-        // precision (bits 8 and 9, 0x300) and replacing it with the precision flag computed above.
-        set_cw((cw & 0xFCFF) | cw_precision);
-
-        FPUControlWord(cw)
-    }
-
-    impl Drop for FPUControlWord {
-        fn drop(&mut self) {
-            set_cw(self.0)
-        }
-    }
-}
-
-/// The fast path of Bellerophon using machine-sized integers and floats.
-///
-/// This is extracted into a separate function so that it can be attempted before constructing
-/// a bignum.
-pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Option<T> {
-    let num_digits = integral.len() + fractional.len();
-    // log_10(f64::MAX_SIG) ~ 15.95. We compare the exact value to MAX_SIG near the end,
-    // this is just a quick, cheap rejection (and also frees the rest of the code from
-    // worrying about underflow).
-    if num_digits > 16 {
-        return None;
-    }
-    if e.abs() >= T::CEIL_LOG5_OF_MAX_SIG as i64 {
-        return None;
-    }
-    let f = num::from_str_unchecked(integral.iter().chain(fractional.iter()));
-    if f > T::MAX_SIG {
-        return None;
-    }
-
-    // The fast path crucially depends on arithmetic being rounded to the correct number of bits
-    // without any intermediate rounding. On x86 (without SSE or SSE2) this requires the precision
-    // of the x87 FPU stack to be changed so that it directly rounds to 64/32 bit.
-    // The `set_precision` function takes care of setting the precision on architectures which
-    // require setting it by changing the global state (like the control word of the x87 FPU).
-    let _cw = fpu_precision::set_precision::<T>();
-
-    // The case e < 0 cannot be folded into the other branch. Negative powers result in
-    // a repeating fractional part in binary, which are rounded, which causes real
-    // (and occasionally quite significant!) errors in the final result.
-    if e >= 0 {
-        Some(T::from_int(f) * T::short_fast_pow10(e as usize))
-    } else {
-        Some(T::from_int(f) / T::short_fast_pow10(e.abs() as usize))
-    }
-}
-
-/// Algorithm Bellerophon is trivial code justified by non-trivial numeric analysis.
-///
-/// It rounds ``f`` to a float with 64 bit significand and multiplies it by the best approximation
-/// of `10^e` (in the same floating point format). This is often enough to get the correct result.
-/// However, when the result is close to halfway between two adjacent (ordinary) floats, the
-/// compound rounding error from multiplying two approximation means the result may be off by a
-/// few bits. When this happens, the iterative Algorithm R fixes things up.
-///
-/// The hand-wavy "close to halfway" is made precise by the numeric analysis in the paper.
-/// In the words of Clinger:
-///
-/// > Slop, expressed in units of the least significant bit, is an inclusive bound for the error
-/// > accumulated during the floating point calculation of the approximation to f * 10^e. (Slop is
-/// > not a bound for the true error, but bounds the difference between the approximation z and
-/// > the best possible approximation that uses p bits of significand.)
-pub fn bellerophon<T: RawFloat>(f: &Big, e: i16) -> T {
-    let slop = if f <= &Big::from_u64(T::MAX_SIG) {
-        // The cases abs(e) < log5(2^N) are in fast_path()
-        if e >= 0 { 0 } else { 3 }
-    } else {
-        if e >= 0 { 1 } else { 4 }
-    };
-    let z = rawfp::big_to_fp(f).mul(&power_of_ten(e)).normalize();
-    let exp_p_n = 1 << (P - T::SIG_BITS as u32);
-    let lowbits: i64 = (z.f % exp_p_n) as i64;
-    // Is the slop large enough to make a difference when
-    // rounding to n bits?
-    if (lowbits - exp_p_n as i64 / 2).abs() <= slop {
-        algorithm_r(f, e, fp_to_float(z))
-    } else {
-        fp_to_float(z)
-    }
-}
-
-/// An iterative algorithm that improves a floating point approximation of `f * 10^e`.
-///
-/// Each iteration gets one unit in the last place closer, which of course takes terribly long to
-/// converge if `z0` is even mildly off. Luckily, when used as fallback for Bellerophon, the
-/// starting approximation is off by at most one ULP.
-fn algorithm_r<T: RawFloat>(f: &Big, e: i16, z0: T) -> T {
-    let mut z = z0;
-    loop {
-        let raw = z.unpack();
-        let (m, k) = (raw.sig, raw.k);
-        let mut x = f.clone();
-        let mut y = Big::from_u64(m);
-
-        // Find positive integers `x`, `y` such that `x / y` is exactly `(f * 10^e) / (m * 2^k)`.
-        // This not only avoids dealing with the signs of `e` and `k`, we also eliminate the
-        // power of two common to `10^e` and `2^k` to make the numbers smaller.
-        make_ratio(&mut x, &mut y, e, k);
-
-        let m_digits = [(m & 0xFF_FF_FF_FF) as u32, (m >> 32) as u32];
-        // This is written a bit awkwardly because our bignums don't support
-        // negative numbers, so we use the absolute value + sign information.
-        // The multiplication with m_digits can't overflow. If `x` or `y` are large enough that
-        // we need to worry about overflow, then they are also large enough that `make_ratio` has
-        // reduced the fraction by a factor of 2^64 or more.
-        let (d2, d_negative) = if x >= y {
-            // Don't need x any more, save a clone().
-            x.sub(&y).mul_pow2(1).mul_digits(&m_digits);
-            (x, false)
-        } else {
-            // Still need y - make a copy.
-            let mut y = y.clone();
-            y.sub(&x).mul_pow2(1).mul_digits(&m_digits);
-            (y, true)
-        };
-
-        if d2 < y {
-            let mut d2_double = d2;
-            d2_double.mul_pow2(1);
-            if m == T::MIN_SIG && d_negative && d2_double > y {
-                z = prev_float(z);
-            } else {
-                return z;
-            }
-        } else if d2 == y {
-            if m % 2 == 0 {
-                if m == T::MIN_SIG && d_negative {
-                    z = prev_float(z);
-                } else {
-                    return z;
-                }
-            } else if d_negative {
-                z = prev_float(z);
-            } else {
-                z = next_float(z);
-            }
-        } else if d_negative {
-            z = prev_float(z);
-        } else {
-            z = next_float(z);
-        }
-    }
-}
-
-/// Given `x = f` and `y = m` where `f` represent input decimal digits as usual and `m` is the
-/// significand of a floating point approximation, make the ratio `x / y` equal to
-/// `(f * 10^e) / (m * 2^k)`, possibly reduced by a power of two both have in common.
-fn make_ratio(x: &mut Big, y: &mut Big, e: i16, k: i16) {
-    let (e_abs, k_abs) = (e.abs() as usize, k.abs() as usize);
-    if e >= 0 {
-        if k >= 0 {
-            // x = f * 10^e, y = m * 2^k, except that we reduce the fraction by some power of two.
-            let common = min(e_abs, k_abs);
-            x.mul_pow5(e_abs).mul_pow2(e_abs - common);
-            y.mul_pow2(k_abs - common);
-        } else {
-            // x = f * 10^e * 2^abs(k), y = m
-            // This can't overflow because it requires positive `e` and negative `k`, which can
-            // only happen for values extremely close to 1, which means that `e` and `k` will be
-            // comparatively tiny.
-            x.mul_pow5(e_abs).mul_pow2(e_abs + k_abs);
-        }
-    } else {
-        if k >= 0 {
-            // x = f, y = m * 10^abs(e) * 2^k
-            // This can't overflow either, see above.
-            y.mul_pow5(e_abs).mul_pow2(k_abs + e_abs);
-        } else {
-            // x = f * 2^abs(k), y = m * 10^abs(e), again reducing by a common power of two.
-            let common = min(e_abs, k_abs);
-            x.mul_pow2(k_abs - common);
-            y.mul_pow5(e_abs).mul_pow2(e_abs - common);
-        }
-    }
-}
-
-/// Conceptually, Algorithm M is the simplest way to convert a decimal to a float.
-///
-/// We form a ratio that is equal to `f * 10^e`, then throwing in powers of two until it gives
-/// a valid float significand. The binary exponent `k` is the number of times we multiplied
-/// numerator or denominator by two, i.e., at all times `f * 10^e` equals `(u / v) * 2^k`.
-/// When we have found out significand, we only need to round by inspecting the remainder of the
-/// division, which is done in helper functions further below.
-///
-/// This algorithm is super slow, even with the optimization described in `quick_start()`.
-/// However, it's the simplest of the algorithms to adapt for overflow, underflow, and subnormal
-/// results. This implementation takes over when Bellerophon and Algorithm R are overwhelmed.
-/// Detecting underflow and overflow is easy: The ratio still isn't an in-range significand,
-/// yet the minimum/maximum exponent has been reached. In the case of overflow, we simply return
-/// infinity.
-///
-/// Handling underflow and subnormals is trickier. One big problem is that, with the minimum
-/// exponent, the ratio might still be too large for a significand. See underflow() for details.
-pub fn algorithm_m<T: RawFloat>(f: &Big, e: i16) -> T {
-    let mut u;
-    let mut v;
-    let e_abs = e.abs() as usize;
-    let mut k = 0;
-    if e < 0 {
-        u = f.clone();
-        v = Big::from_small(1);
-        v.mul_pow5(e_abs).mul_pow2(e_abs);
-    } else {
-        // FIXME possible optimization: generalize big_to_fp so that we can do the equivalent of
-        // fp_to_float(big_to_fp(u)) here, only without the double rounding.
-        u = f.clone();
-        u.mul_pow5(e_abs).mul_pow2(e_abs);
-        v = Big::from_small(1);
-    }
-    quick_start::<T>(&mut u, &mut v, &mut k);
-    let mut rem = Big::from_small(0);
-    let mut x = Big::from_small(0);
-    let min_sig = Big::from_u64(T::MIN_SIG);
-    let max_sig = Big::from_u64(T::MAX_SIG);
-    loop {
-        u.div_rem(&v, &mut x, &mut rem);
-        if k == T::MIN_EXP_INT {
-            // We have to stop at the minimum exponent, if we wait until `k < T::MIN_EXP_INT`,
-            // then we'd be off by a factor of two. Unfortunately this means we have to special-
-            // case normal numbers with the minimum exponent.
-            // FIXME find a more elegant formulation, but run the `tiny-pow10` test to make sure
-            // that it's actually correct!
-            if x >= min_sig && x <= max_sig {
-                break;
-            }
-            return underflow(x, v, rem);
-        }
-        if k > T::MAX_EXP_INT {
-            return T::INFINITY;
-        }
-        if x < min_sig {
-            u.mul_pow2(1);
-            k -= 1;
-        } else if x > max_sig {
-            v.mul_pow2(1);
-            k += 1;
-        } else {
-            break;
-        }
-    }
-    let q = num::to_u64(&x);
-    let z = rawfp::encode_normal(Unpacked::new(q, k));
-    round_by_remainder(v, rem, q, z)
-}
-
-/// Skips over most Algorithm M iterations by checking the bit length.
-fn quick_start<T: RawFloat>(u: &mut Big, v: &mut Big, k: &mut i16) {
-    // The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v).
-    // The estimate is off by at most 1, but always an under-estimate, so the error on log(u)
-    // and log(v) are of the same sign and cancel out (if both are large). Therefore the error
-    // for log(u / v) is at most one as well.
-    // The target ratio is one where u/v is in an in-range significand. Thus our termination
-    // condition is log2(u / v) being the significand bits, plus/minus one.
-    // FIXME Looking at the second bit could improve the estimate and avoid some more divisions.
-    let target_ratio = T::SIG_BITS as i16;
-    let log2_u = u.bit_length() as i16;
-    let log2_v = v.bit_length() as i16;
-    let mut u_shift: i16 = 0;
-    let mut v_shift: i16 = 0;
-    assert!(*k == 0);
-    loop {
-        if *k == T::MIN_EXP_INT {
-            // Underflow or subnormal. Leave it to the main function.
-            break;
-        }
-        if *k == T::MAX_EXP_INT {
-            // Overflow. Leave it to the main function.
-            break;
-        }
-        let log2_ratio = (log2_u + u_shift) - (log2_v + v_shift);
-        if log2_ratio < target_ratio - 1 {
-            u_shift += 1;
-            *k -= 1;
-        } else if log2_ratio > target_ratio + 1 {
-            v_shift += 1;
-            *k += 1;
-        } else {
-            break;
-        }
-    }
-    u.mul_pow2(u_shift as usize);
-    v.mul_pow2(v_shift as usize);
-}
-
-fn underflow<T: RawFloat>(x: Big, v: Big, rem: Big) -> T {
-    if x < Big::from_u64(T::MIN_SIG) {
-        let q = num::to_u64(&x);
-        let z = rawfp::encode_subnormal(q);
-        return round_by_remainder(v, rem, q, z);
-    }
-    // Ratio isn't an in-range significand with the minimum exponent, so we need to round off
-    // excess bits and adjust the exponent accordingly. The real value now looks like this:
-    //
-    //        x        lsb
-    // /--------------\/
-    // 1010101010101010.10101010101010 * 2^k
-    // \-----/\-------/ \------------/
-    //    q     trunc.    (represented by rem)
-    //
-    // Therefore, when the rounded-off bits are != 0.5 ULP, they decide the rounding
-    // on their own. When they are equal and the remainder is non-zero, the value still
-    // needs to be rounded up. Only when the rounded off bits are 1/2 and the remainder
-    // is zero, we have a half-to-even situation.
-    let bits = x.bit_length();
-    let lsb = bits - T::SIG_BITS as usize;
-    let q = num::get_bits(&x, lsb, bits);
-    let k = T::MIN_EXP_INT + lsb as i16;
-    let z = rawfp::encode_normal(Unpacked::new(q, k));
-    let q_even = q % 2 == 0;
-    match num::compare_with_half_ulp(&x, lsb) {
-        Greater => next_float(z),
-        Less => z,
-        Equal if rem.is_zero() && q_even => z,
-        Equal => next_float(z),
-    }
-}
-
-/// Ordinary round-to-even, obfuscated by having to round based on the remainder of a division.
-fn round_by_remainder<T: RawFloat>(v: Big, r: Big, q: u64, z: T) -> T {
-    let mut v_minus_r = v;
-    v_minus_r.sub(&r);
-    if r < v_minus_r {
-        z
-    } else if r > v_minus_r {
-        next_float(z)
-    } else if q % 2 == 0 {
-        z
-    } else {
-        next_float(z)
-    }
-}
diff --git a/library/core/src/num/dec2flt/common.rs b/library/core/src/num/dec2flt/common.rs
new file mode 100644
index 00000000000..247123737df
--- /dev/null
+++ b/library/core/src/num/dec2flt/common.rs
@@ -0,0 +1,198 @@
+//! Common utilities, for internal use only.
+
+use crate::ptr;
+
+/// Helper methods to process immutable bytes.
+pub(crate) trait ByteSlice: AsRef<[u8]> {
+    unsafe fn first_unchecked(&self) -> u8 {
+        debug_assert!(!self.is_empty());
+        // SAFETY: safe as long as self is not empty
+        unsafe { *self.as_ref().get_unchecked(0) }
+    }
+
+    /// Get if the slice contains no elements.
+    fn is_empty(&self) -> bool {
+        self.as_ref().is_empty()
+    }
+
+    /// Check if the slice at least `n` length.
+    fn check_len(&self, n: usize) -> bool {
+        n <= self.as_ref().len()
+    }
+
+    /// Check if the first character in the slice is equal to c.
+    fn first_is(&self, c: u8) -> bool {
+        self.as_ref().first() == Some(&c)
+    }
+
+    /// Check if the first character in the slice is equal to c1 or c2.
+    fn first_is2(&self, c1: u8, c2: u8) -> bool {
+        if let Some(&c) = self.as_ref().first() { c == c1 || c == c2 } else { false }
+    }
+
+    /// Bounds-checked test if the first character in the slice is a digit.
+    fn first_isdigit(&self) -> bool {
+        if let Some(&c) = self.as_ref().first() { c.is_ascii_digit() } else { false }
+    }
+
+    /// Check if self starts with u with a case-insensitive comparison.
+    fn eq_ignore_case(&self, u: &[u8]) -> bool {
+        debug_assert!(self.as_ref().len() >= u.len());
+        let iter = self.as_ref().iter().zip(u.iter());
+        let d = iter.fold(0, |i, (&x, &y)| i | (x ^ y));
+        d == 0 || d == 32
+    }
+
+    /// Get the remaining slice after the first N elements.
+    fn advance(&self, n: usize) -> &[u8] {
+        &self.as_ref()[n..]
+    }
+
+    /// Get the slice after skipping all leading characters equal c.
+    fn skip_chars(&self, c: u8) -> &[u8] {
+        let mut s = self.as_ref();
+        while s.first_is(c) {
+            s = s.advance(1);
+        }
+        s
+    }
+
+    /// Get the slice after skipping all leading characters equal c1 or c2.
+    fn skip_chars2(&self, c1: u8, c2: u8) -> &[u8] {
+        let mut s = self.as_ref();
+        while s.first_is2(c1, c2) {
+            s = s.advance(1);
+        }
+        s
+    }
+
+    /// Read 8 bytes as a 64-bit integer in little-endian order.
+    unsafe fn read_u64_unchecked(&self) -> u64 {
+        debug_assert!(self.check_len(8));
+        let src = self.as_ref().as_ptr() as *const u64;
+        // SAFETY: safe as long as self is at least 8 bytes
+        u64::from_le(unsafe { ptr::read_unaligned(src) })
+    }
+
+    /// Try to read the next 8 bytes from the slice.
+    fn read_u64(&self) -> Option<u64> {
+        if self.check_len(8) {
+            // SAFETY: self must be at least 8 bytes.
+            Some(unsafe { self.read_u64_unchecked() })
+        } else {
+            None
+        }
+    }
+
+    /// Calculate the offset of slice from another.
+    fn offset_from(&self, other: &Self) -> isize {
+        other.as_ref().len() as isize - self.as_ref().len() as isize
+    }
+}
+
+impl ByteSlice for [u8] {}
+
+/// Helper methods to process mutable bytes.
+pub(crate) trait ByteSliceMut: AsMut<[u8]> {
+    /// Write a 64-bit integer as 8 bytes in little-endian order.
+    unsafe fn write_u64_unchecked(&mut self, value: u64) {
+        debug_assert!(self.as_mut().len() >= 8);
+        let dst = self.as_mut().as_mut_ptr() as *mut u64;
+        // NOTE: we must use `write_unaligned`, since dst is not
+        // guaranteed to be properly aligned. Miri will warn us
+        // if we use `write` instead of `write_unaligned`, as expected.
+        // SAFETY: safe as long as self is at least 8 bytes
+        unsafe {
+            ptr::write_unaligned(dst, u64::to_le(value));
+        }
+    }
+}
+
+impl ByteSliceMut for [u8] {}
+
+/// Bytes wrapper with specialized methods for ASCII characters.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub(crate) struct AsciiStr<'a> {
+    slc: &'a [u8],
+}
+
+impl<'a> AsciiStr<'a> {
+    pub fn new(slc: &'a [u8]) -> Self {
+        Self { slc }
+    }
+
+    /// Advance the view by n, advancing it in-place to (n..).
+    pub unsafe fn step_by(&mut self, n: usize) -> &mut Self {
+        // SAFETY: safe as long n is less than the buffer length
+        self.slc = unsafe { self.slc.get_unchecked(n..) };
+        self
+    }
+
+    /// Advance the view by n, advancing it in-place to (1..).
+    pub unsafe fn step(&mut self) -> &mut Self {
+        // SAFETY: safe as long as self is not empty
+        unsafe { self.step_by(1) }
+    }
+
+    /// Iteratively parse and consume digits from bytes.
+    pub fn parse_digits(&mut self, mut func: impl FnMut(u8)) {
+        while let Some(&c) = self.as_ref().first() {
+            let c = c.wrapping_sub(b'0');
+            if c < 10 {
+                func(c);
+                // SAFETY: self cannot be empty
+                unsafe {
+                    self.step();
+                }
+            } else {
+                break;
+            }
+        }
+    }
+}
+
+impl<'a> AsRef<[u8]> for AsciiStr<'a> {
+    #[inline]
+    fn as_ref(&self) -> &[u8] {
+        self.slc
+    }
+}
+
+impl<'a> ByteSlice for AsciiStr<'a> {}
+
+/// Determine if 8 bytes are all decimal digits.
+/// This does not care about the order in which the bytes were loaded.
+pub(crate) fn is_8digits(v: u64) -> bool {
+    let a = v.wrapping_add(0x4646_4646_4646_4646);
+    let b = v.wrapping_sub(0x3030_3030_3030_3030);
+    (a | b) & 0x8080_8080_8080_8080 == 0
+}
+
+/// Iteratively parse and consume digits from bytes.
+pub(crate) fn parse_digits(s: &mut &[u8], mut f: impl FnMut(u8)) {
+    while let Some(&c) = s.get(0) {
+        let c = c.wrapping_sub(b'0');
+        if c < 10 {
+            f(c);
+            *s = s.advance(1);
+        } else {
+            break;
+        }
+    }
+}
+
+/// A custom 64-bit floating point type, representing `f * 2^e`.
+/// e is biased, so it be directly shifted into the exponent bits.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
+pub struct BiasedFp {
+    /// The significant digits.
+    pub f: u64,
+    /// The biased, binary exponent.
+    pub e: i32,
+}
+
+impl BiasedFp {
+    pub const fn zero_pow2(e: i32) -> Self {
+        Self { f: 0, e }
+    }
+}
diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal.rs
new file mode 100644
index 00000000000..f8edc3625e0
--- /dev/null
+++ b/library/core/src/num/dec2flt/decimal.rs
@@ -0,0 +1,351 @@
+//! Arbitrary-precision decimal class for fallback algorithms.
+//!
+//! This is only used if the fast-path (native floats) and
+//! the Eisel-Lemire algorithm are unable to unambiguously
+//! determine the float.
+//!
+//! The technique used is "Simple Decimal Conversion", developed
+//! by Nigel Tao and Ken Thompson. A detailed description of the
+//! algorithm can be found in "ParseNumberF64 by Simple Decimal Conversion",
+//! available online: <https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html>.
+
+use crate::num::dec2flt::common::{is_8digits, parse_digits, ByteSlice, ByteSliceMut};
+
+#[derive(Clone)]
+pub struct Decimal {
+    /// The number of significant digits in the decimal.
+    pub num_digits: usize,
+    /// The offset of the decimal point in the significant digits.
+    pub decimal_point: i32,
+    /// If the number of significant digits stored in the decimal is truncated.
+    pub truncated: bool,
+    /// Buffer of the raw digits, in the range [0, 9].
+    pub digits: [u8; Self::MAX_DIGITS],
+}
+
+impl Default for Decimal {
+    fn default() -> Self {
+        Self { num_digits: 0, decimal_point: 0, truncated: false, digits: [0; Self::MAX_DIGITS] }
+    }
+}
+
+impl Decimal {
+    /// The maximum number of digits required to unambiguously round a float.
+    ///
+    /// For a double-precision IEEE-754 float, this required 767 digits,
+    /// so we store the max digits + 1.
+    ///
+    /// We can exactly represent a float in radix `b` from radix 2 if
+    /// `b` is divisible by 2. This function calculates the exact number of
+    /// digits required to exactly represent that float.
+    ///
+    /// According to the "Handbook of Floating Point Arithmetic",
+    /// for IEEE754, with emin being the min exponent, p2 being the
+    /// precision, and b being the radix, the number of digits follows as:
+    ///
+    /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
+    ///
+    /// For f32, this follows as:
+    ///     emin = -126
+    ///     p2 = 24
+    ///
+    /// For f64, this follows as:
+    ///     emin = -1022
+    ///     p2 = 53
+    ///
+    /// In Python:
+    ///     `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))`
+    pub const MAX_DIGITS: usize = 768;
+    /// The max digits that can be exactly represented in a 64-bit integer.
+    pub const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19;
+    pub const DECIMAL_POINT_RANGE: i32 = 2047;
+
+    /// Append a digit to the buffer.
+    pub fn try_add_digit(&mut self, digit: u8) {
+        if self.num_digits < Self::MAX_DIGITS {
+            self.digits[self.num_digits] = digit;
+        }
+        self.num_digits += 1;
+    }
+
+    /// Trim trailing zeros from the buffer.
+    pub fn trim(&mut self) {
+        // All of the following calls to `Decimal::trim` can't panic because:
+        //
+        //  1. `parse_decimal` sets `num_digits` to a max of `Decimal::MAX_DIGITS`.
+        //  2. `right_shift` sets `num_digits` to `write_index`, which is bounded by `num_digits`.
+        //  3. `left_shift` `num_digits` to a max of `Decimal::MAX_DIGITS`.
+        //
+        // Trim is only called in `right_shift` and `left_shift`.
+        debug_assert!(self.num_digits <= Self::MAX_DIGITS);
+        while self.num_digits != 0 && self.digits[self.num_digits - 1] == 0 {
+            self.num_digits -= 1;
+        }
+    }
+
+    pub fn round(&self) -> u64 {
+        if self.num_digits == 0 || self.decimal_point < 0 {
+            return 0;
+        } else if self.decimal_point > 18 {
+            return 0xFFFF_FFFF_FFFF_FFFF_u64;
+        }
+        let dp = self.decimal_point as usize;
+        let mut n = 0_u64;
+        for i in 0..dp {
+            n *= 10;
+            if i < self.num_digits {
+                n += self.digits[i] as u64;
+            }
+        }
+        let mut round_up = false;
+        if dp < self.num_digits {
+            round_up = self.digits[dp] >= 5;
+            if self.digits[dp] == 5 && dp + 1 == self.num_digits {
+                round_up = self.truncated || ((dp != 0) && (1 & self.digits[dp - 1] != 0))
+            }
+        }
+        if round_up {
+            n += 1;
+        }
+        n
+    }
+
+    /// Computes decimal * 2^shift.
+    pub fn left_shift(&mut self, shift: usize) {
+        if self.num_digits == 0 {
+            return;
+        }
+        let num_new_digits = number_of_digits_decimal_left_shift(self, shift);
+        let mut read_index = self.num_digits;
+        let mut write_index = self.num_digits + num_new_digits;
+        let mut n = 0_u64;
+        while read_index != 0 {
+            read_index -= 1;
+            write_index -= 1;
+            n += (self.digits[read_index] as u64) << shift;
+            let quotient = n / 10;
+            let remainder = n - (10 * quotient);
+            if write_index < Self::MAX_DIGITS {
+                self.digits[write_index] = remainder as u8;
+            } else if remainder > 0 {
+                self.truncated = true;
+            }
+            n = quotient;
+        }
+        while n > 0 {
+            write_index -= 1;
+            let quotient = n / 10;
+            let remainder = n - (10 * quotient);
+            if write_index < Self::MAX_DIGITS {
+                self.digits[write_index] = remainder as u8;
+            } else if remainder > 0 {
+                self.truncated = true;
+            }
+            n = quotient;
+        }
+        self.num_digits += num_new_digits;
+        if self.num_digits > Self::MAX_DIGITS {
+            self.num_digits = Self::MAX_DIGITS;
+        }
+        self.decimal_point += num_new_digits as i32;
+        self.trim();
+    }
+
+    /// Computes decimal * 2^-shift.
+    pub fn right_shift(&mut self, shift: usize) {
+        let mut read_index = 0;
+        let mut write_index = 0;
+        let mut n = 0_u64;
+        while (n >> shift) == 0 {
+            if read_index < self.num_digits {
+                n = (10 * n) + self.digits[read_index] as u64;
+                read_index += 1;
+            } else if n == 0 {
+                return;
+            } else {
+                while (n >> shift) == 0 {
+                    n *= 10;
+                    read_index += 1;
+                }
+                break;
+            }
+        }
+        self.decimal_point -= read_index as i32 - 1;
+        if self.decimal_point < -Self::DECIMAL_POINT_RANGE {
+            // `self = Self::Default()`, but without the overhead of clearing `digits`.
+            self.num_digits = 0;
+            self.decimal_point = 0;
+            self.truncated = false;
+            return;
+        }
+        let mask = (1_u64 << shift) - 1;
+        while read_index < self.num_digits {
+            let new_digit = (n >> shift) as u8;
+            n = (10 * (n & mask)) + self.digits[read_index] as u64;
+            read_index += 1;
+            self.digits[write_index] = new_digit;
+            write_index += 1;
+        }
+        while n > 0 {
+            let new_digit = (n >> shift) as u8;
+            n = 10 * (n & mask);
+            if write_index < Self::MAX_DIGITS {
+                self.digits[write_index] = new_digit;
+                write_index += 1;
+            } else if new_digit > 0 {
+                self.truncated = true;
+            }
+        }
+        self.num_digits = write_index;
+        self.trim();
+    }
+}
+
+/// Parse a big integer representation of the float as a decimal.
+pub fn parse_decimal(mut s: &[u8]) -> Decimal {
+    let mut d = Decimal::default();
+    let start = s;
+    s = s.skip_chars(b'0');
+    parse_digits(&mut s, |digit| d.try_add_digit(digit));
+    if s.first_is(b'.') {
+        s = s.advance(1);
+        let first = s;
+        // Skip leading zeros.
+        if d.num_digits == 0 {
+            s = s.skip_chars(b'0');
+        }
+        while s.len() >= 8 && d.num_digits + 8 < Decimal::MAX_DIGITS {
+            // SAFETY: s is at least 8 bytes.
+            let v = unsafe { s.read_u64_unchecked() };
+            if !is_8digits(v) {
+                break;
+            }
+            // SAFETY: d.num_digits + 8 is less than d.digits.len()
+            unsafe {
+                d.digits[d.num_digits..].write_u64_unchecked(v - 0x3030_3030_3030_3030);
+            }
+            d.num_digits += 8;
+            s = s.advance(8);
+        }
+        parse_digits(&mut s, |digit| d.try_add_digit(digit));
+        d.decimal_point = s.len() as i32 - first.len() as i32;
+    }
+    if d.num_digits != 0 {
+        // Ignore the trailing zeros if there are any
+        let mut n_trailing_zeros = 0;
+        for &c in start[..(start.len() - s.len())].iter().rev() {
+            if c == b'0' {
+                n_trailing_zeros += 1;
+            } else if c != b'.' {
+                break;
+            }
+        }
+        d.decimal_point += n_trailing_zeros as i32;
+        d.num_digits -= n_trailing_zeros;
+        d.decimal_point += d.num_digits as i32;
+        if d.num_digits > Decimal::MAX_DIGITS {
+            d.truncated = true;
+            d.num_digits = Decimal::MAX_DIGITS;
+        }
+    }
+    if s.first_is2(b'e', b'E') {
+        s = s.advance(1);
+        let mut neg_exp = false;
+        if s.first_is(b'-') {
+            neg_exp = true;
+            s = s.advance(1);
+        } else if s.first_is(b'+') {
+            s = s.advance(1);
+        }
+        let mut exp_num = 0_i32;
+        parse_digits(&mut s, |digit| {
+            if exp_num < 0x10000 {
+                exp_num = 10 * exp_num + digit as i32;
+            }
+        });
+        d.decimal_point += if neg_exp { -exp_num } else { exp_num };
+    }
+    for i in d.num_digits..Decimal::MAX_DIGITS_WITHOUT_OVERFLOW {
+        d.digits[i] = 0;
+    }
+    d
+}
+
+fn number_of_digits_decimal_left_shift(d: &Decimal, mut shift: usize) -> usize {
+    #[rustfmt::skip]
+    const TABLE: [u16; 65] = [
+        0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, 0x181D, 0x2024,
+        0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, 0x3073, 0x3080, 0x388E, 0x389C,
+        0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169,
+        0x5180, 0x5998, 0x59B0, 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B,
+        0x72AA, 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, 0x8C02,
+        0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, 0x051C, 0x051C,
+    ];
+    #[rustfmt::skip]
+    const TABLE_POW5: [u8; 0x051C] = [
+        5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9, 0, 6, 2, 5, 1,
+        9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2, 5, 2, 4, 4, 1, 4, 0, 6, 2, 5,
+        1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5, 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2,
+        5, 1, 5, 2, 5, 8, 7, 8, 9, 0, 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6,
+        9, 7, 2, 6, 5, 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1,
+        6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, 1, 8, 5, 7, 9,
+        1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, 8, 1, 2, 5, 5, 9, 6, 0, 4, 6,
+        4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1,
+        4, 9, 0, 1, 1, 6, 1, 1, 9, 3, 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2,
+        3, 8, 2, 8, 1, 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6,
+        2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, 7, 4, 6, 1, 5,
+        4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, 7, 7, 3, 9, 2, 5, 7, 8, 1, 2,
+        5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5,
+        3, 2, 1, 8, 2, 6, 9, 3, 4, 8, 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4,
+        6, 7, 4, 0, 7, 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6,
+        1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, 0, 6, 6, 4, 0,
+        6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, 0, 3, 3, 2, 0, 3, 1, 2, 5, 3,
+        6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8,
+        9, 8, 9, 4, 0, 3, 5, 4, 5, 8, 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4,
+        7, 0, 1, 7, 7, 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5,
+        0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3, 7, 3, 6, 7, 5,
+        4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2, 5, 1, 1, 3, 6, 8, 6, 8, 3, 7,
+        7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9, 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8,
+        8, 6, 0, 8, 0, 8, 0, 1, 4, 8, 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0,
+        9, 4, 3, 0, 4, 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0,
+        8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, 6, 2, 5, 7, 1,
+        0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, 2, 4, 2, 6, 7, 5, 7, 8, 1, 2,
+        5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8,
+        9, 0, 6, 2, 5, 1, 7, 7, 6, 3, 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0,
+        6, 6, 8, 9, 4, 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3,
+        8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, 5, 0, 0, 6, 2,
+        6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, 5, 2, 2, 2, 0, 4, 4, 6, 0, 4,
+        9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1,
+        1, 0, 2, 2, 3, 0, 2, 4, 6, 2, 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8,
+        2, 0, 3, 1, 2, 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5,
+        8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, 6, 2, 8, 9, 1,
+        3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, 1, 2, 5, 1, 3, 8, 7, 7, 7, 8,
+        7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0,
+        6, 2, 5, 6, 9, 3, 8, 8, 9, 3, 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2,
+        5, 5, 6, 7, 6, 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1,
+        8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1, 7, 3, 4, 7, 2,
+        3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4, 8, 1, 3, 9, 1, 9, 0, 6, 7, 3,
+        8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2,
+        2, 4, 0, 6, 9, 5, 9, 5, 3, 3, 6, 9, 1, 4, 0, 6, 2, 5,
+    ];
+
+    shift &= 63;
+    let x_a = TABLE[shift];
+    let x_b = TABLE[shift + 1];
+    let num_new_digits = (x_a >> 11) as _;
+    let pow5_a = (0x7FF & x_a) as usize;
+    let pow5_b = (0x7FF & x_b) as usize;
+    let pow5 = &TABLE_POW5[pow5_a..];
+    for (i, &p5) in pow5.iter().enumerate().take(pow5_b - pow5_a) {
+        if i >= d.num_digits {
+            return num_new_digits - 1;
+        } else if d.digits[i] == p5 {
+            continue;
+        } else if d.digits[i] < p5 {
+            return num_new_digits - 1;
+        } else {
+            return num_new_digits;
+        }
+    }
+    num_new_digits
+}
diff --git a/library/core/src/num/dec2flt/float.rs b/library/core/src/num/dec2flt/float.rs
new file mode 100644
index 00000000000..5921c5ed472
--- /dev/null
+++ b/library/core/src/num/dec2flt/float.rs
@@ -0,0 +1,207 @@
+//! Helper trait for generic float types.
+
+use crate::fmt::{Debug, LowerExp};
+use crate::num::FpCategory;
+use crate::ops::{Add, Div, Mul, Neg};
+
+/// A helper trait to avoid duplicating basically all the conversion code for `f32` and `f64`.
+///
+/// See the parent module's doc comment for why this is necessary.
+///
+/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
+#[doc(hidden)]
+pub trait RawFloat:
+    Sized
+    + Div<Output = Self>
+    + Neg<Output = Self>
+    + Mul<Output = Self>
+    + Add<Output = Self>
+    + LowerExp
+    + PartialEq
+    + PartialOrd
+    + Default
+    + Clone
+    + Copy
+    + Debug
+{
+    const INFINITY: Self;
+    const NEG_INFINITY: Self;
+    const NAN: Self;
+    const NEG_NAN: Self;
+
+    /// The number of bits in the significand, *excluding* the hidden bit.
+    const MANTISSA_EXPLICIT_BITS: usize;
+
+    // Round-to-even only happens for negative values of q
+    // when q ≥ −4 in the 64-bit case and when q ≥ −17 in
+    // the 32-bitcase.
+    //
+    // When q ≥ 0,we have that 5^q ≤ 2m+1. In the 64-bit case,we
+    // have 5^q ≤ 2m+1 ≤ 2^54 or q ≤ 23. In the 32-bit case,we have
+    // 5^q ≤ 2m+1 ≤ 2^25 or q ≤ 10.
+    //
+    // When q < 0, we have w ≥ (2m+1)×5^−q. We must have that w < 2^64
+    // so (2m+1)×5^−q < 2^64. We have that 2m+1 > 2^53 (64-bit case)
+    // or 2m+1 > 2^24 (32-bit case). Hence,we must have 2^53×5^−q < 2^64
+    // (64-bit) and 2^24×5^−q < 2^64 (32-bit). Hence we have 5^−q < 2^11
+    // or q ≥ −4 (64-bit case) and 5^−q < 2^40 or q ≥ −17 (32-bitcase).
+    //
+    // Thus we have that we only need to round ties to even when
+    // we have that q ∈ [−4,23](in the 64-bit case) or q∈[−17,10]
+    // (in the 32-bit case). In both cases,the power of five(5^|q|)
+    // fits in a 64-bit word.
+    const MIN_EXPONENT_ROUND_TO_EVEN: i32;
+    const MAX_EXPONENT_ROUND_TO_EVEN: i32;
+
+    // Minimum exponent that for a fast path case, or `-⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋`
+    const MIN_EXPONENT_FAST_PATH: i64;
+
+    // Maximum exponent that for a fast path case, or `⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋`
+    const MAX_EXPONENT_FAST_PATH: i64;
+
+    // Maximum exponent that can be represented for a disguised-fast path case.
+    // This is `MAX_EXPONENT_FAST_PATH + ⌊(MANTISSA_EXPLICIT_BITS+1)/log2(10)⌋`
+    const MAX_EXPONENT_DISGUISED_FAST_PATH: i64;
+
+    // Minimum exponent value `-(1 << (EXP_BITS - 1)) + 1`.
+    const MINIMUM_EXPONENT: i32;
+
+    // Largest exponent value `(1 << EXP_BITS) - 1`.
+    const INFINITE_POWER: i32;
+
+    // Index (in bits) of the sign.
+    const SIGN_INDEX: usize;
+
+    // Smallest decimal exponent for a non-zero value.
+    const SMALLEST_POWER_OF_TEN: i32;
+
+    // Largest decimal exponent for a non-infinite value.
+    const LARGEST_POWER_OF_TEN: i32;
+
+    // Maximum mantissa for the fast-path (`1 << 53` for f64).
+    const MAX_MANTISSA_FAST_PATH: u64 = 2_u64 << Self::MANTISSA_EXPLICIT_BITS;
+
+    /// Convert integer into float through an as cast.
+    /// This is only called in the fast-path algorithm, and therefore
+    /// will not lose precision, since the value will always have
+    /// only if the value is <= Self::MAX_MANTISSA_FAST_PATH.
+    fn from_u64(v: u64) -> Self;
+
+    /// Performs a raw transmutation from an integer.
+    fn from_u64_bits(v: u64) -> Self;
+
+    /// Get a small power-of-ten for fast-path multiplication.
+    fn pow10_fast_path(exponent: usize) -> Self;
+
+    /// Returns the category that this number falls into.
+    fn classify(self) -> FpCategory;
+
+    /// Returns the mantissa, exponent and sign as integers.
+    fn integer_decode(self) -> (u64, i16, i8);
+}
+
+impl RawFloat for f32 {
+    const INFINITY: Self = f32::INFINITY;
+    const NEG_INFINITY: Self = f32::NEG_INFINITY;
+    const NAN: Self = f32::NAN;
+    const NEG_NAN: Self = -f32::NAN;
+
+    const MANTISSA_EXPLICIT_BITS: usize = 23;
+    const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
+    const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
+    const MIN_EXPONENT_FAST_PATH: i64 = -10; // assuming FLT_EVAL_METHOD = 0
+    const MAX_EXPONENT_FAST_PATH: i64 = 10;
+    const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 17;
+    const MINIMUM_EXPONENT: i32 = -127;
+    const INFINITE_POWER: i32 = 0xFF;
+    const SIGN_INDEX: usize = 31;
+    const SMALLEST_POWER_OF_TEN: i32 = -65;
+    const LARGEST_POWER_OF_TEN: i32 = 38;
+
+    fn from_u64(v: u64) -> Self {
+        debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH);
+        v as _
+    }
+
+    fn from_u64_bits(v: u64) -> Self {
+        f32::from_bits((v & 0xFFFFFFFF) as u32)
+    }
+
+    fn pow10_fast_path(exponent: usize) -> Self {
+        #[allow(clippy::use_self)]
+        const TABLE: [f32; 16] =
+            [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 0., 0., 0., 0., 0.];
+        TABLE[exponent & 15]
+    }
+
+    /// Returns the mantissa, exponent and sign as integers.
+    fn integer_decode(self) -> (u64, i16, i8) {
+        let bits = self.to_bits();
+        let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
+        let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
+        let mantissa =
+            if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 };
+        // Exponent bias + mantissa shift
+        exponent -= 127 + 23;
+        (mantissa as u64, exponent, sign)
+    }
+
+    fn classify(self) -> FpCategory {
+        self.classify()
+    }
+}
+
+impl RawFloat for f64 {
+    const INFINITY: Self = f64::INFINITY;
+    const NEG_INFINITY: Self = f64::NEG_INFINITY;
+    const NAN: Self = f64::NAN;
+    const NEG_NAN: Self = -f64::NAN;
+
+    const MANTISSA_EXPLICIT_BITS: usize = 52;
+    const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4;
+    const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23;
+    const MIN_EXPONENT_FAST_PATH: i64 = -22; // assuming FLT_EVAL_METHOD = 0
+    const MAX_EXPONENT_FAST_PATH: i64 = 22;
+    const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 37;
+    const MINIMUM_EXPONENT: i32 = -1023;
+    const INFINITE_POWER: i32 = 0x7FF;
+    const SIGN_INDEX: usize = 63;
+    const SMALLEST_POWER_OF_TEN: i32 = -342;
+    const LARGEST_POWER_OF_TEN: i32 = 308;
+
+    fn from_u64(v: u64) -> Self {
+        debug_assert!(v <= Self::MAX_MANTISSA_FAST_PATH);
+        v as _
+    }
+
+    fn from_u64_bits(v: u64) -> Self {
+        f64::from_bits(v)
+    }
+
+    fn pow10_fast_path(exponent: usize) -> Self {
+        const TABLE: [f64; 32] = [
+            1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
+            1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 0., 0., 0., 0., 0., 0., 0., 0., 0.,
+        ];
+        TABLE[exponent & 31]
+    }
+
+    /// Returns the mantissa, exponent and sign as integers.
+    fn integer_decode(self) -> (u64, i16, i8) {
+        let bits = self.to_bits();
+        let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
+        let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
+        let mantissa = if exponent == 0 {
+            (bits & 0xfffffffffffff) << 1
+        } else {
+            (bits & 0xfffffffffffff) | 0x10000000000000
+        };
+        // Exponent bias + mantissa shift
+        exponent -= 1023 + 52;
+        (mantissa, exponent, sign)
+    }
+
+    fn classify(self) -> FpCategory {
+        self.classify()
+    }
+}
diff --git a/library/core/src/num/dec2flt/fpu.rs b/library/core/src/num/dec2flt/fpu.rs
new file mode 100644
index 00000000000..24492d9a1dd
--- /dev/null
+++ b/library/core/src/num/dec2flt/fpu.rs
@@ -0,0 +1,89 @@
+//! Platform-specific, assembly instructions to avoid
+//! intermediate rounding on architectures with FPUs.
+
+pub use fpu_precision::set_precision;
+
+// On x86, the x87 FPU is used for float operations if the SSE/SSE2 extensions are not available.
+// The x87 FPU operates with 80 bits of precision by default, which means that operations will
+// round to 80 bits causing double rounding to happen when values are eventually represented as
+// 32/64 bit float values. To overcome this, the FPU control word can be set so that the
+// computations are performed in the desired precision.
+#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
+mod fpu_precision {
+    use core::mem::size_of;
+
+    /// A structure used to preserve the original value of the FPU control word, so that it can be
+    /// restored when the structure is dropped.
+    ///
+    /// The x87 FPU is a 16-bits register whose fields are as follows:
+    ///
+    /// | 12-15 | 10-11 | 8-9 | 6-7 |  5 |  4 |  3 |  2 |  1 |  0 |
+    /// |------:|------:|----:|----:|---:|---:|---:|---:|---:|---:|
+    /// |       | RC    | PC  |     | PM | UM | OM | ZM | DM | IM |
+    ///
+    /// The documentation for all of the fields is available in the IA-32 Architectures Software
+    /// Developer's Manual (Volume 1).
+    ///
+    /// The only field which is relevant for the following code is PC, Precision Control. This
+    /// field determines the precision of the operations performed by the  FPU. It can be set to:
+    ///  - 0b00, single precision i.e., 32-bits
+    ///  - 0b10, double precision i.e., 64-bits
+    ///  - 0b11, double extended precision i.e., 80-bits (default state)
+    /// The 0b01 value is reserved and should not be used.
+    pub struct FPUControlWord(u16);
+
+    fn set_cw(cw: u16) {
+        // SAFETY: the `fldcw` instruction has been audited to be able to work correctly with
+        // any `u16`
+        unsafe {
+            asm!(
+                "fldcw word ptr [{}]",
+                in(reg) &cw,
+                options(nostack),
+            )
+        }
+    }
+
+    /// Sets the precision field of the FPU to `T` and returns a `FPUControlWord`.
+    pub fn set_precision<T>() -> FPUControlWord {
+        let mut cw = 0_u16;
+
+        // Compute the value for the Precision Control field that is appropriate for `T`.
+        let cw_precision = match size_of::<T>() {
+            4 => 0x0000, // 32 bits
+            8 => 0x0200, // 64 bits
+            _ => 0x0300, // default, 80 bits
+        };
+
+        // Get the original value of the control word to restore it later, when the
+        // `FPUControlWord` structure is dropped
+        // SAFETY: the `fnstcw` instruction has been audited to be able to work correctly with
+        // any `u16`
+        unsafe {
+            asm!(
+                "fnstcw word ptr [{}]",
+                in(reg) &mut cw,
+                options(nostack),
+            )
+        }
+
+        // Set the control word to the desired precision. This is achieved by masking away the old
+        // precision (bits 8 and 9, 0x300) and replacing it with the precision flag computed above.
+        set_cw((cw & 0xFCFF) | cw_precision);
+
+        FPUControlWord(cw)
+    }
+
+    impl Drop for FPUControlWord {
+        fn drop(&mut self) {
+            set_cw(self.0)
+        }
+    }
+}
+
+// In most architectures, floating point operations have an explicit bit size, therefore the
+// precision of the computation is determined on a per-operation basis.
+#[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))]
+mod fpu_precision {
+    pub fn set_precision<T>() {}
+}
diff --git a/library/core/src/num/dec2flt/lemire.rs b/library/core/src/num/dec2flt/lemire.rs
new file mode 100644
index 00000000000..9b7efc3d556
--- /dev/null
+++ b/library/core/src/num/dec2flt/lemire.rs
@@ -0,0 +1,166 @@
+//! Implementation of the Eisel-Lemire algorithm.
+
+use crate::num::dec2flt::common::BiasedFp;
+use crate::num::dec2flt::float::RawFloat;
+use crate::num::dec2flt::table::{
+    LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE,
+};
+
+/// Compute a float using an extended-precision representation.
+///
+/// Fast conversion of a the significant digits and decimal exponent
+/// a float to a extended representation with a binary float. This
+/// algorithm will accurately parse the vast majority of cases,
+/// and uses a 128-bit representation (with a fallback 192-bit
+/// representation).
+///
+/// This algorithm scales the exponent by the decimal exponent
+/// using pre-computed powers-of-5, and calculates if the
+/// representation can be unambiguously rounded to the nearest
+/// machine float. Near-halfway cases are not handled here,
+/// and are represented by a negative, biased binary exponent.
+///
+/// The algorithm is described in detail in "Daniel Lemire, Number Parsing
+/// at a Gigabyte per Second" in section 5, "Fast Algorithm", and
+/// section 6, "Exact Numbers And Ties", available online:
+/// <https://arxiv.org/abs/2101.11408.pdf>.
+pub fn compute_float<F: RawFloat>(q: i64, mut w: u64) -> BiasedFp {
+    let fp_zero = BiasedFp::zero_pow2(0);
+    let fp_inf = BiasedFp::zero_pow2(F::INFINITE_POWER);
+    let fp_error = BiasedFp::zero_pow2(-1);
+
+    // Short-circuit if the value can only be a literal 0 or infinity.
+    if w == 0 || q < F::SMALLEST_POWER_OF_TEN as i64 {
+        return fp_zero;
+    } else if q > F::LARGEST_POWER_OF_TEN as i64 {
+        return fp_inf;
+    }
+    // Normalize our significant digits, so the most-significant bit is set.
+    let lz = w.leading_zeros();
+    w <<= lz;
+    let (lo, hi) = compute_product_approx(q, w, F::MANTISSA_EXPLICIT_BITS + 3);
+    if lo == 0xFFFF_FFFF_FFFF_FFFF {
+        // If we have failed to approximate w x 5^-q with our 128-bit value.
+        // Since the addition of 1 could lead to an overflow which could then
+        // round up over the half-way point, this can lead to improper rounding
+        // of a float.
+        //
+        // However, this can only occur if q ∈ [-27, 55]. The upper bound of q
+        // is 55 because 5^55 < 2^128, however, this can only happen if 5^q > 2^64,
+        // since otherwise the product can be represented in 64-bits, producing
+        // an exact result. For negative exponents, rounding-to-even can
+        // only occur if 5^-q < 2^64.
+        //
+        // For detailed explanations of rounding for negative exponents, see
+        // <https://arxiv.org/pdf/2101.11408.pdf#section.9.1>. For detailed
+        // explanations of rounding for positive exponents, see
+        // <https://arxiv.org/pdf/2101.11408.pdf#section.8>.
+        let inside_safe_exponent = (q >= -27) && (q <= 55);
+        if !inside_safe_exponent {
+            return fp_error;
+        }
+    }
+    let upperbit = (hi >> 63) as i32;
+    let mut mantissa = hi >> (upperbit + 64 - F::MANTISSA_EXPLICIT_BITS as i32 - 3);
+    let mut power2 = power(q as i32) + upperbit - lz as i32 - F::MINIMUM_EXPONENT;
+    if power2 <= 0 {
+        if -power2 + 1 >= 64 {
+            // Have more than 64 bits below the minimum exponent, must be 0.
+            return fp_zero;
+        }
+        // Have a subnormal value.
+        mantissa >>= -power2 + 1;
+        mantissa += mantissa & 1;
+        mantissa >>= 1;
+        power2 = (mantissa >= (1_u64 << F::MANTISSA_EXPLICIT_BITS)) as i32;
+        return BiasedFp { f: mantissa, e: power2 };
+    }
+    // Need to handle rounding ties. Normally, we need to round up,
+    // but if we fall right in between and and we have an even basis, we
+    // need to round down.
+    //
+    // This will only occur if:
+    //  1. The lower 64 bits of the 128-bit representation is 0.
+    //      IE, 5^q fits in single 64-bit word.
+    //  2. The least-significant bit prior to truncated mantissa is odd.
+    //  3. All the bits truncated when shifting to mantissa bits + 1 are 0.
+    //
+    // Or, we may fall between two floats: we are exactly halfway.
+    if lo <= 1
+        && q >= F::MIN_EXPONENT_ROUND_TO_EVEN as i64
+        && q <= F::MAX_EXPONENT_ROUND_TO_EVEN as i64
+        && mantissa & 3 == 1
+        && (mantissa << (upperbit + 64 - F::MANTISSA_EXPLICIT_BITS as i32 - 3)) == hi
+    {
+        // Zero the lowest bit, so we don't round up.
+        mantissa &= !1_u64;
+    }
+    // Round-to-even, then shift the significant digits into place.
+    mantissa += mantissa & 1;
+    mantissa >>= 1;
+    if mantissa >= (2_u64 << F::MANTISSA_EXPLICIT_BITS) {
+        // Rounding up overflowed, so the carry bit is set. Set the
+        // mantissa to 1 (only the implicit, hidden bit is set) and
+        // increase the exponent.
+        mantissa = 1_u64 << F::MANTISSA_EXPLICIT_BITS;
+        power2 += 1;
+    }
+    // Zero out the hidden bit.
+    mantissa &= !(1_u64 << F::MANTISSA_EXPLICIT_BITS);
+    if power2 >= F::INFINITE_POWER {
+        // Exponent is above largest normal value, must be infinite.
+        return fp_inf;
+    }
+    BiasedFp { f: mantissa, e: power2 }
+}
+
+/// Calculate a base 2 exponent from a decimal exponent.
+/// This uses a pre-computed integer approximation for
+/// log2(10), where 217706 / 2^16 is accurate for the
+/// entire range of non-finite decimal exponents.
+fn power(q: i32) -> i32 {
+    (q.wrapping_mul(152_170 + 65536) >> 16) + 63
+}
+
+fn full_multiplication(a: u64, b: u64) -> (u64, u64) {
+    let r = (a as u128) * (b as u128);
+    (r as u64, (r >> 64) as u64)
+}
+
+// This will compute or rather approximate w * 5**q and return a pair of 64-bit words
+// approximating the result, with the "high" part corresponding to the most significant
+// bits and the low part corresponding to the least significant bits.
+fn compute_product_approx(q: i64, w: u64, precision: usize) -> (u64, u64) {
+    debug_assert!(q >= SMALLEST_POWER_OF_FIVE as i64);
+    debug_assert!(q <= LARGEST_POWER_OF_FIVE as i64);
+    debug_assert!(precision <= 64);
+
+    let mask = if precision < 64 {
+        0xFFFF_FFFF_FFFF_FFFF_u64 >> precision
+    } else {
+        0xFFFF_FFFF_FFFF_FFFF_u64
+    };
+
+    // 5^q < 2^64, then the multiplication always provides an exact value.
+    // That means whenever we need to round ties to even, we always have
+    // an exact value.
+    let index = (q - SMALLEST_POWER_OF_FIVE as i64) as usize;
+    let (lo5, hi5) = POWER_OF_FIVE_128[index];
+    // Only need one multiplication as long as there is 1 zero but
+    // in the explicit mantissa bits, +1 for the hidden bit, +1 to
+    // determine the rounding direction, +1 for if the computed
+    // product has a leading zero.
+    let (mut first_lo, mut first_hi) = full_multiplication(w, lo5);
+    if first_hi & mask == mask {
+        // Need to do a second multiplication to get better precision
+        // for the lower product. This will always be exact
+        // where q is < 55, since 5^55 < 2^128. If this wraps,
+        // then we need to need to round up the hi product.
+        let (_, second_hi) = full_multiplication(w, hi5);
+        first_lo = first_lo.wrapping_add(second_hi);
+        if second_hi > first_lo {
+            first_hi += 1;
+        }
+    }
+    (first_lo, first_hi)
+}
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index f008a64ffe6..c78492f5ae2 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -27,20 +27,12 @@
 //!
 //! We then try a long chain of progressively more general and expensive special cases using
 //! machine-sized integers and small, fixed-sized floating point numbers (first `f32`/`f64`, then
-//! a type with 64 bit significand, `Fp`). When all these fail, we bite the bullet and resort to a
-//! simple but very slow algorithm that involved computing `f * 10^e` fully and doing an iterative
-//! search for the best approximation.
-//!
-//! Primarily, this module and its children implement the algorithms described in:
-//! "How to Read Floating Point Numbers Accurately" by William D. Clinger,
-//! available online: <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.4152>
-//!
-//! In addition, there are numerous helper functions that are used in the paper but not available
-//! in Rust (or at least in core). Our version is additionally complicated by the need to handle
-//! overflow and underflow and the desire to handle subnormal numbers. Bellerophon and
-//! Algorithm R have trouble with overflow, subnormals, and underflow. We conservatively switch to
-//! Algorithm M (with the modifications described in section 8 of the paper) well before the
-//! inputs get into the critical region.
+//! a type with 64 bit significand). The extended-precision algorithm
+//! uses the Eisel-Lemire algorithm, which uses a 128-bit (or 192-bit)
+//! representation that can accurately and quickly compute the vast majority
+//! of floats. When all these fail, we bite the bullet and resort to using
+//! a large-decimal representation, shifting the digits into range, calculating
+//! the upper significant bits and exactly round to the nearest representation.
 //!
 //! Another aspect that needs attention is the ``RawFloat`` trait by which almost all functions
 //! are parametrized. One might think that it's enough to parse to `f64` and cast the result to
@@ -54,10 +46,9 @@
 //! operations as well, if you want 0.5 ULP accuracy you need to do *everything* in full precision
 //! and round *exactly once, at the end*, by considering all truncated bits at once.
 //!
-//! FIXME: Although some code duplication is necessary, perhaps parts of the code could be shuffled
-//! around such that less code is duplicated. Large parts of the algorithms are independent of the
-//! float type to output, or only needs access to a few constants, which could be passed in as
-//! parameters.
+//! Primarily, this module and its children implement the algorithms described in:
+//! "Number Parsing at a Gigabyte per Second", available online:
+//! <https://arxiv.org/abs/2101.11408>.
 //!
 //! # Other
 //!
@@ -87,16 +78,22 @@
 use crate::fmt;
 use crate::str::FromStr;
 
-use self::num::digits_to_big;
-use self::parse::{parse_decimal, Decimal, ParseResult, Sign};
-use self::rawfp::RawFloat;
+use self::common::{BiasedFp, ByteSlice};
+use self::float::RawFloat;
+use self::lemire::compute_float;
+use self::parse::{parse_inf_nan, parse_number};
+use self::slow::parse_long_mantissa;
 
-mod algorithm;
-mod num;
+mod common;
+mod decimal;
+mod fpu;
+mod slow;
 mod table;
-// These two have their own tests.
+// float is used in flt2dec, and all are used in unit tests.
+pub mod float;
+pub mod lemire;
+pub mod number;
 pub mod parse;
-pub mod rawfp;
 
 macro_rules! from_str_float_impl {
     ($t:ty) => {
@@ -136,13 +133,6 @@ macro_rules! from_str_float_impl {
             ///
             /// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation
             ///
-            /// # Known bugs
-            ///
-            /// In some situations, some strings that should create a valid float
-            /// instead return an error. See [issue #31407] for details.
-            ///
-            /// [issue #31407]: https://github.com/rust-lang/rust/issues/31407
-            ///
             /// # Arguments
             ///
             /// * src - A string
@@ -211,148 +201,70 @@ impl fmt::Display for ParseFloatError {
     }
 }
 
-fn pfe_empty() -> ParseFloatError {
+pub(super) fn pfe_empty() -> ParseFloatError {
     ParseFloatError { kind: FloatErrorKind::Empty }
 }
 
-fn pfe_invalid() -> ParseFloatError {
+// Used in unit tests, keep public.
+// This is much better than making FloatErrorKind and ParseFloatError::kind public.
+pub fn pfe_invalid() -> ParseFloatError {
     ParseFloatError { kind: FloatErrorKind::Invalid }
 }
 
-/// Splits a decimal string into sign and the rest, without inspecting or validating the rest.
-fn extract_sign(s: &str) -> (Sign, &str) {
-    match s.as_bytes()[0] {
-        b'+' => (Sign::Positive, &s[1..]),
-        b'-' => (Sign::Negative, &s[1..]),
-        // If the string is invalid, we never use the sign, so we don't need to validate here.
-        _ => (Sign::Positive, s),
-    }
+/// Converts a `BiasedFp` to the closest machine float type.
+fn biased_fp_to_float<T: RawFloat>(x: BiasedFp) -> T {
+    let mut word = x.f;
+    word |= (x.e as u64) << T::MANTISSA_EXPLICIT_BITS;
+    T::from_u64_bits(word)
 }
 
 /// Converts a decimal string into a floating point number.
-fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
-    if s.is_empty() {
+pub fn dec2flt<F: RawFloat>(s: &str) -> Result<F, ParseFloatError> {
+    let mut s = s.as_bytes();
+    let c = if let Some(&c) = s.first() {
+        c
+    } else {
         return Err(pfe_empty());
+    };
+    let negative = c == b'-';
+    if c == b'-' || c == b'+' {
+        s = s.advance(1);
+    }
+    if s.is_empty() {
+        return Err(pfe_invalid());
     }
-    let (sign, s) = extract_sign(s);
-    let flt = match parse_decimal(s) {
-        ParseResult::Valid(decimal) => convert(decimal)?,
-        ParseResult::ShortcutToInf => T::INFINITY,
-        ParseResult::ShortcutToZero => T::ZERO,
-        ParseResult::Invalid => {
-            if s.eq_ignore_ascii_case("nan") {
-                T::NAN
-            } else if s.eq_ignore_ascii_case("inf") || s.eq_ignore_ascii_case("infinity") {
-                T::INFINITY
+
+    let num = match parse_number(s, negative) {
+        Some(r) => r,
+        None => {
+            if let Some(value) = parse_inf_nan(s, negative) {
+                return Ok(value);
             } else {
                 return Err(pfe_invalid());
             }
         }
     };
-
-    match sign {
-        Sign::Positive => Ok(flt),
-        Sign::Negative => Ok(-flt),
+    if let Some(value) = num.try_fast_path::<F>() {
+        return Ok(value);
     }
-}
-
-/// The main workhorse for the decimal-to-float conversion: Orchestrate all the preprocessing
-/// and figure out which algorithm should do the actual conversion.
-fn convert<T: RawFloat>(mut decimal: Decimal<'_>) -> Result<T, ParseFloatError> {
-    simplify(&mut decimal);
-    if let Some(x) = trivial_cases(&decimal) {
-        return Ok(x);
-    }
-    // Remove/shift out the decimal point.
-    let e = decimal.exp - decimal.fractional.len() as i64;
-    if let Some(x) = algorithm::fast_path(decimal.integral, decimal.fractional, e) {
-        return Ok(x);
-    }
-    // Big32x40 is limited to 1280 bits, which translates to about 385 decimal digits.
-    // If we exceed this, we'll crash, so we error out before getting too close (within 10^10).
-    let upper_bound = bound_intermediate_digits(&decimal, e);
-    if upper_bound > 375 {
-        return Err(pfe_invalid());
-    }
-    let f = digits_to_big(decimal.integral, decimal.fractional);
-
-    // Now the exponent certainly fits in 16 bit, which is used throughout the main algorithms.
-    let e = e as i16;
-    // FIXME These bounds are rather conservative. A more careful analysis of the failure modes
-    // of Bellerophon could allow using it in more cases for a massive speed up.
-    let exponent_in_range = table::MIN_E <= e && e <= table::MAX_E;
-    let value_in_range = upper_bound <= T::MAX_NORMAL_DIGITS as u64;
-    if exponent_in_range && value_in_range {
-        Ok(algorithm::bellerophon(&f, e))
-    } else {
-        Ok(algorithm::algorithm_m(&f, e))
-    }
-}
 
-// As written, this optimizes badly (see #27130, though it refers to an old version of the code).
-// `inline(always)` is a workaround for that. There are only two call sites overall and it doesn't
-// make code size worse.
-
-/// Strip zeros where possible, even when this requires changing the exponent
-#[inline(always)]
-fn simplify(decimal: &mut Decimal<'_>) {
-    let is_zero = &|&&d: &&u8| -> bool { d == b'0' };
-    // Trimming these zeros does not change anything but may enable the fast path (< 15 digits).
-    let leading_zeros = decimal.integral.iter().take_while(is_zero).count();
-    decimal.integral = &decimal.integral[leading_zeros..];
-    let trailing_zeros = decimal.fractional.iter().rev().take_while(is_zero).count();
-    let end = decimal.fractional.len() - trailing_zeros;
-    decimal.fractional = &decimal.fractional[..end];
-    // Simplify numbers of the form 0.0...x and x...0.0, adjusting the exponent accordingly.
-    // This may not always be a win (possibly pushes some numbers out of the fast path), but it
-    // simplifies other parts significantly (notably, approximating the magnitude of the value).
-    if decimal.integral.is_empty() {
-        let leading_zeros = decimal.fractional.iter().take_while(is_zero).count();
-        decimal.fractional = &decimal.fractional[leading_zeros..];
-        decimal.exp -= leading_zeros as i64;
-    } else if decimal.fractional.is_empty() {
-        let trailing_zeros = decimal.integral.iter().rev().take_while(is_zero).count();
-        let end = decimal.integral.len() - trailing_zeros;
-        decimal.integral = &decimal.integral[..end];
-        decimal.exp += trailing_zeros as i64;
+    // If significant digits were truncated, then we can have rounding error
+    // only if `mantissa + 1` produces a different result. We also avoid
+    // redundantly using the Eisel-Lemire algorithm if it was unable to
+    // correctly round on the first pass.
+    let mut fp = compute_float::<F>(num.exponent, num.mantissa);
+    if num.many_digits && fp.e >= 0 && fp != compute_float::<F>(num.exponent, num.mantissa + 1) {
+        fp.e = -1;
     }
-}
-
-/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R
-/// and Algorithm M will compute while working on the given decimal.
-fn bound_intermediate_digits(decimal: &Decimal<'_>, e: i64) -> u64 {
-    // We don't need to worry too much about overflow here thanks to trivial_cases() and the
-    // parser, which filter out the most extreme inputs for us.
-    let f_len: u64 = decimal.integral.len() as u64 + decimal.fractional.len() as u64;
-    if e >= 0 {
-        // In the case e >= 0, both algorithms compute about `f * 10^e`. Algorithm R proceeds to
-        // do some complicated calculations with this but we can ignore that for the upper bound
-        // because it also reduces the fraction beforehand, so we have plenty of buffer there.
-        f_len + (e as u64)
-    } else {
-        // If e < 0, Algorithm R does roughly the same thing, but Algorithm M differs:
-        // It tries to find a positive number k such that `f << k / 10^e` is an in-range
-        // significand. This will result in about `2^53 * f * 10^e` < `10^17 * f * 10^e`.
-        // One input that triggers this is 0.33...33 (375 x 3).
-        f_len + e.unsigned_abs() + 17
+    // Unable to correctly round the float using the Eisel-Lemire algorithm.
+    // Fallback to a slower, but always correct algorithm.
+    if fp.e < 0 {
+        fp = parse_long_mantissa::<F>(s);
     }
-}
 
-/// Detects obvious overflows and underflows without even looking at the decimal digits.
-fn trivial_cases<T: RawFloat>(decimal: &Decimal<'_>) -> Option<T> {
-    // There were zeros but they were stripped by simplify()
-    if decimal.integral.is_empty() && decimal.fractional.is_empty() {
-        return Some(T::ZERO);
-    }
-    // This is a crude approximation of ceil(log10(the real value)). We don't need to worry too
-    // much about overflow here because the input length is tiny (at least compared to 2^64) and
-    // the parser already handles exponents whose absolute value is greater than 10^18
-    // (which is still 10^19 short of 2^64).
-    let max_place = decimal.exp + decimal.integral.len() as i64;
-    if max_place > T::INF_CUTOFF {
-        return Some(T::INFINITY);
-    } else if max_place < T::ZERO_CUTOFF {
-        return Some(T::ZERO);
+    let mut float = biased_fp_to_float::<F>(fp);
+    if num.negative {
+        float = -float;
     }
-    None
+    Ok(float)
 }
diff --git a/library/core/src/num/dec2flt/num.rs b/library/core/src/num/dec2flt/num.rs
deleted file mode 100644
index 208783dd32f..00000000000
--- a/library/core/src/num/dec2flt/num.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-//! Utility functions for bignums that don't make too much sense to turn into methods.
-
-// FIXME This module's name is a bit unfortunate, since other modules also import `core::num`.
-
-use crate::cmp::Ordering::{self, Equal, Greater, Less};
-
-pub use crate::num::bignum::Big32x40 as Big;
-
-/// Test whether truncating all bits less significant than `ones_place` introduces
-/// a relative error less, equal, or greater than 0.5 ULP.
-pub fn compare_with_half_ulp(f: &Big, ones_place: usize) -> Ordering {
-    if ones_place == 0 {
-        return Less;
-    }
-    let half_bit = ones_place - 1;
-    if f.get_bit(half_bit) == 0 {
-        // < 0.5 ULP
-        return Less;
-    }
-    // If all remaining bits are zero, it's = 0.5 ULP, otherwise > 0.5
-    // If there are no more bits (half_bit == 0), the below also correctly returns Equal.
-    for i in 0..half_bit {
-        if f.get_bit(i) == 1 {
-            return Greater;
-        }
-    }
-    Equal
-}
-
-/// Converts an ASCII string containing only decimal digits to a `u64`.
-///
-/// Does not perform checks for overflow or invalid characters, so if the caller is not careful,
-/// the result is bogus and can panic (though it won't be `unsafe`). Additionally, empty strings
-/// are treated as zero. This function exists because
-///
-/// 1. using `FromStr` on `&[u8]` requires `from_utf8_unchecked`, which is bad, and
-/// 2. piecing together the results of `integral.parse()` and `fractional.parse()` is
-///    more complicated than this entire function.
-pub fn from_str_unchecked<'a, T>(bytes: T) -> u64
-where
-    T: IntoIterator<Item = &'a u8>,
-{
-    let mut result = 0;
-    for &c in bytes {
-        result = result * 10 + (c - b'0') as u64;
-    }
-    result
-}
-
-/// Converts a string of ASCII digits into a bignum.
-///
-/// Like `from_str_unchecked`, this function relies on the parser to weed out non-digits.
-pub fn digits_to_big(integral: &[u8], fractional: &[u8]) -> Big {
-    let mut f = Big::from_small(0);
-    for &c in integral.iter().chain(fractional) {
-        let n = (c - b'0') as u32;
-        f.mul_small(10);
-        f.add_small(n);
-    }
-    f
-}
-
-/// Unwraps a bignum into a 64 bit integer. Panics if the number is too large.
-pub fn to_u64(x: &Big) -> u64 {
-    assert!(x.bit_length() < 64);
-    let d = x.digits();
-    if d.len() < 2 { d[0] as u64 } else { (d[1] as u64) << 32 | d[0] as u64 }
-}
-
-/// Extracts a range of bits.
-
-/// Index 0 is the least significant bit and the range is half-open as usual.
-/// Panics if asked to extract more bits than fit into the return type.
-pub fn get_bits(x: &Big, start: usize, end: usize) -> u64 {
-    assert!(end - start <= 64);
-    let mut result: u64 = 0;
-    for i in (start..end).rev() {
-        result = result << 1 | x.get_bit(i) as u64;
-    }
-    result
-}
diff --git a/library/core/src/num/dec2flt/number.rs b/library/core/src/num/dec2flt/number.rs
new file mode 100644
index 00000000000..36432718af4
--- /dev/null
+++ b/library/core/src/num/dec2flt/number.rs
@@ -0,0 +1,86 @@
+//! Representation of a float as the significant digits and exponent.
+
+use crate::num::dec2flt::float::RawFloat;
+use crate::num::dec2flt::fpu::set_precision;
+
+#[rustfmt::skip]
+const INT_POW10: [u64; 16] = [
+    1,
+    10,
+    100,
+    1000,
+    10000,
+    100000,
+    1000000,
+    10000000,
+    100000000,
+    1000000000,
+    10000000000,
+    100000000000,
+    1000000000000,
+    10000000000000,
+    100000000000000,
+    1000000000000000,
+];
+
+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
+pub struct Number {
+    pub exponent: i64,
+    pub mantissa: u64,
+    pub negative: bool,
+    pub many_digits: bool,
+}
+
+impl Number {
+    /// Detect if the float can be accurately reconstructed from native floats.
+    fn is_fast_path<F: RawFloat>(&self) -> bool {
+        F::MIN_EXPONENT_FAST_PATH <= self.exponent
+            && self.exponent <= F::MAX_EXPONENT_DISGUISED_FAST_PATH
+            && self.mantissa <= F::MAX_MANTISSA_FAST_PATH
+            && !self.many_digits
+    }
+
+    /// The fast path algorithmn using machine-sized integers and floats.
+    ///
+    /// This is extracted into a separate function so that it can be attempted before constructing
+    /// a Decimal. This only works if both the mantissa and the exponent
+    /// can be exactly represented as a machine float, since IEE-754 guarantees
+    /// no rounding will occur.
+    ///
+    /// There is an exception: disguised fast-path cases, where we can shift
+    /// powers-of-10 from the exponent to the significant digits.
+    pub fn try_fast_path<F: RawFloat>(&self) -> Option<F> {
+        // The fast path crucially depends on arithmetic being rounded to the correct number of bits
+        // without any intermediate rounding. On x86 (without SSE or SSE2) this requires the precision
+        // of the x87 FPU stack to be changed so that it directly rounds to 64/32 bit.
+        // The `set_precision` function takes care of setting the precision on architectures which
+        // require setting it by changing the global state (like the control word of the x87 FPU).
+        let _cw = set_precision::<F>();
+
+        if self.is_fast_path::<F>() {
+            let mut value = if self.exponent <= F::MAX_EXPONENT_FAST_PATH {
+                // normal fast path
+                let value = F::from_u64(self.mantissa);
+                if self.exponent < 0 {
+                    value / F::pow10_fast_path((-self.exponent) as _)
+                } else {
+                    value * F::pow10_fast_path(self.exponent as _)
+                }
+            } else {
+                // disguised fast path
+                let shift = self.exponent - F::MAX_EXPONENT_FAST_PATH;
+                let mantissa = self.mantissa.checked_mul(INT_POW10[shift as usize])?;
+                if mantissa > F::MAX_MANTISSA_FAST_PATH {
+                    return None;
+                }
+                F::from_u64(mantissa) * F::pow10_fast_path(F::MAX_EXPONENT_FAST_PATH as _)
+            };
+            if self.negative {
+                value = -value;
+            }
+            Some(value)
+        } else {
+            None
+        }
+    }
+}
diff --git a/library/core/src/num/dec2flt/parse.rs b/library/core/src/num/dec2flt/parse.rs
index 858cc3c9b01..fa677bf5123 100644
--- a/library/core/src/num/dec2flt/parse.rs
+++ b/library/core/src/num/dec2flt/parse.rs
@@ -1,121 +1,233 @@
-//! Validating and decomposing a decimal string of the form:
-//!
-//! `(digits | digits? '.'? digits?) (('e' | 'E') ('+' | '-')? digits)?`
-//!
-//! In other words, standard floating-point syntax, with two exceptions: No sign, and no
-//! handling of "inf" and "NaN". These are handled by the driver function (super::dec2flt).
-//!
-//! Although recognizing valid inputs is relatively easy, this module also has to reject the
-//! countless invalid variations, never panic, and perform numerous checks that the other
-//! modules rely on to not panic (or overflow) in turn.
-//! To make matters worse, all that happens in a single pass over the input.
-//! So, be careful when modifying anything, and double-check with the other modules.
-use self::ParseResult::{Invalid, ShortcutToInf, ShortcutToZero, Valid};
-use super::num;
-
-#[derive(Debug)]
-pub enum Sign {
-    Positive,
-    Negative,
+//! Functions to parse floating-point numbers.
+
+use crate::num::dec2flt::common::{is_8digits, AsciiStr, ByteSlice};
+use crate::num::dec2flt::float::RawFloat;
+use crate::num::dec2flt::number::Number;
+
+const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000;
+
+/// Parse 8 digits, loaded as bytes in little-endian order.
+///
+/// This uses the trick where every digit is in [0x030, 0x39],
+/// and therefore can be parsed in 3 multiplications, much
+/// faster than the normal 8.
+///
+/// This is based off the algorithm described in "Fast numeric string to
+/// int", available here: <https://johnnylee-sde.github.io/Fast-numeric-string-to-int/>.
+fn parse_8digits(mut v: u64) -> u64 {
+    const MASK: u64 = 0x0000_00FF_0000_00FF;
+    const MUL1: u64 = 0x000F_4240_0000_0064;
+    const MUL2: u64 = 0x0000_2710_0000_0001;
+    v -= 0x3030_3030_3030_3030;
+    v = (v * 10) + (v >> 8); // will not overflow, fits in 63 bits
+    let v1 = (v & MASK).wrapping_mul(MUL1);
+    let v2 = ((v >> 16) & MASK).wrapping_mul(MUL2);
+    ((v1.wrapping_add(v2) >> 32) as u32) as u64
 }
 
-#[derive(Debug, PartialEq, Eq)]
-/// The interesting parts of a decimal string.
-pub struct Decimal<'a> {
-    pub integral: &'a [u8],
-    pub fractional: &'a [u8],
-    /// The decimal exponent, guaranteed to have fewer than 18 decimal digits.
-    pub exp: i64,
+/// Parse digits until a non-digit character is found.
+fn try_parse_digits(s: &mut AsciiStr<'_>, x: &mut u64) {
+    // may cause overflows, to be handled later
+    s.parse_digits(|digit| {
+        *x = x.wrapping_mul(10).wrapping_add(digit as _);
+    });
 }
 
-impl<'a> Decimal<'a> {
-    pub fn new(integral: &'a [u8], fractional: &'a [u8], exp: i64) -> Decimal<'a> {
-        Decimal { integral, fractional, exp }
+/// Parse up to 19 digits (the max that can be stored in a 64-bit integer).
+fn try_parse_19digits(s: &mut AsciiStr<'_>, x: &mut u64) {
+    while *x < MIN_19DIGIT_INT {
+        if let Some(&c) = s.as_ref().first() {
+            let digit = c.wrapping_sub(b'0');
+            if digit < 10 {
+                *x = (*x * 10) + digit as u64; // no overflows here
+                // SAFETY: cannot be empty
+                unsafe {
+                    s.step();
+                }
+            } else {
+                break;
+            }
+        } else {
+            break;
+        }
     }
 }
 
-#[derive(Debug, PartialEq, Eq)]
-pub enum ParseResult<'a> {
-    Valid(Decimal<'a>),
-    ShortcutToInf,
-    ShortcutToZero,
-    Invalid,
+/// Try to parse 8 digits at a time, using an optimized algorithm.
+fn try_parse_8digits(s: &mut AsciiStr<'_>, x: &mut u64) {
+    // may cause overflows, to be handled later
+    if let Some(v) = s.read_u64() {
+        if is_8digits(v) {
+            *x = x.wrapping_mul(1_0000_0000).wrapping_add(parse_8digits(v));
+            // SAFETY: already ensured the buffer was >= 8 bytes in read_u64.
+            unsafe {
+                s.step_by(8);
+            }
+            if let Some(v) = s.read_u64() {
+                if is_8digits(v) {
+                    *x = x.wrapping_mul(1_0000_0000).wrapping_add(parse_8digits(v));
+                    // SAFETY: already ensured the buffer was >= 8 bytes in try_read_u64.
+                    unsafe {
+                        s.step_by(8);
+                    }
+                }
+            }
+        }
+    }
 }
 
-/// Checks if the input string is a valid floating point number and if so, locate the integral
-/// part, the fractional part, and the exponent in it. Does not handle signs.
-pub fn parse_decimal(s: &str) -> ParseResult<'_> {
-    if s.is_empty() {
-        return Invalid;
+/// Parse the scientific notation component of a float.
+fn parse_scientific(s: &mut AsciiStr<'_>) -> Option<i64> {
+    let mut exponent = 0_i64;
+    let mut negative = false;
+    if let Some(&c) = s.as_ref().get(0) {
+        negative = c == b'-';
+        if c == b'-' || c == b'+' {
+            // SAFETY: s cannot be empty
+            unsafe {
+                s.step();
+            }
+        }
     }
+    if s.first_isdigit() {
+        s.parse_digits(|digit| {
+            // no overflows here, saturate well before overflow
+            if exponent < 0x10000 {
+                exponent = 10 * exponent + digit as i64;
+            }
+        });
+        if negative { Some(-exponent) } else { Some(exponent) }
+    } else {
+        None
+    }
+}
 
-    let s = s.as_bytes();
-    let (integral, s) = eat_digits(s);
+/// Parse a partial, non-special floating point number.
+///
+/// This creates a representation of the float as the
+/// significant digits and the decimal exponent.
+fn parse_partial_number(s: &[u8], negative: bool) -> Option<(Number, usize)> {
+    let mut s = AsciiStr::new(s);
+    let start = s;
+    debug_assert!(!s.is_empty());
 
-    match s.first() {
-        None => Valid(Decimal::new(integral, b"", 0)),
-        Some(&b'e' | &b'E') => {
-            if integral.is_empty() {
-                return Invalid; // No digits before 'e'
-            }
+    // parse initial digits before dot
+    let mut mantissa = 0_u64;
+    let digits_start = s;
+    try_parse_digits(&mut s, &mut mantissa);
+    let mut n_digits = s.offset_from(&digits_start);
+
+    // handle dot with the following digits
+    let mut n_after_dot = 0;
+    let mut exponent = 0_i64;
+    let int_end = s;
+    if s.first_is(b'.') {
+        // SAFETY: s cannot be empty due to first_is
+        unsafe { s.step() };
+        let before = s;
+        try_parse_8digits(&mut s, &mut mantissa);
+        try_parse_digits(&mut s, &mut mantissa);
+        n_after_dot = s.offset_from(&before);
+        exponent = -n_after_dot as i64;
+    }
 
-            parse_exp(integral, b"", &s[1..])
+    n_digits += n_after_dot;
+    if n_digits == 0 {
+        return None;
+    }
+
+    // handle scientific format
+    let mut exp_number = 0_i64;
+    if s.first_is2(b'e', b'E') {
+        // SAFETY: s cannot be empty
+        unsafe {
+            s.step();
         }
-        Some(&b'.') => {
-            let (fractional, s) = eat_digits(&s[1..]);
-            if integral.is_empty() && fractional.is_empty() {
-                // We require at least a single digit before or after the point.
-                return Invalid;
-            }
+        // If None, we have no trailing digits after exponent, or an invalid float.
+        exp_number = parse_scientific(&mut s)?;
+        exponent += exp_number;
+    }
 
-            match s.first() {
-                None => Valid(Decimal::new(integral, fractional, 0)),
-                Some(&b'e' | &b'E') => parse_exp(integral, fractional, &s[1..]),
-                _ => Invalid, // Trailing junk after fractional part
-            }
+    let len = s.offset_from(&start) as _;
+
+    // handle uncommon case with many digits
+    if n_digits <= 19 {
+        return Some((Number { exponent, mantissa, negative, many_digits: false }, len));
+    }
+
+    n_digits -= 19;
+    let mut many_digits = false;
+    let mut p = digits_start;
+    while p.first_is2(b'0', b'.') {
+        // SAFETY: p cannot be empty due to first_is2
+        unsafe {
+            // '0' = b'.' + 2
+            n_digits -= p.first_unchecked().saturating_sub(b'0' - 1) as isize;
+            p.step();
         }
-        _ => Invalid, // Trailing junk after first digit string
     }
-}
+    if n_digits > 0 {
+        // at this point we have more than 19 significant digits, let's try again
+        many_digits = true;
+        mantissa = 0;
+        let mut s = digits_start;
+        try_parse_19digits(&mut s, &mut mantissa);
+        exponent = if mantissa >= MIN_19DIGIT_INT {
+            // big int
+            int_end.offset_from(&s)
+        } else {
+            // SAFETY: the next byte must be present and be '.'
+            // We know this is true because we had more than 19
+            // digits previously, so we overflowed a 64-bit integer,
+            // but parsing only the integral digits produced less
+            // than 19 digits. That means we must have a decimal
+            // point, and at least 1 fractional digit.
+            unsafe { s.step() };
+            let before = s;
+            try_parse_19digits(&mut s, &mut mantissa);
+            -s.offset_from(&before)
+        } as i64;
+        // add back the explicit part
+        exponent += exp_number;
+    }
 
-/// Carves off decimal digits up to the first non-digit character.
-fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) {
-    let pos = s.iter().position(|c| !c.is_ascii_digit()).unwrap_or(s.len());
-    s.split_at(pos)
+    Some((Number { exponent, mantissa, negative, many_digits }, len))
 }
 
-/// Exponent extraction and error checking.
-fn parse_exp<'a>(integral: &'a [u8], fractional: &'a [u8], rest: &'a [u8]) -> ParseResult<'a> {
-    let (sign, rest) = match rest.first() {
-        Some(&b'-') => (Sign::Negative, &rest[1..]),
-        Some(&b'+') => (Sign::Positive, &rest[1..]),
-        _ => (Sign::Positive, rest),
-    };
-    let (mut number, trailing) = eat_digits(rest);
-    if !trailing.is_empty() {
-        return Invalid; // Trailing junk after exponent
+/// Try to parse a non-special floating point number.
+pub fn parse_number(s: &[u8], negative: bool) -> Option<Number> {
+    if let Some((float, rest)) = parse_partial_number(s, negative) {
+        if rest == s.len() {
+            return Some(float);
+        }
     }
-    if number.is_empty() {
-        return Invalid; // Empty exponent
+    None
+}
+
+/// Parse a partial representation of a special, non-finite float.
+fn parse_partial_inf_nan<F: RawFloat>(s: &[u8]) -> Option<(F, usize)> {
+    fn parse_inf_rest(s: &[u8]) -> usize {
+        if s.len() >= 8 && s[3..].as_ref().eq_ignore_case(b"inity") { 8 } else { 3 }
     }
-    // At this point, we certainly have a valid string of digits. It may be too long to put into
-    // an `i64`, but if it's that huge, the input is certainly zero or infinity. Since each zero
-    // in the decimal digits only adjusts the exponent by +/- 1, at exp = 10^18 the input would
-    // have to be 17 exabyte (!) of zeros to get even remotely close to being finite.
-    // This is not exactly a use case we need to cater to.
-    while number.first() == Some(&b'0') {
-        number = &number[1..];
+    if s.len() >= 3 {
+        if s.eq_ignore_case(b"nan") {
+            return Some((F::NAN, 3));
+        } else if s.eq_ignore_case(b"inf") {
+            return Some((F::INFINITY, parse_inf_rest(s)));
+        }
     }
-    if number.len() >= 18 {
-        return match sign {
-            Sign::Positive => ShortcutToInf,
-            Sign::Negative => ShortcutToZero,
-        };
+    None
+}
+
+/// Try to parse a special, non-finite float.
+pub fn parse_inf_nan<F: RawFloat>(s: &[u8], negative: bool) -> Option<F> {
+    if let Some((mut float, rest)) = parse_partial_inf_nan::<F>(s) {
+        if rest == s.len() {
+            if negative {
+                float = -float;
+            }
+            return Some(float);
+        }
     }
-    let abs_exp = num::from_str_unchecked(number);
-    let e = match sign {
-        Sign::Positive => abs_exp as i64,
-        Sign::Negative => -(abs_exp as i64),
-    };
-    Valid(Decimal::new(integral, fractional, e))
+    None
 }
diff --git a/library/core/src/num/dec2flt/rawfp.rs b/library/core/src/num/dec2flt/rawfp.rs
deleted file mode 100644
index 0ab15b23e53..00000000000
--- a/library/core/src/num/dec2flt/rawfp.rs
+++ /dev/null
@@ -1,363 +0,0 @@
-//! Bit fiddling on positive IEEE 754 floats. Negative numbers aren't and needn't be handled.
-//! Normal floating point numbers have a canonical representation as (frac, exp) such that the
-//! value is 2<sup>exp</sup> * (1 + sum(frac[N-i] / 2<sup>i</sup>)) where N is the number of bits.
-//! Subnormals are slightly different and weird, but the same principle applies.
-//!
-//! Here, however, we represent them as (sig, k) with f positive, such that the value is f *
-//! 2<sup>e</sup>. Besides making the "hidden bit" explicit, this changes the exponent by the
-//! so-called mantissa shift.
-//!
-//! Put another way, normally floats are written as (1) but here they are written as (2):
-//!
-//! 1. `1.101100...11 * 2^m`
-//! 2. `1101100...11 * 2^n`
-//!
-//! We call (1) the **fractional representation** and (2) the **integral representation**.
-//!
-//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively
-//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
-//! That algorithm needs only next_float() which does handle subnormals and zeros.
-use crate::cmp::Ordering::{Equal, Greater, Less};
-use crate::convert::{TryFrom, TryInto};
-use crate::fmt::{Debug, LowerExp};
-use crate::num::dec2flt::num::{self, Big};
-use crate::num::dec2flt::table;
-use crate::num::diy_float::Fp;
-use crate::num::FpCategory;
-use crate::num::FpCategory::{Infinite, Nan, Normal, Subnormal, Zero};
-use crate::ops::{Add, Div, Mul, Neg};
-
-#[derive(Copy, Clone, Debug)]
-pub struct Unpacked {
-    pub sig: u64,
-    pub k: i16,
-}
-
-impl Unpacked {
-    pub fn new(sig: u64, k: i16) -> Self {
-        Unpacked { sig, k }
-    }
-}
-
-/// A helper trait to avoid duplicating basically all the conversion code for `f32` and `f64`.
-///
-/// See the parent module's doc comment for why this is necessary.
-///
-/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
-pub trait RawFloat:
-    Copy + Debug + LowerExp + Mul<Output = Self> + Div<Output = Self> + Neg<Output = Self>
-{
-    const INFINITY: Self;
-    const NAN: Self;
-    const ZERO: Self;
-
-    /// Type used by `to_bits` and `from_bits`.
-    type Bits: Add<Output = Self::Bits> + From<u8> + TryFrom<u64>;
-
-    /// Performs a raw transmutation to an integer.
-    fn to_bits(self) -> Self::Bits;
-
-    /// Performs a raw transmutation from an integer.
-    fn from_bits(v: Self::Bits) -> Self;
-
-    /// Returns the category that this number falls into.
-    fn classify(self) -> FpCategory;
-
-    /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8);
-
-    /// Decodes the float.
-    fn unpack(self) -> Unpacked;
-
-    /// Casts from a small integer that can be represented exactly. Panic if the integer can't be
-    /// represented, the other code in this module makes sure to never let that happen.
-    fn from_int(x: u64) -> Self;
-
-    /// Gets the value 10<sup>e</sup> from a pre-computed table.
-    /// Panics for `e >= CEIL_LOG5_OF_MAX_SIG`.
-    fn short_fast_pow10(e: usize) -> Self;
-
-    /// What the name says. It's easier to hard code than juggling intrinsics and
-    /// hoping LLVM constant folds it.
-    const CEIL_LOG5_OF_MAX_SIG: i16;
-
-    // A conservative bound on the decimal digits of inputs that can't produce overflow or zero or
-    /// subnormals. Probably the decimal exponent of the maximum normal value, hence the name.
-    const MAX_NORMAL_DIGITS: usize;
-
-    /// When the most significant decimal digit has a place value greater than this, the number
-    /// is certainly rounded to infinity.
-    const INF_CUTOFF: i64;
-
-    /// When the most significant decimal digit has a place value less than this, the number
-    /// is certainly rounded to zero.
-    const ZERO_CUTOFF: i64;
-
-    /// The number of bits in the exponent.
-    const EXP_BITS: u8;
-
-    /// The number of bits in the significand, *including* the hidden bit.
-    const SIG_BITS: u8;
-
-    /// The number of bits in the significand, *excluding* the hidden bit.
-    const EXPLICIT_SIG_BITS: u8;
-
-    /// The maximum legal exponent in fractional representation.
-    const MAX_EXP: i16;
-
-    /// The minimum legal exponent in fractional representation, excluding subnormals.
-    const MIN_EXP: i16;
-
-    /// `MAX_EXP` for integral representation, i.e., with the shift applied.
-    const MAX_EXP_INT: i16;
-
-    /// `MAX_EXP` encoded (i.e., with offset bias)
-    const MAX_ENCODED_EXP: i16;
-
-    /// `MIN_EXP` for integral representation, i.e., with the shift applied.
-    const MIN_EXP_INT: i16;
-
-    /// The maximum normalized significand in integral representation.
-    const MAX_SIG: u64;
-
-    /// The minimal normalized significand in integral representation.
-    const MIN_SIG: u64;
-}
-
-// Mostly a workaround for #34344.
-macro_rules! other_constants {
-    ($type: ident) => {
-        const EXPLICIT_SIG_BITS: u8 = Self::SIG_BITS - 1;
-        const MAX_EXP: i16 = (1 << (Self::EXP_BITS - 1)) - 1;
-        const MIN_EXP: i16 = -<Self as RawFloat>::MAX_EXP + 1;
-        const MAX_EXP_INT: i16 = <Self as RawFloat>::MAX_EXP - (Self::SIG_BITS as i16 - 1);
-        const MAX_ENCODED_EXP: i16 = (1 << Self::EXP_BITS) - 1;
-        const MIN_EXP_INT: i16 = <Self as RawFloat>::MIN_EXP - (Self::SIG_BITS as i16 - 1);
-        const MAX_SIG: u64 = (1 << Self::SIG_BITS) - 1;
-        const MIN_SIG: u64 = 1 << (Self::SIG_BITS - 1);
-
-        const INFINITY: Self = $type::INFINITY;
-        const NAN: Self = $type::NAN;
-        const ZERO: Self = 0.0;
-    };
-}
-
-impl RawFloat for f32 {
-    type Bits = u32;
-
-    const SIG_BITS: u8 = 24;
-    const EXP_BITS: u8 = 8;
-    const CEIL_LOG5_OF_MAX_SIG: i16 = 11;
-    const MAX_NORMAL_DIGITS: usize = 35;
-    const INF_CUTOFF: i64 = 40;
-    const ZERO_CUTOFF: i64 = -48;
-    other_constants!(f32);
-
-    /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8) {
-        let bits = self.to_bits();
-        let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
-        let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
-        let mantissa =
-            if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 };
-        // Exponent bias + mantissa shift
-        exponent -= 127 + 23;
-        (mantissa as u64, exponent, sign)
-    }
-
-    fn unpack(self) -> Unpacked {
-        let (sig, exp, _sig) = self.integer_decode();
-        Unpacked::new(sig, exp)
-    }
-
-    fn from_int(x: u64) -> f32 {
-        // rkruppe is uncertain whether `as` rounds correctly on all platforms.
-        debug_assert!(x as f32 == fp_to_float(Fp { f: x, e: 0 }));
-        x as f32
-    }
-
-    fn short_fast_pow10(e: usize) -> Self {
-        table::F32_SHORT_POWERS[e]
-    }
-
-    fn classify(self) -> FpCategory {
-        self.classify()
-    }
-    fn to_bits(self) -> Self::Bits {
-        self.to_bits()
-    }
-    fn from_bits(v: Self::Bits) -> Self {
-        Self::from_bits(v)
-    }
-}
-
-impl RawFloat for f64 {
-    type Bits = u64;
-
-    const SIG_BITS: u8 = 53;
-    const EXP_BITS: u8 = 11;
-    const CEIL_LOG5_OF_MAX_SIG: i16 = 23;
-    const MAX_NORMAL_DIGITS: usize = 305;
-    const INF_CUTOFF: i64 = 310;
-    const ZERO_CUTOFF: i64 = -326;
-    other_constants!(f64);
-
-    /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8) {
-        let bits = self.to_bits();
-        let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
-        let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
-        let mantissa = if exponent == 0 {
-            (bits & 0xfffffffffffff) << 1
-        } else {
-            (bits & 0xfffffffffffff) | 0x10000000000000
-        };
-        // Exponent bias + mantissa shift
-        exponent -= 1023 + 52;
-        (mantissa, exponent, sign)
-    }
-
-    fn unpack(self) -> Unpacked {
-        let (sig, exp, _sig) = self.integer_decode();
-        Unpacked::new(sig, exp)
-    }
-
-    fn from_int(x: u64) -> f64 {
-        // rkruppe is uncertain whether `as` rounds correctly on all platforms.
-        debug_assert!(x as f64 == fp_to_float(Fp { f: x, e: 0 }));
-        x as f64
-    }
-
-    fn short_fast_pow10(e: usize) -> Self {
-        table::F64_SHORT_POWERS[e]
-    }
-
-    fn classify(self) -> FpCategory {
-        self.classify()
-    }
-    fn to_bits(self) -> Self::Bits {
-        self.to_bits()
-    }
-    fn from_bits(v: Self::Bits) -> Self {
-        Self::from_bits(v)
-    }
-}
-
-/// Converts an `Fp` to the closest machine float type.
-/// Does not handle subnormal results.
-pub fn fp_to_float<T: RawFloat>(x: Fp) -> T {
-    let x = x.normalize();
-    // x.f is 64 bit, so x.e has a mantissa shift of 63
-    let e = x.e + 63;
-    if e > T::MAX_EXP {
-        panic!("fp_to_float: exponent {} too large", e)
-    } else if e > T::MIN_EXP {
-        encode_normal(round_normal::<T>(x))
-    } else {
-        panic!("fp_to_float: exponent {} too small", e)
-    }
-}
-
-/// Round the 64-bit significand to T::SIG_BITS bits with half-to-even.
-/// Does not handle exponent overflow.
-pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked {
-    let excess = 64 - T::SIG_BITS as i16;
-    let half: u64 = 1 << (excess - 1);
-    let (q, rem) = (x.f >> excess, x.f & ((1 << excess) - 1));
-    assert_eq!(q << excess | rem, x.f);
-    // Adjust mantissa shift
-    let k = x.e + excess;
-    if rem < half {
-        Unpacked::new(q, k)
-    } else if rem == half && (q % 2) == 0 {
-        Unpacked::new(q, k)
-    } else if q == T::MAX_SIG {
-        Unpacked::new(T::MIN_SIG, k + 1)
-    } else {
-        Unpacked::new(q + 1, k)
-    }
-}
-
-/// Inverse of `RawFloat::unpack()` for normalized numbers.
-/// Panics if the significand or exponent are not valid for normalized numbers.
-pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T {
-    debug_assert!(
-        T::MIN_SIG <= x.sig && x.sig <= T::MAX_SIG,
-        "encode_normal: significand not normalized"
-    );
-    // Remove the hidden bit
-    let sig_enc = x.sig & !(1 << T::EXPLICIT_SIG_BITS);
-    // Adjust the exponent for exponent bias and mantissa shift
-    let k_enc = x.k + T::MAX_EXP + T::EXPLICIT_SIG_BITS as i16;
-    debug_assert!(k_enc != 0 && k_enc < T::MAX_ENCODED_EXP, "encode_normal: exponent out of range");
-    // Leave sign bit at 0 ("+"), our numbers are all positive
-    let bits = (k_enc as u64) << T::EXPLICIT_SIG_BITS | sig_enc;
-    T::from_bits(bits.try_into().unwrap_or_else(|_| unreachable!()))
-}
-
-/// Construct a subnormal. A mantissa of 0 is allowed and constructs zero.
-pub fn encode_subnormal<T: RawFloat>(significand: u64) -> T {
-    assert!(significand < T::MIN_SIG, "encode_subnormal: not actually subnormal");
-    // Encoded exponent is 0, the sign bit is 0, so we just have to reinterpret the bits.
-    T::from_bits(significand.try_into().unwrap_or_else(|_| unreachable!()))
-}
-
-/// Approximate a bignum with an Fp. Rounds within 0.5 ULP with half-to-even.
-pub fn big_to_fp(f: &Big) -> Fp {
-    let end = f.bit_length();
-    assert!(end != 0, "big_to_fp: unexpectedly, input is zero");
-    let start = end.saturating_sub(64);
-    let leading = num::get_bits(f, start, end);
-    // We cut off all bits prior to the index `start`, i.e., we effectively right-shift by
-    // an amount of `start`, so this is also the exponent we need.
-    let e = start as i16;
-    let rounded_down = Fp { f: leading, e }.normalize();
-    // Round (half-to-even) depending on the truncated bits.
-    match num::compare_with_half_ulp(f, start) {
-        Less => rounded_down,
-        Equal if leading % 2 == 0 => rounded_down,
-        Equal | Greater => match leading.checked_add(1) {
-            Some(f) => Fp { f, e }.normalize(),
-            None => Fp { f: 1 << 63, e: e + 1 },
-        },
-    }
-}
-
-/// Finds the largest floating point number strictly smaller than the argument.
-/// Does not handle subnormals, zero, or exponent underflow.
-pub fn prev_float<T: RawFloat>(x: T) -> T {
-    match x.classify() {
-        Infinite => panic!("prev_float: argument is infinite"),
-        Nan => panic!("prev_float: argument is NaN"),
-        Subnormal => panic!("prev_float: argument is subnormal"),
-        Zero => panic!("prev_float: argument is zero"),
-        Normal => {
-            let Unpacked { sig, k } = x.unpack();
-            if sig == T::MIN_SIG {
-                encode_normal(Unpacked::new(T::MAX_SIG, k - 1))
-            } else {
-                encode_normal(Unpacked::new(sig - 1, k))
-            }
-        }
-    }
-}
-
-// Find the smallest floating point number strictly larger than the argument.
-// This operation is saturating, i.e., next_float(inf) == inf.
-// Unlike most code in this module, this function does handle zero, subnormals, and infinities.
-// However, like all other code here, it does not deal with NaN and negative numbers.
-pub fn next_float<T: RawFloat>(x: T) -> T {
-    match x.classify() {
-        Nan => panic!("next_float: argument is NaN"),
-        Infinite => T::INFINITY,
-        // This seems too good to be true, but it works.
-        // 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa.
-        // In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F.
-        // The smallest normal number is 0x0010...0, so this corner case works as well.
-        // If the increment overflows the mantissa, the carry bit increments the exponent as we
-        // want, and the mantissa bits become zero. Because of the hidden bit convention, this
-        // too is exactly what we want!
-        // Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY.
-        Zero | Subnormal | Normal => T::from_bits(x.to_bits() + T::Bits::from(1u8)),
-    }
-}
diff --git a/library/core/src/num/dec2flt/slow.rs b/library/core/src/num/dec2flt/slow.rs
new file mode 100644
index 00000000000..bf1044033e6
--- /dev/null
+++ b/library/core/src/num/dec2flt/slow.rs
@@ -0,0 +1,109 @@
+//! Slow, fallback algorithm for cases the Eisel-Lemire algorithm cannot round.
+
+use crate::num::dec2flt::common::BiasedFp;
+use crate::num::dec2flt::decimal::{parse_decimal, Decimal};
+use crate::num::dec2flt::float::RawFloat;
+
+/// Parse the significant digits and biased, binary exponent of a float.
+///
+/// This is a fallback algorithm that uses a big-integer representation
+/// of the float, and therefore is considerably slower than faster
+/// approximations. However, it will always determine how to round
+/// the significant digits to the nearest machine float, allowing
+/// use to handle near half-way cases.
+///
+/// Near half-way cases are halfway between two consecutive machine floats.
+/// For example, the float `16777217.0` has a bitwise representation of
+/// `100000000000000000000000 1`. Rounding to a single-precision float,
+/// the trailing `1` is truncated. Using round-nearest, tie-even, any
+/// value above `16777217.0` must be rounded up to `16777218.0`, while
+/// any value before or equal to `16777217.0` must be rounded down
+/// to `16777216.0`. These near-halfway conversions therefore may require
+/// a large number of digits to unambiguously determine how to round.
+///
+/// The algorithms described here are based on "Processing Long Numbers Quickly",
+/// available here: <https://arxiv.org/pdf/2101.11408.pdf#section.11>.
+pub(crate) fn parse_long_mantissa<F: RawFloat>(s: &[u8]) -> BiasedFp {
+    const MAX_SHIFT: usize = 60;
+    const NUM_POWERS: usize = 19;
+    const POWERS: [u8; 19] =
+        [0, 3, 6, 9, 13, 16, 19, 23, 26, 29, 33, 36, 39, 43, 46, 49, 53, 56, 59];
+
+    let get_shift = |n| {
+        if n < NUM_POWERS { POWERS[n] as usize } else { MAX_SHIFT }
+    };
+
+    let fp_zero = BiasedFp::zero_pow2(0);
+    let fp_inf = BiasedFp::zero_pow2(F::INFINITE_POWER);
+
+    let mut d = parse_decimal(s);
+
+    // Short-circuit if the value can only be a literal 0 or infinity.
+    if d.num_digits == 0 || d.decimal_point < -324 {
+        return fp_zero;
+    } else if d.decimal_point >= 310 {
+        return fp_inf;
+    }
+    let mut exp2 = 0_i32;
+    // Shift right toward (1/2 ... 1].
+    while d.decimal_point > 0 {
+        let n = d.decimal_point as usize;
+        let shift = get_shift(n);
+        d.right_shift(shift);
+        if d.decimal_point < -Decimal::DECIMAL_POINT_RANGE {
+            return fp_zero;
+        }
+        exp2 += shift as i32;
+    }
+    // Shift left toward (1/2 ... 1].
+    while d.decimal_point <= 0 {
+        let shift = if d.decimal_point == 0 {
+            match d.digits[0] {
+                digit if digit >= 5 => break,
+                0 | 1 => 2,
+                _ => 1,
+            }
+        } else {
+            get_shift((-d.decimal_point) as _)
+        };
+        d.left_shift(shift);
+        if d.decimal_point > Decimal::DECIMAL_POINT_RANGE {
+            return fp_inf;
+        }
+        exp2 -= shift as i32;
+    }
+    // We are now in the range [1/2 ... 1] but the binary format uses [1 ... 2].
+    exp2 -= 1;
+    while (F::MINIMUM_EXPONENT + 1) > exp2 {
+        let mut n = ((F::MINIMUM_EXPONENT + 1) - exp2) as usize;
+        if n > MAX_SHIFT {
+            n = MAX_SHIFT;
+        }
+        d.right_shift(n);
+        exp2 += n as i32;
+    }
+    if (exp2 - F::MINIMUM_EXPONENT) >= F::INFINITE_POWER {
+        return fp_inf;
+    }
+    // Shift the decimal to the hidden bit, and then round the value
+    // to get the high mantissa+1 bits.
+    d.left_shift(F::MANTISSA_EXPLICIT_BITS + 1);
+    let mut mantissa = d.round();
+    if mantissa >= (1_u64 << (F::MANTISSA_EXPLICIT_BITS + 1)) {
+        // Rounding up overflowed to the carry bit, need to
+        // shift back to the hidden bit.
+        d.right_shift(1);
+        exp2 += 1;
+        mantissa = d.round();
+        if (exp2 - F::MINIMUM_EXPONENT) >= F::INFINITE_POWER {
+            return fp_inf;
+        }
+    }
+    let mut power2 = exp2 - F::MINIMUM_EXPONENT;
+    if mantissa < (1_u64 << F::MANTISSA_EXPLICIT_BITS) {
+        power2 -= 1;
+    }
+    // Zero out all the bits above the explicit mantissa bits.
+    mantissa &= (1_u64 << F::MANTISSA_EXPLICIT_BITS) - 1;
+    BiasedFp { f: mantissa, e: power2 }
+}
diff --git a/library/core/src/num/dec2flt/table.rs b/library/core/src/num/dec2flt/table.rs
index 97b497e81e0..4856074a62b 100644
--- a/library/core/src/num/dec2flt/table.rs
+++ b/library/core/src/num/dec2flt/table.rs
@@ -1,1277 +1,670 @@
-//! Tables of approximations of powers of ten.
+//! Pre-computed tables powers-of-5 for extended-precision representations.
+//!
+//! These tables enable fast scaling of the significant digits
+//! of a float to the decimal exponent, with minimal rounding
+//! errors, in a 128 or 192-bit representation.
+//!
 //! DO NOT MODIFY: Generated by `src/etc/dec2flt_table.py`
 
-pub const MIN_E: i16 = -305;
-pub const MAX_E: i16 = 305;
+pub const SMALLEST_POWER_OF_FIVE: i32 = -342;
+pub const LARGEST_POWER_OF_FIVE: i32 = 308;
+pub const N_POWERS_OF_FIVE: usize = (LARGEST_POWER_OF_FIVE - SMALLEST_POWER_OF_FIVE + 1) as usize;
 
+// Use static to avoid long compile times: Rust compiler errors
+// can have the entire table compiled multiple times, and then
+// emit code multiple times, even if it's stripped out in
+// the final binary.
 #[rustfmt::skip]
-pub static POWERS: ([u64; 611], [i16; 611]) = (
-    [
-        0xe0b62e2929aba83c,
-        0x8c71dcd9ba0b4926,
-        0xaf8e5410288e1b6f,
-        0xdb71e91432b1a24b,
-        0x892731ac9faf056f,
-        0xab70fe17c79ac6ca,
-        0xd64d3d9db981787d,
-        0x85f0468293f0eb4e,
-        0xa76c582338ed2622,
-        0xd1476e2c07286faa,
-        0x82cca4db847945ca,
-        0xa37fce126597973d,
-        0xcc5fc196fefd7d0c,
-        0xff77b1fcbebcdc4f,
-        0x9faacf3df73609b1,
-        0xc795830d75038c1e,
-        0xf97ae3d0d2446f25,
-        0x9becce62836ac577,
-        0xc2e801fb244576d5,
-        0xf3a20279ed56d48a,
-        0x9845418c345644d7,
-        0xbe5691ef416bd60c,
-        0xedec366b11c6cb8f,
-        0x94b3a202eb1c3f39,
-        0xb9e08a83a5e34f08,
-        0xe858ad248f5c22ca,
-        0x91376c36d99995be,
-        0xb58547448ffffb2e,
-        0xe2e69915b3fff9f9,
-        0x8dd01fad907ffc3c,
-        0xb1442798f49ffb4b,
-        0xdd95317f31c7fa1d,
-        0x8a7d3eef7f1cfc52,
-        0xad1c8eab5ee43b67,
-        0xd863b256369d4a41,
-        0x873e4f75e2224e68,
-        0xa90de3535aaae202,
-        0xd3515c2831559a83,
-        0x8412d9991ed58092,
-        0xa5178fff668ae0b6,
-        0xce5d73ff402d98e4,
-        0x80fa687f881c7f8e,
-        0xa139029f6a239f72,
-        0xc987434744ac874f,
-        0xfbe9141915d7a922,
-        0x9d71ac8fada6c9b5,
-        0xc4ce17b399107c23,
-        0xf6019da07f549b2b,
-        0x99c102844f94e0fb,
-        0xc0314325637a193a,
-        0xf03d93eebc589f88,
-        0x96267c7535b763b5,
-        0xbbb01b9283253ca3,
-        0xea9c227723ee8bcb,
-        0x92a1958a7675175f,
-        0xb749faed14125d37,
-        0xe51c79a85916f485,
-        0x8f31cc0937ae58d3,
-        0xb2fe3f0b8599ef08,
-        0xdfbdcece67006ac9,
-        0x8bd6a141006042be,
-        0xaecc49914078536d,
-        0xda7f5bf590966849,
-        0x888f99797a5e012d,
-        0xaab37fd7d8f58179,
-        0xd5605fcdcf32e1d7,
-        0x855c3be0a17fcd26,
-        0xa6b34ad8c9dfc070,
-        0xd0601d8efc57b08c,
-        0x823c12795db6ce57,
-        0xa2cb1717b52481ed,
-        0xcb7ddcdda26da269,
-        0xfe5d54150b090b03,
-        0x9efa548d26e5a6e2,
-        0xc6b8e9b0709f109a,
-        0xf867241c8cc6d4c1,
-        0x9b407691d7fc44f8,
-        0xc21094364dfb5637,
-        0xf294b943e17a2bc4,
-        0x979cf3ca6cec5b5b,
-        0xbd8430bd08277231,
-        0xece53cec4a314ebe,
-        0x940f4613ae5ed137,
-        0xb913179899f68584,
-        0xe757dd7ec07426e5,
-        0x9096ea6f3848984f,
-        0xb4bca50b065abe63,
-        0xe1ebce4dc7f16dfc,
-        0x8d3360f09cf6e4bd,
-        0xb080392cc4349ded,
-        0xdca04777f541c568,
-        0x89e42caaf9491b61,
-        0xac5d37d5b79b6239,
-        0xd77485cb25823ac7,
-        0x86a8d39ef77164bd,
-        0xa8530886b54dbdec,
-        0xd267caa862a12d67,
-        0x8380dea93da4bc60,
-        0xa46116538d0deb78,
-        0xcd795be870516656,
-        0x806bd9714632dff6,
-        0xa086cfcd97bf97f4,
-        0xc8a883c0fdaf7df0,
-        0xfad2a4b13d1b5d6c,
-        0x9cc3a6eec6311a64,
-        0xc3f490aa77bd60fd,
-        0xf4f1b4d515acb93c,
-        0x991711052d8bf3c5,
-        0xbf5cd54678eef0b7,
-        0xef340a98172aace5,
-        0x9580869f0e7aac0f,
-        0xbae0a846d2195713,
-        0xe998d258869facd7,
-        0x91ff83775423cc06,
-        0xb67f6455292cbf08,
-        0xe41f3d6a7377eeca,
-        0x8e938662882af53e,
-        0xb23867fb2a35b28e,
-        0xdec681f9f4c31f31,
-        0x8b3c113c38f9f37f,
-        0xae0b158b4738705f,
-        0xd98ddaee19068c76,
-        0x87f8a8d4cfa417ca,
-        0xa9f6d30a038d1dbc,
-        0xd47487cc8470652b,
-        0x84c8d4dfd2c63f3b,
-        0xa5fb0a17c777cf0a,
-        0xcf79cc9db955c2cc,
-        0x81ac1fe293d599c0,
-        0xa21727db38cb0030,
-        0xca9cf1d206fdc03c,
-        0xfd442e4688bd304b,
-        0x9e4a9cec15763e2f,
-        0xc5dd44271ad3cdba,
-        0xf7549530e188c129,
-        0x9a94dd3e8cf578ba,
-        0xc13a148e3032d6e8,
-        0xf18899b1bc3f8ca2,
-        0x96f5600f15a7b7e5,
-        0xbcb2b812db11a5de,
-        0xebdf661791d60f56,
-        0x936b9fcebb25c996,
-        0xb84687c269ef3bfb,
-        0xe65829b3046b0afa,
-        0x8ff71a0fe2c2e6dc,
-        0xb3f4e093db73a093,
-        0xe0f218b8d25088b8,
-        0x8c974f7383725573,
-        0xafbd2350644eead0,
-        0xdbac6c247d62a584,
-        0x894bc396ce5da772,
-        0xab9eb47c81f5114f,
-        0xd686619ba27255a3,
-        0x8613fd0145877586,
-        0xa798fc4196e952e7,
-        0xd17f3b51fca3a7a1,
-        0x82ef85133de648c5,
-        0xa3ab66580d5fdaf6,
-        0xcc963fee10b7d1b3,
-        0xffbbcfe994e5c620,
-        0x9fd561f1fd0f9bd4,
-        0xc7caba6e7c5382c9,
-        0xf9bd690a1b68637b,
-        0x9c1661a651213e2d,
-        0xc31bfa0fe5698db8,
-        0xf3e2f893dec3f126,
-        0x986ddb5c6b3a76b8,
-        0xbe89523386091466,
-        0xee2ba6c0678b597f,
-        0x94db483840b717f0,
-        0xba121a4650e4ddec,
-        0xe896a0d7e51e1566,
-        0x915e2486ef32cd60,
-        0xb5b5ada8aaff80b8,
-        0xe3231912d5bf60e6,
-        0x8df5efabc5979c90,
-        0xb1736b96b6fd83b4,
-        0xddd0467c64bce4a1,
-        0x8aa22c0dbef60ee4,
-        0xad4ab7112eb3929e,
-        0xd89d64d57a607745,
-        0x87625f056c7c4a8b,
-        0xa93af6c6c79b5d2e,
-        0xd389b47879823479,
-        0x843610cb4bf160cc,
-        0xa54394fe1eedb8ff,
-        0xce947a3da6a9273e,
-        0x811ccc668829b887,
-        0xa163ff802a3426a9,
-        0xc9bcff6034c13053,
-        0xfc2c3f3841f17c68,
-        0x9d9ba7832936edc1,
-        0xc5029163f384a931,
-        0xf64335bcf065d37d,
-        0x99ea0196163fa42e,
-        0xc06481fb9bcf8d3a,
-        0xf07da27a82c37088,
-        0x964e858c91ba2655,
-        0xbbe226efb628afeb,
-        0xeadab0aba3b2dbe5,
-        0x92c8ae6b464fc96f,
-        0xb77ada0617e3bbcb,
-        0xe55990879ddcaabe,
-        0x8f57fa54c2a9eab7,
-        0xb32df8e9f3546564,
-        0xdff9772470297ebd,
-        0x8bfbea76c619ef36,
-        0xaefae51477a06b04,
-        0xdab99e59958885c5,
-        0x88b402f7fd75539b,
-        0xaae103b5fcd2a882,
-        0xd59944a37c0752a2,
-        0x857fcae62d8493a5,
-        0xa6dfbd9fb8e5b88f,
-        0xd097ad07a71f26b2,
-        0x825ecc24c8737830,
-        0xa2f67f2dfa90563b,
-        0xcbb41ef979346bca,
-        0xfea126b7d78186bd,
-        0x9f24b832e6b0f436,
-        0xc6ede63fa05d3144,
-        0xf8a95fcf88747d94,
-        0x9b69dbe1b548ce7d,
-        0xc24452da229b021c,
-        0xf2d56790ab41c2a3,
-        0x97c560ba6b0919a6,
-        0xbdb6b8e905cb600f,
-        0xed246723473e3813,
-        0x9436c0760c86e30c,
-        0xb94470938fa89bcf,
-        0xe7958cb87392c2c3,
-        0x90bd77f3483bb9ba,
-        0xb4ecd5f01a4aa828,
-        0xe2280b6c20dd5232,
-        0x8d590723948a535f,
-        0xb0af48ec79ace837,
-        0xdcdb1b2798182245,
-        0x8a08f0f8bf0f156b,
-        0xac8b2d36eed2dac6,
-        0xd7adf884aa879177,
-        0x86ccbb52ea94baeb,
-        0xa87fea27a539e9a5,
-        0xd29fe4b18e88640f,
-        0x83a3eeeef9153e89,
-        0xa48ceaaab75a8e2b,
-        0xcdb02555653131b6,
-        0x808e17555f3ebf12,
-        0xa0b19d2ab70e6ed6,
-        0xc8de047564d20a8c,
-        0xfb158592be068d2f,
-        0x9ced737bb6c4183d,
-        0xc428d05aa4751e4d,
-        0xf53304714d9265e0,
-        0x993fe2c6d07b7fac,
-        0xbf8fdb78849a5f97,
-        0xef73d256a5c0f77d,
-        0x95a8637627989aae,
-        0xbb127c53b17ec159,
-        0xe9d71b689dde71b0,
-        0x9226712162ab070e,
-        0xb6b00d69bb55c8d1,
-        0xe45c10c42a2b3b06,
-        0x8eb98a7a9a5b04e3,
-        0xb267ed1940f1c61c,
-        0xdf01e85f912e37a3,
-        0x8b61313bbabce2c6,
-        0xae397d8aa96c1b78,
-        0xd9c7dced53c72256,
-        0x881cea14545c7575,
-        0xaa242499697392d3,
-        0xd4ad2dbfc3d07788,
-        0x84ec3c97da624ab5,
-        0xa6274bbdd0fadd62,
-        0xcfb11ead453994ba,
-        0x81ceb32c4b43fcf5,
-        0xa2425ff75e14fc32,
-        0xcad2f7f5359a3b3e,
-        0xfd87b5f28300ca0e,
-        0x9e74d1b791e07e48,
-        0xc612062576589ddb,
-        0xf79687aed3eec551,
-        0x9abe14cd44753b53,
-        0xc16d9a0095928a27,
-        0xf1c90080baf72cb1,
-        0x971da05074da7bef,
-        0xbce5086492111aeb,
-        0xec1e4a7db69561a5,
-        0x9392ee8e921d5d07,
-        0xb877aa3236a4b449,
-        0xe69594bec44de15b,
-        0x901d7cf73ab0acd9,
-        0xb424dc35095cd80f,
-        0xe12e13424bb40e13,
-        0x8cbccc096f5088cc,
-        0xafebff0bcb24aaff,
-        0xdbe6fecebdedd5bf,
-        0x89705f4136b4a597,
-        0xabcc77118461cefd,
-        0xd6bf94d5e57a42bc,
-        0x8637bd05af6c69b6,
-        0xa7c5ac471b478423,
-        0xd1b71758e219652c,
-        0x83126e978d4fdf3b,
-        0xa3d70a3d70a3d70a,
-        0xcccccccccccccccd,
-        0x8000000000000000,
-        0xa000000000000000,
-        0xc800000000000000,
-        0xfa00000000000000,
-        0x9c40000000000000,
-        0xc350000000000000,
-        0xf424000000000000,
-        0x9896800000000000,
-        0xbebc200000000000,
-        0xee6b280000000000,
-        0x9502f90000000000,
-        0xba43b74000000000,
-        0xe8d4a51000000000,
-        0x9184e72a00000000,
-        0xb5e620f480000000,
-        0xe35fa931a0000000,
-        0x8e1bc9bf04000000,
-        0xb1a2bc2ec5000000,
-        0xde0b6b3a76400000,
-        0x8ac7230489e80000,
-        0xad78ebc5ac620000,
-        0xd8d726b7177a8000,
-        0x878678326eac9000,
-        0xa968163f0a57b400,
-        0xd3c21bcecceda100,
-        0x84595161401484a0,
-        0xa56fa5b99019a5c8,
-        0xcecb8f27f4200f3a,
-        0x813f3978f8940984,
-        0xa18f07d736b90be5,
-        0xc9f2c9cd04674edf,
-        0xfc6f7c4045812296,
-        0x9dc5ada82b70b59e,
-        0xc5371912364ce305,
-        0xf684df56c3e01bc7,
-        0x9a130b963a6c115c,
-        0xc097ce7bc90715b3,
-        0xf0bdc21abb48db20,
-        0x96769950b50d88f4,
-        0xbc143fa4e250eb31,
-        0xeb194f8e1ae525fd,
-        0x92efd1b8d0cf37be,
-        0xb7abc627050305ae,
-        0xe596b7b0c643c719,
-        0x8f7e32ce7bea5c70,
-        0xb35dbf821ae4f38c,
-        0xe0352f62a19e306f,
-        0x8c213d9da502de45,
-        0xaf298d050e4395d7,
-        0xdaf3f04651d47b4c,
-        0x88d8762bf324cd10,
-        0xab0e93b6efee0054,
-        0xd5d238a4abe98068,
-        0x85a36366eb71f041,
-        0xa70c3c40a64e6c52,
-        0xd0cf4b50cfe20766,
-        0x82818f1281ed44a0,
-        0xa321f2d7226895c8,
-        0xcbea6f8ceb02bb3a,
-        0xfee50b7025c36a08,
-        0x9f4f2726179a2245,
-        0xc722f0ef9d80aad6,
-        0xf8ebad2b84e0d58c,
-        0x9b934c3b330c8577,
-        0xc2781f49ffcfa6d5,
-        0xf316271c7fc3908b,
-        0x97edd871cfda3a57,
-        0xbde94e8e43d0c8ec,
-        0xed63a231d4c4fb27,
-        0x945e455f24fb1cf9,
-        0xb975d6b6ee39e437,
-        0xe7d34c64a9c85d44,
-        0x90e40fbeea1d3a4b,
-        0xb51d13aea4a488dd,
-        0xe264589a4dcdab15,
-        0x8d7eb76070a08aed,
-        0xb0de65388cc8ada8,
-        0xdd15fe86affad912,
-        0x8a2dbf142dfcc7ab,
-        0xacb92ed9397bf996,
-        0xd7e77a8f87daf7fc,
-        0x86f0ac99b4e8dafd,
-        0xa8acd7c0222311bd,
-        0xd2d80db02aabd62c,
-        0x83c7088e1aab65db,
-        0xa4b8cab1a1563f52,
-        0xcde6fd5e09abcf27,
-        0x80b05e5ac60b6178,
-        0xa0dc75f1778e39d6,
-        0xc913936dd571c84c,
-        0xfb5878494ace3a5f,
-        0x9d174b2dcec0e47b,
-        0xc45d1df942711d9a,
-        0xf5746577930d6501,
-        0x9968bf6abbe85f20,
-        0xbfc2ef456ae276e9,
-        0xefb3ab16c59b14a3,
-        0x95d04aee3b80ece6,
-        0xbb445da9ca61281f,
-        0xea1575143cf97227,
-        0x924d692ca61be758,
-        0xb6e0c377cfa2e12e,
-        0xe498f455c38b997a,
-        0x8edf98b59a373fec,
-        0xb2977ee300c50fe7,
-        0xdf3d5e9bc0f653e1,
-        0x8b865b215899f46d,
-        0xae67f1e9aec07188,
-        0xda01ee641a708dea,
-        0x884134fe908658b2,
-        0xaa51823e34a7eedf,
-        0xd4e5e2cdc1d1ea96,
-        0x850fadc09923329e,
-        0xa6539930bf6bff46,
-        0xcfe87f7cef46ff17,
-        0x81f14fae158c5f6e,
-        0xa26da3999aef774a,
-        0xcb090c8001ab551c,
-        0xfdcb4fa002162a63,
-        0x9e9f11c4014dda7e,
-        0xc646d63501a1511e,
-        0xf7d88bc24209a565,
-        0x9ae757596946075f,
-        0xc1a12d2fc3978937,
-        0xf209787bb47d6b85,
-        0x9745eb4d50ce6333,
-        0xbd176620a501fc00,
-        0xec5d3fa8ce427b00,
-        0x93ba47c980e98ce0,
-        0xb8a8d9bbe123f018,
-        0xe6d3102ad96cec1e,
-        0x9043ea1ac7e41393,
-        0xb454e4a179dd1877,
-        0xe16a1dc9d8545e95,
-        0x8ce2529e2734bb1d,
-        0xb01ae745b101e9e4,
-        0xdc21a1171d42645d,
-        0x899504ae72497eba,
-        0xabfa45da0edbde69,
-        0xd6f8d7509292d603,
-        0x865b86925b9bc5c2,
-        0xa7f26836f282b733,
-        0xd1ef0244af2364ff,
-        0x8335616aed761f1f,
-        0xa402b9c5a8d3a6e7,
-        0xcd036837130890a1,
-        0x802221226be55a65,
-        0xa02aa96b06deb0fe,
-        0xc83553c5c8965d3d,
-        0xfa42a8b73abbf48d,
-        0x9c69a97284b578d8,
-        0xc38413cf25e2d70e,
-        0xf46518c2ef5b8cd1,
-        0x98bf2f79d5993803,
-        0xbeeefb584aff8604,
-        0xeeaaba2e5dbf6785,
-        0x952ab45cfa97a0b3,
-        0xba756174393d88e0,
-        0xe912b9d1478ceb17,
-        0x91abb422ccb812ef,
-        0xb616a12b7fe617aa,
-        0xe39c49765fdf9d95,
-        0x8e41ade9fbebc27d,
-        0xb1d219647ae6b31c,
-        0xde469fbd99a05fe3,
-        0x8aec23d680043bee,
-        0xada72ccc20054aea,
-        0xd910f7ff28069da4,
-        0x87aa9aff79042287,
-        0xa99541bf57452b28,
-        0xd3fa922f2d1675f2,
-        0x847c9b5d7c2e09b7,
-        0xa59bc234db398c25,
-        0xcf02b2c21207ef2f,
-        0x8161afb94b44f57d,
-        0xa1ba1ba79e1632dc,
-        0xca28a291859bbf93,
-        0xfcb2cb35e702af78,
-        0x9defbf01b061adab,
-        0xc56baec21c7a1916,
-        0xf6c69a72a3989f5c,
-        0x9a3c2087a63f6399,
-        0xc0cb28a98fcf3c80,
-        0xf0fdf2d3f3c30b9f,
-        0x969eb7c47859e744,
-        0xbc4665b596706115,
-        0xeb57ff22fc0c795a,
-        0x9316ff75dd87cbd8,
-        0xb7dcbf5354e9bece,
-        0xe5d3ef282a242e82,
-        0x8fa475791a569d11,
-        0xb38d92d760ec4455,
-        0xe070f78d3927556b,
-        0x8c469ab843b89563,
-        0xaf58416654a6babb,
-        0xdb2e51bfe9d0696a,
-        0x88fcf317f22241e2,
-        0xab3c2fddeeaad25b,
-        0xd60b3bd56a5586f2,
-        0x85c7056562757457,
-        0xa738c6bebb12d16d,
-        0xd106f86e69d785c8,
-        0x82a45b450226b39d,
-        0xa34d721642b06084,
-        0xcc20ce9bd35c78a5,
-        0xff290242c83396ce,
-        0x9f79a169bd203e41,
-        0xc75809c42c684dd1,
-        0xf92e0c3537826146,
-        0x9bbcc7a142b17ccc,
-        0xc2abf989935ddbfe,
-        0xf356f7ebf83552fe,
-        0x98165af37b2153df,
-        0xbe1bf1b059e9a8d6,
-        0xeda2ee1c7064130c,
-        0x9485d4d1c63e8be8,
-        0xb9a74a0637ce2ee1,
-        0xe8111c87c5c1ba9a,
-        0x910ab1d4db9914a0,
-        0xb54d5e4a127f59c8,
-        0xe2a0b5dc971f303a,
-        0x8da471a9de737e24,
-        0xb10d8e1456105dad,
-        0xdd50f1996b947519,
-        0x8a5296ffe33cc930,
-        0xace73cbfdc0bfb7b,
-        0xd8210befd30efa5a,
-        0x8714a775e3e95c78,
-        0xa8d9d1535ce3b396,
-        0xd31045a8341ca07c,
-        0x83ea2b892091e44e,
-        0xa4e4b66b68b65d61,
-        0xce1de40642e3f4b9,
-        0x80d2ae83e9ce78f4,
-        0xa1075a24e4421731,
-        0xc94930ae1d529cfd,
-        0xfb9b7cd9a4a7443c,
-        0x9d412e0806e88aa6,
-        0xc491798a08a2ad4f,
-        0xf5b5d7ec8acb58a3,
-        0x9991a6f3d6bf1766,
-        0xbff610b0cc6edd3f,
-        0xeff394dcff8a948f,
-        0x95f83d0a1fb69cd9,
-        0xbb764c4ca7a44410,
-        0xea53df5fd18d5514,
-        0x92746b9be2f8552c,
-        0xb7118682dbb66a77,
-        0xe4d5e82392a40515,
-        0x8f05b1163ba6832d,
-        0xb2c71d5bca9023f8,
-        0xdf78e4b2bd342cf7,
-        0x8bab8eefb6409c1a,
-        0xae9672aba3d0c321,
-        0xda3c0f568cc4f3e9,
-        0x8865899617fb1871,
-        0xaa7eebfb9df9de8e,
-        0xd51ea6fa85785631,
-        0x8533285c936b35df,
-        0xa67ff273b8460357,
-        0xd01fef10a657842c,
-        0x8213f56a67f6b29c,
-        0xa298f2c501f45f43,
-        0xcb3f2f7642717713,
-        0xfe0efb53d30dd4d8,
-        0x9ec95d1463e8a507,
-        0xc67bb4597ce2ce49,
-        0xf81aa16fdc1b81db,
-        0x9b10a4e5e9913129,
-        0xc1d4ce1f63f57d73,
-        0xf24a01a73cf2dcd0,
-        0x976e41088617ca02,
-        0xbd49d14aa79dbc82,
-        0xec9c459d51852ba3,
-        0x93e1ab8252f33b46,
-        0xb8da1662e7b00a17,
-        0xe7109bfba19c0c9d,
-        0x906a617d450187e2,
-        0xb484f9dc9641e9db,
-        0xe1a63853bbd26451,
-        0x8d07e33455637eb3,
-        0xb049dc016abc5e60,
-        0xdc5c5301c56b75f7,
-        0x89b9b3e11b6329bb,
-        0xac2820d9623bf429,
-        0xd732290fbacaf134,
-        0x867f59a9d4bed6c0,
-        0xa81f301449ee8c70,
-        0xd226fc195c6a2f8c,
-        0x83585d8fd9c25db8,
-        0xa42e74f3d032f526,
-        0xcd3a1230c43fb26f,
-        0x80444b5e7aa7cf85,
-        0xa0555e361951c367,
-        0xc86ab5c39fa63441,
-        0xfa856334878fc151,
-        0x9c935e00d4b9d8d2,
-        0xc3b8358109e84f07,
-        0xf4a642e14c6262c9,
-        0x98e7e9cccfbd7dbe,
-        0xbf21e44003acdd2d,
-        0xeeea5d5004981478,
-        0x95527a5202df0ccb,
-        0xbaa718e68396cffe,
-        0xe950df20247c83fd,
-        0x91d28b7416cdd27e,
-    ],
-    [
-        -1077,
-        -1073,
-        -1070,
-        -1067,
-        -1063,
-        -1060,
-        -1057,
-        -1053,
-        -1050,
-        -1047,
-        -1043,
-        -1040,
-        -1037,
-        -1034,
-        -1030,
-        -1027,
-        -1024,
-        -1020,
-        -1017,
-        -1014,
-        -1010,
-        -1007,
-        -1004,
-        -1000,
-        -997,
-        -994,
-        -990,
-        -987,
-        -984,
-        -980,
-        -977,
-        -974,
-        -970,
-        -967,
-        -964,
-        -960,
-        -957,
-        -954,
-        -950,
-        -947,
-        -944,
-        -940,
-        -937,
-        -934,
-        -931,
-        -927,
-        -924,
-        -921,
-        -917,
-        -914,
-        -911,
-        -907,
-        -904,
-        -901,
-        -897,
-        -894,
-        -891,
-        -887,
-        -884,
-        -881,
-        -877,
-        -874,
-        -871,
-        -867,
-        -864,
-        -861,
-        -857,
-        -854,
-        -851,
-        -847,
-        -844,
-        -841,
-        -838,
-        -834,
-        -831,
-        -828,
-        -824,
-        -821,
-        -818,
-        -814,
-        -811,
-        -808,
-        -804,
-        -801,
-        -798,
-        -794,
-        -791,
-        -788,
-        -784,
-        -781,
-        -778,
-        -774,
-        -771,
-        -768,
-        -764,
-        -761,
-        -758,
-        -754,
-        -751,
-        -748,
-        -744,
-        -741,
-        -738,
-        -735,
-        -731,
-        -728,
-        -725,
-        -721,
-        -718,
-        -715,
-        -711,
-        -708,
-        -705,
-        -701,
-        -698,
-        -695,
-        -691,
-        -688,
-        -685,
-        -681,
-        -678,
-        -675,
-        -671,
-        -668,
-        -665,
-        -661,
-        -658,
-        -655,
-        -651,
-        -648,
-        -645,
-        -642,
-        -638,
-        -635,
-        -632,
-        -628,
-        -625,
-        -622,
-        -618,
-        -615,
-        -612,
-        -608,
-        -605,
-        -602,
-        -598,
-        -595,
-        -592,
-        -588,
-        -585,
-        -582,
-        -578,
-        -575,
-        -572,
-        -568,
-        -565,
-        -562,
-        -558,
-        -555,
-        -552,
-        -549,
-        -545,
-        -542,
-        -539,
-        -535,
-        -532,
-        -529,
-        -525,
-        -522,
-        -519,
-        -515,
-        -512,
-        -509,
-        -505,
-        -502,
-        -499,
-        -495,
-        -492,
-        -489,
-        -485,
-        -482,
-        -479,
-        -475,
-        -472,
-        -469,
-        -465,
-        -462,
-        -459,
-        -455,
-        -452,
-        -449,
-        -446,
-        -442,
-        -439,
-        -436,
-        -432,
-        -429,
-        -426,
-        -422,
-        -419,
-        -416,
-        -412,
-        -409,
-        -406,
-        -402,
-        -399,
-        -396,
-        -392,
-        -389,
-        -386,
-        -382,
-        -379,
-        -376,
-        -372,
-        -369,
-        -366,
-        -362,
-        -359,
-        -356,
-        -353,
-        -349,
-        -346,
-        -343,
-        -339,
-        -336,
-        -333,
-        -329,
-        -326,
-        -323,
-        -319,
-        -316,
-        -313,
-        -309,
-        -306,
-        -303,
-        -299,
-        -296,
-        -293,
-        -289,
-        -286,
-        -283,
-        -279,
-        -276,
-        -273,
-        -269,
-        -266,
-        -263,
-        -259,
-        -256,
-        -253,
-        -250,
-        -246,
-        -243,
-        -240,
-        -236,
-        -233,
-        -230,
-        -226,
-        -223,
-        -220,
-        -216,
-        -213,
-        -210,
-        -206,
-        -203,
-        -200,
-        -196,
-        -193,
-        -190,
-        -186,
-        -183,
-        -180,
-        -176,
-        -173,
-        -170,
-        -166,
-        -163,
-        -160,
-        -157,
-        -153,
-        -150,
-        -147,
-        -143,
-        -140,
-        -137,
-        -133,
-        -130,
-        -127,
-        -123,
-        -120,
-        -117,
-        -113,
-        -110,
-        -107,
-        -103,
-        -100,
-        -97,
-        -93,
-        -90,
-        -87,
-        -83,
-        -80,
-        -77,
-        -73,
-        -70,
-        -67,
-        -63,
-        -60,
-        -57,
-        -54,
-        -50,
-        -47,
-        -44,
-        -40,
-        -37,
-        -34,
-        -30,
-        -27,
-        -24,
-        -20,
-        -17,
-        -14,
-        -10,
-        -7,
-        -4,
-        0,
-        3,
-        6,
-        10,
-        13,
-        16,
-        20,
-        23,
-        26,
-        30,
-        33,
-        36,
-        39,
-        43,
-        46,
-        49,
-        53,
-        56,
-        59,
-        63,
-        66,
-        69,
-        73,
-        76,
-        79,
-        83,
-        86,
-        89,
-        93,
-        96,
-        99,
-        103,
-        106,
-        109,
-        113,
-        116,
-        119,
-        123,
-        126,
-        129,
-        132,
-        136,
-        139,
-        142,
-        146,
-        149,
-        152,
-        156,
-        159,
-        162,
-        166,
-        169,
-        172,
-        176,
-        179,
-        182,
-        186,
-        189,
-        192,
-        196,
-        199,
-        202,
-        206,
-        209,
-        212,
-        216,
-        219,
-        222,
-        226,
-        229,
-        232,
-        235,
-        239,
-        242,
-        245,
-        249,
-        252,
-        255,
-        259,
-        262,
-        265,
-        269,
-        272,
-        275,
-        279,
-        282,
-        285,
-        289,
-        292,
-        295,
-        299,
-        302,
-        305,
-        309,
-        312,
-        315,
-        319,
-        322,
-        325,
-        328,
-        332,
-        335,
-        338,
-        342,
-        345,
-        348,
-        352,
-        355,
-        358,
-        362,
-        365,
-        368,
-        372,
-        375,
-        378,
-        382,
-        385,
-        388,
-        392,
-        395,
-        398,
-        402,
-        405,
-        408,
-        412,
-        415,
-        418,
-        422,
-        425,
-        428,
-        431,
-        435,
-        438,
-        441,
-        445,
-        448,
-        451,
-        455,
-        458,
-        461,
-        465,
-        468,
-        471,
-        475,
-        478,
-        481,
-        485,
-        488,
-        491,
-        495,
-        498,
-        501,
-        505,
-        508,
-        511,
-        515,
-        518,
-        521,
-        524,
-        528,
-        531,
-        534,
-        538,
-        541,
-        544,
-        548,
-        551,
-        554,
-        558,
-        561,
-        564,
-        568,
-        571,
-        574,
-        578,
-        581,
-        584,
-        588,
-        591,
-        594,
-        598,
-        601,
-        604,
-        608,
-        611,
-        614,
-        617,
-        621,
-        624,
-        627,
-        631,
-        634,
-        637,
-        641,
-        644,
-        647,
-        651,
-        654,
-        657,
-        661,
-        664,
-        667,
-        671,
-        674,
-        677,
-        681,
-        684,
-        687,
-        691,
-        694,
-        697,
-        701,
-        704,
-        707,
-        711,
-        714,
-        717,
-        720,
-        724,
-        727,
-        730,
-        734,
-        737,
-        740,
-        744,
-        747,
-        750,
-        754,
-        757,
-        760,
-        764,
-        767,
-        770,
-        774,
-        777,
-        780,
-        784,
-        787,
-        790,
-        794,
-        797,
-        800,
-        804,
-        807,
-        810,
-        813,
-        817,
-        820,
-        823,
-        827,
-        830,
-        833,
-        837,
-        840,
-        843,
-        847,
-        850,
-        853,
-        857,
-        860,
-        863,
-        867,
-        870,
-        873,
-        877,
-        880,
-        883,
-        887,
-        890,
-        893,
-        897,
-        900,
-        903,
-        907,
-        910,
-        913,
-        916,
-        920,
-        923,
-        926,
-        930,
-        933,
-        936,
-        940,
-        943,
-        946,
-        950,
-    ],
-);
-
-#[rustfmt::skip]
-pub const F32_SHORT_POWERS: [f32; 11] = [
-    1e0,
-    1e1,
-    1e2,
-    1e3,
-    1e4,
-    1e5,
-    1e6,
-    1e7,
-    1e8,
-    1e9,
-    1e10,
-];
-
-#[rustfmt::skip]
-pub const F64_SHORT_POWERS: [f64; 23] = [
-    1e0,
-    1e1,
-    1e2,
-    1e3,
-    1e4,
-    1e5,
-    1e6,
-    1e7,
-    1e8,
-    1e9,
-    1e10,
-    1e11,
-    1e12,
-    1e13,
-    1e14,
-    1e15,
-    1e16,
-    1e17,
-    1e18,
-    1e19,
-    1e20,
-    1e21,
-    1e22,
+pub static POWER_OF_FIVE_128: [(u64, u64); N_POWERS_OF_FIVE] = [
+    (0xeef453d6923bd65a, 0x113faa2906a13b3f), // 5^-342
+    (0x9558b4661b6565f8, 0x4ac7ca59a424c507), // 5^-341
+    (0xbaaee17fa23ebf76, 0x5d79bcf00d2df649), // 5^-340
+    (0xe95a99df8ace6f53, 0xf4d82c2c107973dc), // 5^-339
+    (0x91d8a02bb6c10594, 0x79071b9b8a4be869), // 5^-338
+    (0xb64ec836a47146f9, 0x9748e2826cdee284), // 5^-337
+    (0xe3e27a444d8d98b7, 0xfd1b1b2308169b25), // 5^-336
+    (0x8e6d8c6ab0787f72, 0xfe30f0f5e50e20f7), // 5^-335
+    (0xb208ef855c969f4f, 0xbdbd2d335e51a935), // 5^-334
+    (0xde8b2b66b3bc4723, 0xad2c788035e61382), // 5^-333
+    (0x8b16fb203055ac76, 0x4c3bcb5021afcc31), // 5^-332
+    (0xaddcb9e83c6b1793, 0xdf4abe242a1bbf3d), // 5^-331
+    (0xd953e8624b85dd78, 0xd71d6dad34a2af0d), // 5^-330
+    (0x87d4713d6f33aa6b, 0x8672648c40e5ad68), // 5^-329
+    (0xa9c98d8ccb009506, 0x680efdaf511f18c2), // 5^-328
+    (0xd43bf0effdc0ba48, 0x212bd1b2566def2),  // 5^-327
+    (0x84a57695fe98746d, 0x14bb630f7604b57),  // 5^-326
+    (0xa5ced43b7e3e9188, 0x419ea3bd35385e2d), // 5^-325
+    (0xcf42894a5dce35ea, 0x52064cac828675b9), // 5^-324
+    (0x818995ce7aa0e1b2, 0x7343efebd1940993), // 5^-323
+    (0xa1ebfb4219491a1f, 0x1014ebe6c5f90bf8), // 5^-322
+    (0xca66fa129f9b60a6, 0xd41a26e077774ef6), // 5^-321
+    (0xfd00b897478238d0, 0x8920b098955522b4), // 5^-320
+    (0x9e20735e8cb16382, 0x55b46e5f5d5535b0), // 5^-319
+    (0xc5a890362fddbc62, 0xeb2189f734aa831d), // 5^-318
+    (0xf712b443bbd52b7b, 0xa5e9ec7501d523e4), // 5^-317
+    (0x9a6bb0aa55653b2d, 0x47b233c92125366e), // 5^-316
+    (0xc1069cd4eabe89f8, 0x999ec0bb696e840a), // 5^-315
+    (0xf148440a256e2c76, 0xc00670ea43ca250d), // 5^-314
+    (0x96cd2a865764dbca, 0x380406926a5e5728), // 5^-313
+    (0xbc807527ed3e12bc, 0xc605083704f5ecf2), // 5^-312
+    (0xeba09271e88d976b, 0xf7864a44c633682e), // 5^-311
+    (0x93445b8731587ea3, 0x7ab3ee6afbe0211d), // 5^-310
+    (0xb8157268fdae9e4c, 0x5960ea05bad82964), // 5^-309
+    (0xe61acf033d1a45df, 0x6fb92487298e33bd), // 5^-308
+    (0x8fd0c16206306bab, 0xa5d3b6d479f8e056), // 5^-307
+    (0xb3c4f1ba87bc8696, 0x8f48a4899877186c), // 5^-306
+    (0xe0b62e2929aba83c, 0x331acdabfe94de87), // 5^-305
+    (0x8c71dcd9ba0b4925, 0x9ff0c08b7f1d0b14), // 5^-304
+    (0xaf8e5410288e1b6f, 0x7ecf0ae5ee44dd9),  // 5^-303
+    (0xdb71e91432b1a24a, 0xc9e82cd9f69d6150), // 5^-302
+    (0x892731ac9faf056e, 0xbe311c083a225cd2), // 5^-301
+    (0xab70fe17c79ac6ca, 0x6dbd630a48aaf406), // 5^-300
+    (0xd64d3d9db981787d, 0x92cbbccdad5b108),  // 5^-299
+    (0x85f0468293f0eb4e, 0x25bbf56008c58ea5), // 5^-298
+    (0xa76c582338ed2621, 0xaf2af2b80af6f24e), // 5^-297
+    (0xd1476e2c07286faa, 0x1af5af660db4aee1), // 5^-296
+    (0x82cca4db847945ca, 0x50d98d9fc890ed4d), // 5^-295
+    (0xa37fce126597973c, 0xe50ff107bab528a0), // 5^-294
+    (0xcc5fc196fefd7d0c, 0x1e53ed49a96272c8), // 5^-293
+    (0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7a), // 5^-292
+    (0x9faacf3df73609b1, 0x77b191618c54e9ac), // 5^-291
+    (0xc795830d75038c1d, 0xd59df5b9ef6a2417), // 5^-290
+    (0xf97ae3d0d2446f25, 0x4b0573286b44ad1d), // 5^-289
+    (0x9becce62836ac577, 0x4ee367f9430aec32), // 5^-288
+    (0xc2e801fb244576d5, 0x229c41f793cda73f), // 5^-287
+    (0xf3a20279ed56d48a, 0x6b43527578c1110f), // 5^-286
+    (0x9845418c345644d6, 0x830a13896b78aaa9), // 5^-285
+    (0xbe5691ef416bd60c, 0x23cc986bc656d553), // 5^-284
+    (0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa8), // 5^-283
+    (0x94b3a202eb1c3f39, 0x7bf7d71432f3d6a9), // 5^-282
+    (0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc53), // 5^-281
+    (0xe858ad248f5c22c9, 0xd1b3400f8f9cff68), // 5^-280
+    (0x91376c36d99995be, 0x23100809b9c21fa1), // 5^-279
+    (0xb58547448ffffb2d, 0xabd40a0c2832a78a), // 5^-278
+    (0xe2e69915b3fff9f9, 0x16c90c8f323f516c), // 5^-277
+    (0x8dd01fad907ffc3b, 0xae3da7d97f6792e3), // 5^-276
+    (0xb1442798f49ffb4a, 0x99cd11cfdf41779c), // 5^-275
+    (0xdd95317f31c7fa1d, 0x40405643d711d583), // 5^-274
+    (0x8a7d3eef7f1cfc52, 0x482835ea666b2572), // 5^-273
+    (0xad1c8eab5ee43b66, 0xda3243650005eecf), // 5^-272
+    (0xd863b256369d4a40, 0x90bed43e40076a82), // 5^-271
+    (0x873e4f75e2224e68, 0x5a7744a6e804a291), // 5^-270
+    (0xa90de3535aaae202, 0x711515d0a205cb36), // 5^-269
+    (0xd3515c2831559a83, 0xd5a5b44ca873e03),  // 5^-268
+    (0x8412d9991ed58091, 0xe858790afe9486c2), // 5^-267
+    (0xa5178fff668ae0b6, 0x626e974dbe39a872), // 5^-266
+    (0xce5d73ff402d98e3, 0xfb0a3d212dc8128f), // 5^-265
+    (0x80fa687f881c7f8e, 0x7ce66634bc9d0b99), // 5^-264
+    (0xa139029f6a239f72, 0x1c1fffc1ebc44e80), // 5^-263
+    (0xc987434744ac874e, 0xa327ffb266b56220), // 5^-262
+    (0xfbe9141915d7a922, 0x4bf1ff9f0062baa8), // 5^-261
+    (0x9d71ac8fada6c9b5, 0x6f773fc3603db4a9), // 5^-260
+    (0xc4ce17b399107c22, 0xcb550fb4384d21d3), // 5^-259
+    (0xf6019da07f549b2b, 0x7e2a53a146606a48), // 5^-258
+    (0x99c102844f94e0fb, 0x2eda7444cbfc426d), // 5^-257
+    (0xc0314325637a1939, 0xfa911155fefb5308), // 5^-256
+    (0xf03d93eebc589f88, 0x793555ab7eba27ca), // 5^-255
+    (0x96267c7535b763b5, 0x4bc1558b2f3458de), // 5^-254
+    (0xbbb01b9283253ca2, 0x9eb1aaedfb016f16), // 5^-253
+    (0xea9c227723ee8bcb, 0x465e15a979c1cadc), // 5^-252
+    (0x92a1958a7675175f, 0xbfacd89ec191ec9),  // 5^-251
+    (0xb749faed14125d36, 0xcef980ec671f667b), // 5^-250
+    (0xe51c79a85916f484, 0x82b7e12780e7401a), // 5^-249
+    (0x8f31cc0937ae58d2, 0xd1b2ecb8b0908810), // 5^-248
+    (0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa15), // 5^-247
+    (0xdfbdcece67006ac9, 0x67a791e093e1d49a), // 5^-246
+    (0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e0), // 5^-245
+    (0xaecc49914078536d, 0x58fae9f773886e18), // 5^-244
+    (0xda7f5bf590966848, 0xaf39a475506a899e), // 5^-243
+    (0x888f99797a5e012d, 0x6d8406c952429603), // 5^-242
+    (0xaab37fd7d8f58178, 0xc8e5087ba6d33b83), // 5^-241
+    (0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a64), // 5^-240
+    (0x855c3be0a17fcd26, 0x5cf2eea09a55067f), // 5^-239
+    (0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481e), // 5^-238
+    (0xd0601d8efc57b08b, 0xf13b94daf124da26), // 5^-237
+    (0x823c12795db6ce57, 0x76c53d08d6b70858), // 5^-236
+    (0xa2cb1717b52481ed, 0x54768c4b0c64ca6e), // 5^-235
+    (0xcb7ddcdda26da268, 0xa9942f5dcf7dfd09), // 5^-234
+    (0xfe5d54150b090b02, 0xd3f93b35435d7c4c), // 5^-233
+    (0x9efa548d26e5a6e1, 0xc47bc5014a1a6daf), // 5^-232
+    (0xc6b8e9b0709f109a, 0x359ab6419ca1091b), // 5^-231
+    (0xf867241c8cc6d4c0, 0xc30163d203c94b62), // 5^-230
+    (0x9b407691d7fc44f8, 0x79e0de63425dcf1d), // 5^-229
+    (0xc21094364dfb5636, 0x985915fc12f542e4), // 5^-228
+    (0xf294b943e17a2bc4, 0x3e6f5b7b17b2939d), // 5^-227
+    (0x979cf3ca6cec5b5a, 0xa705992ceecf9c42), // 5^-226
+    (0xbd8430bd08277231, 0x50c6ff782a838353), // 5^-225
+    (0xece53cec4a314ebd, 0xa4f8bf5635246428), // 5^-224
+    (0x940f4613ae5ed136, 0x871b7795e136be99), // 5^-223
+    (0xb913179899f68584, 0x28e2557b59846e3f), // 5^-222
+    (0xe757dd7ec07426e5, 0x331aeada2fe589cf), // 5^-221
+    (0x9096ea6f3848984f, 0x3ff0d2c85def7621), // 5^-220
+    (0xb4bca50b065abe63, 0xfed077a756b53a9),  // 5^-219
+    (0xe1ebce4dc7f16dfb, 0xd3e8495912c62894), // 5^-218
+    (0x8d3360f09cf6e4bd, 0x64712dd7abbbd95c), // 5^-217
+    (0xb080392cc4349dec, 0xbd8d794d96aacfb3), // 5^-216
+    (0xdca04777f541c567, 0xecf0d7a0fc5583a0), // 5^-215
+    (0x89e42caaf9491b60, 0xf41686c49db57244), // 5^-214
+    (0xac5d37d5b79b6239, 0x311c2875c522ced5), // 5^-213
+    (0xd77485cb25823ac7, 0x7d633293366b828b), // 5^-212
+    (0x86a8d39ef77164bc, 0xae5dff9c02033197), // 5^-211
+    (0xa8530886b54dbdeb, 0xd9f57f830283fdfc), // 5^-210
+    (0xd267caa862a12d66, 0xd072df63c324fd7b), // 5^-209
+    (0x8380dea93da4bc60, 0x4247cb9e59f71e6d), // 5^-208
+    (0xa46116538d0deb78, 0x52d9be85f074e608), // 5^-207
+    (0xcd795be870516656, 0x67902e276c921f8b), // 5^-206
+    (0x806bd9714632dff6, 0xba1cd8a3db53b6),   // 5^-205
+    (0xa086cfcd97bf97f3, 0x80e8a40eccd228a4), // 5^-204
+    (0xc8a883c0fdaf7df0, 0x6122cd128006b2cd), // 5^-203
+    (0xfad2a4b13d1b5d6c, 0x796b805720085f81), // 5^-202
+    (0x9cc3a6eec6311a63, 0xcbe3303674053bb0), // 5^-201
+    (0xc3f490aa77bd60fc, 0xbedbfc4411068a9c), // 5^-200
+    (0xf4f1b4d515acb93b, 0xee92fb5515482d44), // 5^-199
+    (0x991711052d8bf3c5, 0x751bdd152d4d1c4a), // 5^-198
+    (0xbf5cd54678eef0b6, 0xd262d45a78a0635d), // 5^-197
+    (0xef340a98172aace4, 0x86fb897116c87c34), // 5^-196
+    (0x9580869f0e7aac0e, 0xd45d35e6ae3d4da0), // 5^-195
+    (0xbae0a846d2195712, 0x8974836059cca109), // 5^-194
+    (0xe998d258869facd7, 0x2bd1a438703fc94b), // 5^-193
+    (0x91ff83775423cc06, 0x7b6306a34627ddcf), // 5^-192
+    (0xb67f6455292cbf08, 0x1a3bc84c17b1d542), // 5^-191
+    (0xe41f3d6a7377eeca, 0x20caba5f1d9e4a93), // 5^-190
+    (0x8e938662882af53e, 0x547eb47b7282ee9c), // 5^-189
+    (0xb23867fb2a35b28d, 0xe99e619a4f23aa43), // 5^-188
+    (0xdec681f9f4c31f31, 0x6405fa00e2ec94d4), // 5^-187
+    (0x8b3c113c38f9f37e, 0xde83bc408dd3dd04), // 5^-186
+    (0xae0b158b4738705e, 0x9624ab50b148d445), // 5^-185
+    (0xd98ddaee19068c76, 0x3badd624dd9b0957), // 5^-184
+    (0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d6), // 5^-183
+    (0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4c), // 5^-182
+    (0xd47487cc8470652b, 0x7647c3200069671f), // 5^-181
+    (0x84c8d4dfd2c63f3b, 0x29ecd9f40041e073), // 5^-180
+    (0xa5fb0a17c777cf09, 0xf468107100525890), // 5^-179
+    (0xcf79cc9db955c2cc, 0x7182148d4066eeb4), // 5^-178
+    (0x81ac1fe293d599bf, 0xc6f14cd848405530), // 5^-177
+    (0xa21727db38cb002f, 0xb8ada00e5a506a7c), // 5^-176
+    (0xca9cf1d206fdc03b, 0xa6d90811f0e4851c), // 5^-175
+    (0xfd442e4688bd304a, 0x908f4a166d1da663), // 5^-174
+    (0x9e4a9cec15763e2e, 0x9a598e4e043287fe), // 5^-173
+    (0xc5dd44271ad3cdba, 0x40eff1e1853f29fd), // 5^-172
+    (0xf7549530e188c128, 0xd12bee59e68ef47c), // 5^-171
+    (0x9a94dd3e8cf578b9, 0x82bb74f8301958ce), // 5^-170
+    (0xc13a148e3032d6e7, 0xe36a52363c1faf01), // 5^-169
+    (0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac1), // 5^-168
+    (0x96f5600f15a7b7e5, 0x29ab103a5ef8c0b9), // 5^-167
+    (0xbcb2b812db11a5de, 0x7415d448f6b6f0e7), // 5^-166
+    (0xebdf661791d60f56, 0x111b495b3464ad21), // 5^-165
+    (0x936b9fcebb25c995, 0xcab10dd900beec34), // 5^-164
+    (0xb84687c269ef3bfb, 0x3d5d514f40eea742), // 5^-163
+    (0xe65829b3046b0afa, 0xcb4a5a3112a5112),  // 5^-162
+    (0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ab), // 5^-161
+    (0xb3f4e093db73a093, 0x59ed216765690f56), // 5^-160
+    (0xe0f218b8d25088b8, 0x306869c13ec3532c), // 5^-159
+    (0x8c974f7383725573, 0x1e414218c73a13fb), // 5^-158
+    (0xafbd2350644eeacf, 0xe5d1929ef90898fa), // 5^-157
+    (0xdbac6c247d62a583, 0xdf45f746b74abf39), // 5^-156
+    (0x894bc396ce5da772, 0x6b8bba8c328eb783), // 5^-155
+    (0xab9eb47c81f5114f, 0x66ea92f3f326564),  // 5^-154
+    (0xd686619ba27255a2, 0xc80a537b0efefebd), // 5^-153
+    (0x8613fd0145877585, 0xbd06742ce95f5f36), // 5^-152
+    (0xa798fc4196e952e7, 0x2c48113823b73704), // 5^-151
+    (0xd17f3b51fca3a7a0, 0xf75a15862ca504c5), // 5^-150
+    (0x82ef85133de648c4, 0x9a984d73dbe722fb), // 5^-149
+    (0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebba), // 5^-148
+    (0xcc963fee10b7d1b3, 0x318df905079926a8), // 5^-147
+    (0xffbbcfe994e5c61f, 0xfdf17746497f7052), // 5^-146
+    (0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa633), // 5^-145
+    (0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc0), // 5^-144
+    (0xf9bd690a1b68637b, 0x3dfdce7aa3c673b0), // 5^-143
+    (0x9c1661a651213e2d, 0x6bea10ca65c084e),  // 5^-142
+    (0xc31bfa0fe5698db8, 0x486e494fcff30a62), // 5^-141
+    (0xf3e2f893dec3f126, 0x5a89dba3c3efccfa), // 5^-140
+    (0x986ddb5c6b3a76b7, 0xf89629465a75e01c), // 5^-139
+    (0xbe89523386091465, 0xf6bbb397f1135823), // 5^-138
+    (0xee2ba6c0678b597f, 0x746aa07ded582e2c), // 5^-137
+    (0x94db483840b717ef, 0xa8c2a44eb4571cdc), // 5^-136
+    (0xba121a4650e4ddeb, 0x92f34d62616ce413), // 5^-135
+    (0xe896a0d7e51e1566, 0x77b020baf9c81d17), // 5^-134
+    (0x915e2486ef32cd60, 0xace1474dc1d122e),  // 5^-133
+    (0xb5b5ada8aaff80b8, 0xd819992132456ba),  // 5^-132
+    (0xe3231912d5bf60e6, 0x10e1fff697ed6c69), // 5^-131
+    (0x8df5efabc5979c8f, 0xca8d3ffa1ef463c1), // 5^-130
+    (0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb2), // 5^-129
+    (0xddd0467c64bce4a0, 0xac7cb3f6d05ddbde), // 5^-128
+    (0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96b), // 5^-127
+    (0xad4ab7112eb3929d, 0x86c16c98d2c953c6), // 5^-126
+    (0xd89d64d57a607744, 0xe871c7bf077ba8b7), // 5^-125
+    (0x87625f056c7c4a8b, 0x11471cd764ad4972), // 5^-124
+    (0xa93af6c6c79b5d2d, 0xd598e40d3dd89bcf), // 5^-123
+    (0xd389b47879823479, 0x4aff1d108d4ec2c3), // 5^-122
+    (0x843610cb4bf160cb, 0xcedf722a585139ba), // 5^-121
+    (0xa54394fe1eedb8fe, 0xc2974eb4ee658828), // 5^-120
+    (0xce947a3da6a9273e, 0x733d226229feea32), // 5^-119
+    (0x811ccc668829b887, 0x806357d5a3f525f),  // 5^-118
+    (0xa163ff802a3426a8, 0xca07c2dcb0cf26f7), // 5^-117
+    (0xc9bcff6034c13052, 0xfc89b393dd02f0b5), // 5^-116
+    (0xfc2c3f3841f17c67, 0xbbac2078d443ace2), // 5^-115
+    (0x9d9ba7832936edc0, 0xd54b944b84aa4c0d), // 5^-114
+    (0xc5029163f384a931, 0xa9e795e65d4df11),  // 5^-113
+    (0xf64335bcf065d37d, 0x4d4617b5ff4a16d5), // 5^-112
+    (0x99ea0196163fa42e, 0x504bced1bf8e4e45), // 5^-111
+    (0xc06481fb9bcf8d39, 0xe45ec2862f71e1d6), // 5^-110
+    (0xf07da27a82c37088, 0x5d767327bb4e5a4c), // 5^-109
+    (0x964e858c91ba2655, 0x3a6a07f8d510f86f), // 5^-108
+    (0xbbe226efb628afea, 0x890489f70a55368b), // 5^-107
+    (0xeadab0aba3b2dbe5, 0x2b45ac74ccea842e), // 5^-106
+    (0x92c8ae6b464fc96f, 0x3b0b8bc90012929d), // 5^-105
+    (0xb77ada0617e3bbcb, 0x9ce6ebb40173744),  // 5^-104
+    (0xe55990879ddcaabd, 0xcc420a6a101d0515), // 5^-103
+    (0x8f57fa54c2a9eab6, 0x9fa946824a12232d), // 5^-102
+    (0xb32df8e9f3546564, 0x47939822dc96abf9), // 5^-101
+    (0xdff9772470297ebd, 0x59787e2b93bc56f7), // 5^-100
+    (0x8bfbea76c619ef36, 0x57eb4edb3c55b65a), // 5^-99
+    (0xaefae51477a06b03, 0xede622920b6b23f1), // 5^-98
+    (0xdab99e59958885c4, 0xe95fab368e45eced), // 5^-97
+    (0x88b402f7fd75539b, 0x11dbcb0218ebb414), // 5^-96
+    (0xaae103b5fcd2a881, 0xd652bdc29f26a119), // 5^-95
+    (0xd59944a37c0752a2, 0x4be76d3346f0495f), // 5^-94
+    (0x857fcae62d8493a5, 0x6f70a4400c562ddb), // 5^-93
+    (0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb952), // 5^-92
+    (0xd097ad07a71f26b2, 0x7e2000a41346a7a7), // 5^-91
+    (0x825ecc24c873782f, 0x8ed400668c0c28c8), // 5^-90
+    (0xa2f67f2dfa90563b, 0x728900802f0f32fa), // 5^-89
+    (0xcbb41ef979346bca, 0x4f2b40a03ad2ffb9), // 5^-88
+    (0xfea126b7d78186bc, 0xe2f610c84987bfa8), // 5^-87
+    (0x9f24b832e6b0f436, 0xdd9ca7d2df4d7c9),  // 5^-86
+    (0xc6ede63fa05d3143, 0x91503d1c79720dbb), // 5^-85
+    (0xf8a95fcf88747d94, 0x75a44c6397ce912a), // 5^-84
+    (0x9b69dbe1b548ce7c, 0xc986afbe3ee11aba), // 5^-83
+    (0xc24452da229b021b, 0xfbe85badce996168), // 5^-82
+    (0xf2d56790ab41c2a2, 0xfae27299423fb9c3), // 5^-81
+    (0x97c560ba6b0919a5, 0xdccd879fc967d41a), // 5^-80
+    (0xbdb6b8e905cb600f, 0x5400e987bbc1c920), // 5^-79
+    (0xed246723473e3813, 0x290123e9aab23b68), // 5^-78
+    (0x9436c0760c86e30b, 0xf9a0b6720aaf6521), // 5^-77
+    (0xb94470938fa89bce, 0xf808e40e8d5b3e69), // 5^-76
+    (0xe7958cb87392c2c2, 0xb60b1d1230b20e04), // 5^-75
+    (0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c2), // 5^-74
+    (0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af3), // 5^-73
+    (0xe2280b6c20dd5232, 0x25c6da63c38de1b0), // 5^-72
+    (0x8d590723948a535f, 0x579c487e5a38ad0e), // 5^-71
+    (0xb0af48ec79ace837, 0x2d835a9df0c6d851), // 5^-70
+    (0xdcdb1b2798182244, 0xf8e431456cf88e65), // 5^-69
+    (0x8a08f0f8bf0f156b, 0x1b8e9ecb641b58ff), // 5^-68
+    (0xac8b2d36eed2dac5, 0xe272467e3d222f3f), // 5^-67
+    (0xd7adf884aa879177, 0x5b0ed81dcc6abb0f), // 5^-66
+    (0x86ccbb52ea94baea, 0x98e947129fc2b4e9), // 5^-65
+    (0xa87fea27a539e9a5, 0x3f2398d747b36224), // 5^-64
+    (0xd29fe4b18e88640e, 0x8eec7f0d19a03aad), // 5^-63
+    (0x83a3eeeef9153e89, 0x1953cf68300424ac), // 5^-62
+    (0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd7), // 5^-61
+    (0xcdb02555653131b6, 0x3792f412cb06794d), // 5^-60
+    (0x808e17555f3ebf11, 0xe2bbd88bbee40bd0), // 5^-59
+    (0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec4), // 5^-58
+    (0xc8de047564d20a8b, 0xf245825a5a445275), // 5^-57
+    (0xfb158592be068d2e, 0xeed6e2f0f0d56712), // 5^-56
+    (0x9ced737bb6c4183d, 0x55464dd69685606b), // 5^-55
+    (0xc428d05aa4751e4c, 0xaa97e14c3c26b886), // 5^-54
+    (0xf53304714d9265df, 0xd53dd99f4b3066a8), // 5^-53
+    (0x993fe2c6d07b7fab, 0xe546a8038efe4029), // 5^-52
+    (0xbf8fdb78849a5f96, 0xde98520472bdd033), // 5^-51
+    (0xef73d256a5c0f77c, 0x963e66858f6d4440), // 5^-50
+    (0x95a8637627989aad, 0xdde7001379a44aa8), // 5^-49
+    (0xbb127c53b17ec159, 0x5560c018580d5d52), // 5^-48
+    (0xe9d71b689dde71af, 0xaab8f01e6e10b4a6), // 5^-47
+    (0x9226712162ab070d, 0xcab3961304ca70e8), // 5^-46
+    (0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d22), // 5^-45
+    (0xe45c10c42a2b3b05, 0x8cb89a7db77c506a), // 5^-44
+    (0x8eb98a7a9a5b04e3, 0x77f3608e92adb242), // 5^-43
+    (0xb267ed1940f1c61c, 0x55f038b237591ed3), // 5^-42
+    (0xdf01e85f912e37a3, 0x6b6c46dec52f6688), // 5^-41
+    (0x8b61313bbabce2c6, 0x2323ac4b3b3da015), // 5^-40
+    (0xae397d8aa96c1b77, 0xabec975e0a0d081a), // 5^-39
+    (0xd9c7dced53c72255, 0x96e7bd358c904a21), // 5^-38
+    (0x881cea14545c7575, 0x7e50d64177da2e54), // 5^-37
+    (0xaa242499697392d2, 0xdde50bd1d5d0b9e9), // 5^-36
+    (0xd4ad2dbfc3d07787, 0x955e4ec64b44e864), // 5^-35
+    (0x84ec3c97da624ab4, 0xbd5af13bef0b113e), // 5^-34
+    (0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58e), // 5^-33
+    (0xcfb11ead453994ba, 0x67de18eda5814af2), // 5^-32
+    (0x81ceb32c4b43fcf4, 0x80eacf948770ced7), // 5^-31
+    (0xa2425ff75e14fc31, 0xa1258379a94d028d), // 5^-30
+    (0xcad2f7f5359a3b3e, 0x96ee45813a04330),  // 5^-29
+    (0xfd87b5f28300ca0d, 0x8bca9d6e188853fc), // 5^-28
+    (0x9e74d1b791e07e48, 0x775ea264cf55347e), // 5^-27
+    (0xc612062576589dda, 0x95364afe032a819e), // 5^-26
+    (0xf79687aed3eec551, 0x3a83ddbd83f52205), // 5^-25
+    (0x9abe14cd44753b52, 0xc4926a9672793543), // 5^-24
+    (0xc16d9a0095928a27, 0x75b7053c0f178294), // 5^-23
+    (0xf1c90080baf72cb1, 0x5324c68b12dd6339), // 5^-22
+    (0x971da05074da7bee, 0xd3f6fc16ebca5e04), // 5^-21
+    (0xbce5086492111aea, 0x88f4bb1ca6bcf585), // 5^-20
+    (0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6), // 5^-19
+    (0x9392ee8e921d5d07, 0x3aff322e62439fd0), // 5^-18
+    (0xb877aa3236a4b449, 0x9befeb9fad487c3),  // 5^-17
+    (0xe69594bec44de15b, 0x4c2ebe687989a9b4), // 5^-16
+    (0x901d7cf73ab0acd9, 0xf9d37014bf60a11),  // 5^-15
+    (0xb424dc35095cd80f, 0x538484c19ef38c95), // 5^-14
+    (0xe12e13424bb40e13, 0x2865a5f206b06fba), // 5^-13
+    (0x8cbccc096f5088cb, 0xf93f87b7442e45d4), // 5^-12
+    (0xafebff0bcb24aafe, 0xf78f69a51539d749), // 5^-11
+    (0xdbe6fecebdedd5be, 0xb573440e5a884d1c), // 5^-10
+    (0x89705f4136b4a597, 0x31680a88f8953031), // 5^-9
+    (0xabcc77118461cefc, 0xfdc20d2b36ba7c3e), // 5^-8
+    (0xd6bf94d5e57a42bc, 0x3d32907604691b4d), // 5^-7
+    (0x8637bd05af6c69b5, 0xa63f9a49c2c1b110), // 5^-6
+    (0xa7c5ac471b478423, 0xfcf80dc33721d54),  // 5^-5
+    (0xd1b71758e219652b, 0xd3c36113404ea4a9), // 5^-4
+    (0x83126e978d4fdf3b, 0x645a1cac083126ea), // 5^-3
+    (0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4), // 5^-2
+    (0xcccccccccccccccc, 0xcccccccccccccccd), // 5^-1
+    (0x8000000000000000, 0x0),                // 5^0
+    (0xa000000000000000, 0x0),                // 5^1
+    (0xc800000000000000, 0x0),                // 5^2
+    (0xfa00000000000000, 0x0),                // 5^3
+    (0x9c40000000000000, 0x0),                // 5^4
+    (0xc350000000000000, 0x0),                // 5^5
+    (0xf424000000000000, 0x0),                // 5^6
+    (0x9896800000000000, 0x0),                // 5^7
+    (0xbebc200000000000, 0x0),                // 5^8
+    (0xee6b280000000000, 0x0),                // 5^9
+    (0x9502f90000000000, 0x0),                // 5^10
+    (0xba43b74000000000, 0x0),                // 5^11
+    (0xe8d4a51000000000, 0x0),                // 5^12
+    (0x9184e72a00000000, 0x0),                // 5^13
+    (0xb5e620f480000000, 0x0),                // 5^14
+    (0xe35fa931a0000000, 0x0),                // 5^15
+    (0x8e1bc9bf04000000, 0x0),                // 5^16
+    (0xb1a2bc2ec5000000, 0x0),                // 5^17
+    (0xde0b6b3a76400000, 0x0),                // 5^18
+    (0x8ac7230489e80000, 0x0),                // 5^19
+    (0xad78ebc5ac620000, 0x0),                // 5^20
+    (0xd8d726b7177a8000, 0x0),                // 5^21
+    (0x878678326eac9000, 0x0),                // 5^22
+    (0xa968163f0a57b400, 0x0),                // 5^23
+    (0xd3c21bcecceda100, 0x0),                // 5^24
+    (0x84595161401484a0, 0x0),                // 5^25
+    (0xa56fa5b99019a5c8, 0x0),                // 5^26
+    (0xcecb8f27f4200f3a, 0x0),                // 5^27
+    (0x813f3978f8940984, 0x4000000000000000), // 5^28
+    (0xa18f07d736b90be5, 0x5000000000000000), // 5^29
+    (0xc9f2c9cd04674ede, 0xa400000000000000), // 5^30
+    (0xfc6f7c4045812296, 0x4d00000000000000), // 5^31
+    (0x9dc5ada82b70b59d, 0xf020000000000000), // 5^32
+    (0xc5371912364ce305, 0x6c28000000000000), // 5^33
+    (0xf684df56c3e01bc6, 0xc732000000000000), // 5^34
+    (0x9a130b963a6c115c, 0x3c7f400000000000), // 5^35
+    (0xc097ce7bc90715b3, 0x4b9f100000000000), // 5^36
+    (0xf0bdc21abb48db20, 0x1e86d40000000000), // 5^37
+    (0x96769950b50d88f4, 0x1314448000000000), // 5^38
+    (0xbc143fa4e250eb31, 0x17d955a000000000), // 5^39
+    (0xeb194f8e1ae525fd, 0x5dcfab0800000000), // 5^40
+    (0x92efd1b8d0cf37be, 0x5aa1cae500000000), // 5^41
+    (0xb7abc627050305ad, 0xf14a3d9e40000000), // 5^42
+    (0xe596b7b0c643c719, 0x6d9ccd05d0000000), // 5^43
+    (0x8f7e32ce7bea5c6f, 0xe4820023a2000000), // 5^44
+    (0xb35dbf821ae4f38b, 0xdda2802c8a800000), // 5^45
+    (0xe0352f62a19e306e, 0xd50b2037ad200000), // 5^46
+    (0x8c213d9da502de45, 0x4526f422cc340000), // 5^47
+    (0xaf298d050e4395d6, 0x9670b12b7f410000), // 5^48
+    (0xdaf3f04651d47b4c, 0x3c0cdd765f114000), // 5^49
+    (0x88d8762bf324cd0f, 0xa5880a69fb6ac800), // 5^50
+    (0xab0e93b6efee0053, 0x8eea0d047a457a00), // 5^51
+    (0xd5d238a4abe98068, 0x72a4904598d6d880), // 5^52
+    (0x85a36366eb71f041, 0x47a6da2b7f864750), // 5^53
+    (0xa70c3c40a64e6c51, 0x999090b65f67d924), // 5^54
+    (0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d), // 5^55
+    (0x82818f1281ed449f, 0xbff8f10e7a8921a4), // 5^56
+    (0xa321f2d7226895c7, 0xaff72d52192b6a0d), // 5^57
+    (0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490), // 5^58
+    (0xfee50b7025c36a08, 0x2f236d04753d5b4),  // 5^59
+    (0x9f4f2726179a2245, 0x1d762422c946590),  // 5^60
+    (0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5), // 5^61
+    (0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2), // 5^62
+    (0x9b934c3b330c8577, 0x63cc55f49f88eb2f), // 5^63
+    (0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb), // 5^64
+    (0xf316271c7fc3908a, 0x8bef464e3945ef7a), // 5^65
+    (0x97edd871cfda3a56, 0x97758bf0e3cbb5ac), // 5^66
+    (0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317), // 5^67
+    (0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd), // 5^68
+    (0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a), // 5^69
+    (0xb975d6b6ee39e436, 0xb3e2fd538e122b44), // 5^70
+    (0xe7d34c64a9c85d44, 0x60dbbca87196b616), // 5^71
+    (0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd), // 5^72
+    (0xb51d13aea4a488dd, 0x6babab6398bdbe41), // 5^73
+    (0xe264589a4dcdab14, 0xc696963c7eed2dd1), // 5^74
+    (0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2), // 5^75
+    (0xb0de65388cc8ada8, 0x3b25a55f43294bcb), // 5^76
+    (0xdd15fe86affad912, 0x49ef0eb713f39ebe), // 5^77
+    (0x8a2dbf142dfcc7ab, 0x6e3569326c784337), // 5^78
+    (0xacb92ed9397bf996, 0x49c2c37f07965404), // 5^79
+    (0xd7e77a8f87daf7fb, 0xdc33745ec97be906), // 5^80
+    (0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3), // 5^81
+    (0xa8acd7c0222311bc, 0xc40832ea0d68ce0c), // 5^82
+    (0xd2d80db02aabd62b, 0xf50a3fa490c30190), // 5^83
+    (0x83c7088e1aab65db, 0x792667c6da79e0fa), // 5^84
+    (0xa4b8cab1a1563f52, 0x577001b891185938), // 5^85
+    (0xcde6fd5e09abcf26, 0xed4c0226b55e6f86), // 5^86
+    (0x80b05e5ac60b6178, 0x544f8158315b05b4), // 5^87
+    (0xa0dc75f1778e39d6, 0x696361ae3db1c721), // 5^88
+    (0xc913936dd571c84c, 0x3bc3a19cd1e38e9),  // 5^89
+    (0xfb5878494ace3a5f, 0x4ab48a04065c723),  // 5^90
+    (0x9d174b2dcec0e47b, 0x62eb0d64283f9c76), // 5^91
+    (0xc45d1df942711d9a, 0x3ba5d0bd324f8394), // 5^92
+    (0xf5746577930d6500, 0xca8f44ec7ee36479), // 5^93
+    (0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb), // 5^94
+    (0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e), // 5^95
+    (0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e), // 5^96
+    (0x95d04aee3b80ece5, 0xbba1f1d158724a12), // 5^97
+    (0xbb445da9ca61281f, 0x2a8a6e45ae8edc97), // 5^98
+    (0xea1575143cf97226, 0xf52d09d71a3293bd), // 5^99
+    (0x924d692ca61be758, 0x593c2626705f9c56), // 5^100
+    (0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c), // 5^101
+    (0xe498f455c38b997a, 0xb6dfb9c0f956447),  // 5^102
+    (0x8edf98b59a373fec, 0x4724bd4189bd5eac), // 5^103
+    (0xb2977ee300c50fe7, 0x58edec91ec2cb657), // 5^104
+    (0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed), // 5^105
+    (0x8b865b215899f46c, 0xbd79e0d20082ee74), // 5^106
+    (0xae67f1e9aec07187, 0xecd8590680a3aa11), // 5^107
+    (0xda01ee641a708de9, 0xe80e6f4820cc9495), // 5^108
+    (0x884134fe908658b2, 0x3109058d147fdcdd), // 5^109
+    (0xaa51823e34a7eede, 0xbd4b46f0599fd415), // 5^110
+    (0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a), // 5^111
+    (0x850fadc09923329e, 0x3e2cf6bc604ddb0),  // 5^112
+    (0xa6539930bf6bff45, 0x84db8346b786151c), // 5^113
+    (0xcfe87f7cef46ff16, 0xe612641865679a63), // 5^114
+    (0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e), // 5^115
+    (0xa26da3999aef7749, 0xe3be5e330f38f09d), // 5^116
+    (0xcb090c8001ab551c, 0x5cadf5bfd3072cc5), // 5^117
+    (0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6), // 5^118
+    (0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa), // 5^119
+    (0xc646d63501a1511d, 0xb281e1fd541501b8), // 5^120
+    (0xf7d88bc24209a565, 0x1f225a7ca91a4226), // 5^121
+    (0x9ae757596946075f, 0x3375788de9b06958), // 5^122
+    (0xc1a12d2fc3978937, 0x52d6b1641c83ae),   // 5^123
+    (0xf209787bb47d6b84, 0xc0678c5dbd23a49a), // 5^124
+    (0x9745eb4d50ce6332, 0xf840b7ba963646e0), // 5^125
+    (0xbd176620a501fbff, 0xb650e5a93bc3d898), // 5^126
+    (0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe), // 5^127
+    (0x93ba47c980e98cdf, 0xc66f336c36b10137), // 5^128
+    (0xb8a8d9bbe123f017, 0xb80b0047445d4184), // 5^129
+    (0xe6d3102ad96cec1d, 0xa60dc059157491e5), // 5^130
+    (0x9043ea1ac7e41392, 0x87c89837ad68db2f), // 5^131
+    (0xb454e4a179dd1877, 0x29babe4598c311fb), // 5^132
+    (0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a), // 5^133
+    (0x8ce2529e2734bb1d, 0x1899e4a65f58660c), // 5^134
+    (0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f), // 5^135
+    (0xdc21a1171d42645d, 0x76707543f4fa1f73), // 5^136
+    (0x899504ae72497eba, 0x6a06494a791c53a8), // 5^137
+    (0xabfa45da0edbde69, 0x487db9d17636892),  // 5^138
+    (0xd6f8d7509292d603, 0x45a9d2845d3c42b6), // 5^139
+    (0x865b86925b9bc5c2, 0xb8a2392ba45a9b2),  // 5^140
+    (0xa7f26836f282b732, 0x8e6cac7768d7141e), // 5^141
+    (0xd1ef0244af2364ff, 0x3207d795430cd926), // 5^142
+    (0x8335616aed761f1f, 0x7f44e6bd49e807b8), // 5^143
+    (0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6), // 5^144
+    (0xcd036837130890a1, 0x36dba887c37a8c0f), // 5^145
+    (0x802221226be55a64, 0xc2494954da2c9789), // 5^146
+    (0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c), // 5^147
+    (0xc83553c5c8965d3d, 0x6f92829494e5acc7), // 5^148
+    (0xfa42a8b73abbf48c, 0xcb772339ba1f17f9), // 5^149
+    (0x9c69a97284b578d7, 0xff2a760414536efb), // 5^150
+    (0xc38413cf25e2d70d, 0xfef5138519684aba), // 5^151
+    (0xf46518c2ef5b8cd1, 0x7eb258665fc25d69), // 5^152
+    (0x98bf2f79d5993802, 0xef2f773ffbd97a61), // 5^153
+    (0xbeeefb584aff8603, 0xaafb550ffacfd8fa), // 5^154
+    (0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38), // 5^155
+    (0x952ab45cfa97a0b2, 0xdd945a747bf26183), // 5^156
+    (0xba756174393d88df, 0x94f971119aeef9e4), // 5^157
+    (0xe912b9d1478ceb17, 0x7a37cd5601aab85d), // 5^158
+    (0x91abb422ccb812ee, 0xac62e055c10ab33a), // 5^159
+    (0xb616a12b7fe617aa, 0x577b986b314d6009), // 5^160
+    (0xe39c49765fdf9d94, 0xed5a7e85fda0b80b), // 5^161
+    (0x8e41ade9fbebc27d, 0x14588f13be847307), // 5^162
+    (0xb1d219647ae6b31c, 0x596eb2d8ae258fc8), // 5^163
+    (0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb), // 5^164
+    (0x8aec23d680043bee, 0x25de7bb9480d5854), // 5^165
+    (0xada72ccc20054ae9, 0xaf561aa79a10ae6a), // 5^166
+    (0xd910f7ff28069da4, 0x1b2ba1518094da04), // 5^167
+    (0x87aa9aff79042286, 0x90fb44d2f05d0842), // 5^168
+    (0xa99541bf57452b28, 0x353a1607ac744a53), // 5^169
+    (0xd3fa922f2d1675f2, 0x42889b8997915ce8), // 5^170
+    (0x847c9b5d7c2e09b7, 0x69956135febada11), // 5^171
+    (0xa59bc234db398c25, 0x43fab9837e699095), // 5^172
+    (0xcf02b2c21207ef2e, 0x94f967e45e03f4bb), // 5^173
+    (0x8161afb94b44f57d, 0x1d1be0eebac278f5), // 5^174
+    (0xa1ba1ba79e1632dc, 0x6462d92a69731732), // 5^175
+    (0xca28a291859bbf93, 0x7d7b8f7503cfdcfe), // 5^176
+    (0xfcb2cb35e702af78, 0x5cda735244c3d43e), // 5^177
+    (0x9defbf01b061adab, 0x3a0888136afa64a7), // 5^178
+    (0xc56baec21c7a1916, 0x88aaa1845b8fdd0),  // 5^179
+    (0xf6c69a72a3989f5b, 0x8aad549e57273d45), // 5^180
+    (0x9a3c2087a63f6399, 0x36ac54e2f678864b), // 5^181
+    (0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd), // 5^182
+    (0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5), // 5^183
+    (0x969eb7c47859e743, 0x9f644ae5a4b1b325), // 5^184
+    (0xbc4665b596706114, 0x873d5d9f0dde1fee), // 5^185
+    (0xeb57ff22fc0c7959, 0xa90cb506d155a7ea), // 5^186
+    (0x9316ff75dd87cbd8, 0x9a7f12442d588f2),  // 5^187
+    (0xb7dcbf5354e9bece, 0xc11ed6d538aeb2f),  // 5^188
+    (0xe5d3ef282a242e81, 0x8f1668c8a86da5fa), // 5^189
+    (0x8fa475791a569d10, 0xf96e017d694487bc), // 5^190
+    (0xb38d92d760ec4455, 0x37c981dcc395a9ac), // 5^191
+    (0xe070f78d3927556a, 0x85bbe253f47b1417), // 5^192
+    (0x8c469ab843b89562, 0x93956d7478ccec8e), // 5^193
+    (0xaf58416654a6babb, 0x387ac8d1970027b2), // 5^194
+    (0xdb2e51bfe9d0696a, 0x6997b05fcc0319e),  // 5^195
+    (0x88fcf317f22241e2, 0x441fece3bdf81f03), // 5^196
+    (0xab3c2fddeeaad25a, 0xd527e81cad7626c3), // 5^197
+    (0xd60b3bd56a5586f1, 0x8a71e223d8d3b074), // 5^198
+    (0x85c7056562757456, 0xf6872d5667844e49), // 5^199
+    (0xa738c6bebb12d16c, 0xb428f8ac016561db), // 5^200
+    (0xd106f86e69d785c7, 0xe13336d701beba52), // 5^201
+    (0x82a45b450226b39c, 0xecc0024661173473), // 5^202
+    (0xa34d721642b06084, 0x27f002d7f95d0190), // 5^203
+    (0xcc20ce9bd35c78a5, 0x31ec038df7b441f4), // 5^204
+    (0xff290242c83396ce, 0x7e67047175a15271), // 5^205
+    (0x9f79a169bd203e41, 0xf0062c6e984d386),  // 5^206
+    (0xc75809c42c684dd1, 0x52c07b78a3e60868), // 5^207
+    (0xf92e0c3537826145, 0xa7709a56ccdf8a82), // 5^208
+    (0x9bbcc7a142b17ccb, 0x88a66076400bb691), // 5^209
+    (0xc2abf989935ddbfe, 0x6acff893d00ea435), // 5^210
+    (0xf356f7ebf83552fe, 0x583f6b8c4124d43),  // 5^211
+    (0x98165af37b2153de, 0xc3727a337a8b704a), // 5^212
+    (0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c), // 5^213
+    (0xeda2ee1c7064130c, 0x1162def06f79df73), // 5^214
+    (0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8), // 5^215
+    (0xb9a74a0637ce2ee1, 0x6d953e2bd7173692), // 5^216
+    (0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437), // 5^217
+    (0x910ab1d4db9914a0, 0x1d9c9892400a22a2), // 5^218
+    (0xb54d5e4a127f59c8, 0x2503beb6d00cab4b), // 5^219
+    (0xe2a0b5dc971f303a, 0x2e44ae64840fd61d), // 5^220
+    (0x8da471a9de737e24, 0x5ceaecfed289e5d2), // 5^221
+    (0xb10d8e1456105dad, 0x7425a83e872c5f47), // 5^222
+    (0xdd50f1996b947518, 0xd12f124e28f77719), // 5^223
+    (0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f), // 5^224
+    (0xace73cbfdc0bfb7b, 0x636cc64d1001550b), // 5^225
+    (0xd8210befd30efa5a, 0x3c47f7e05401aa4e), // 5^226
+    (0x8714a775e3e95c78, 0x65acfaec34810a71), // 5^227
+    (0xa8d9d1535ce3b396, 0x7f1839a741a14d0d), // 5^228
+    (0xd31045a8341ca07c, 0x1ede48111209a050), // 5^229
+    (0x83ea2b892091e44d, 0x934aed0aab460432), // 5^230
+    (0xa4e4b66b68b65d60, 0xf81da84d5617853f), // 5^231
+    (0xce1de40642e3f4b9, 0x36251260ab9d668e), // 5^232
+    (0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019), // 5^233
+    (0xa1075a24e4421730, 0xb24cf65b8612f81f), // 5^234
+    (0xc94930ae1d529cfc, 0xdee033f26797b627), // 5^235
+    (0xfb9b7cd9a4a7443c, 0x169840ef017da3b1), // 5^236
+    (0x9d412e0806e88aa5, 0x8e1f289560ee864e), // 5^237
+    (0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2), // 5^238
+    (0xf5b5d7ec8acb58a2, 0xae10af696774b1db), // 5^239
+    (0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29), // 5^240
+    (0xbff610b0cc6edd3f, 0x17fd090a58d32af3), // 5^241
+    (0xeff394dcff8a948e, 0xddfc4b4cef07f5b0), // 5^242
+    (0x95f83d0a1fb69cd9, 0x4abdaf101564f98e), // 5^243
+    (0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1), // 5^244
+    (0xea53df5fd18d5513, 0x84c86189216dc5ed), // 5^245
+    (0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4), // 5^246
+    (0xb7118682dbb66a77, 0x3fbc8c33221dc2a1), // 5^247
+    (0xe4d5e82392a40515, 0xfabaf3feaa5334a),  // 5^248
+    (0x8f05b1163ba6832d, 0x29cb4d87f2a7400e), // 5^249
+    (0xb2c71d5bca9023f8, 0x743e20e9ef511012), // 5^250
+    (0xdf78e4b2bd342cf6, 0x914da9246b255416), // 5^251
+    (0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e), // 5^252
+    (0xae9672aba3d0c320, 0xa184ac2473b529b1), // 5^253
+    (0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e), // 5^254
+    (0x8865899617fb1871, 0x7e2fa67c7a658892), // 5^255
+    (0xaa7eebfb9df9de8d, 0xddbb901b98feeab7), // 5^256
+    (0xd51ea6fa85785631, 0x552a74227f3ea565), // 5^257
+    (0x8533285c936b35de, 0xd53a88958f87275f), // 5^258
+    (0xa67ff273b8460356, 0x8a892abaf368f137), // 5^259
+    (0xd01fef10a657842c, 0x2d2b7569b0432d85), // 5^260
+    (0x8213f56a67f6b29b, 0x9c3b29620e29fc73), // 5^261
+    (0xa298f2c501f45f42, 0x8349f3ba91b47b8f), // 5^262
+    (0xcb3f2f7642717713, 0x241c70a936219a73), // 5^263
+    (0xfe0efb53d30dd4d7, 0xed238cd383aa0110), // 5^264
+    (0x9ec95d1463e8a506, 0xf4363804324a40aa), // 5^265
+    (0xc67bb4597ce2ce48, 0xb143c6053edcd0d5), // 5^266
+    (0xf81aa16fdc1b81da, 0xdd94b7868e94050a), // 5^267
+    (0x9b10a4e5e9913128, 0xca7cf2b4191c8326), // 5^268
+    (0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0), // 5^269
+    (0xf24a01a73cf2dccf, 0xbc633b39673c8cec), // 5^270
+    (0x976e41088617ca01, 0xd5be0503e085d813), // 5^271
+    (0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18), // 5^272
+    (0xec9c459d51852ba2, 0xddf8e7d60ed1219e), // 5^273
+    (0x93e1ab8252f33b45, 0xcabb90e5c942b503), // 5^274
+    (0xb8da1662e7b00a17, 0x3d6a751f3b936243), // 5^275
+    (0xe7109bfba19c0c9d, 0xcc512670a783ad4),  // 5^276
+    (0x906a617d450187e2, 0x27fb2b80668b24c5), // 5^277
+    (0xb484f9dc9641e9da, 0xb1f9f660802dedf6), // 5^278
+    (0xe1a63853bbd26451, 0x5e7873f8a0396973), // 5^279
+    (0x8d07e33455637eb2, 0xdb0b487b6423e1e8), // 5^280
+    (0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62), // 5^281
+    (0xdc5c5301c56b75f7, 0x7641a140cc7810fb), // 5^282
+    (0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d), // 5^283
+    (0xac2820d9623bf429, 0x546345fa9fbdcd44), // 5^284
+    (0xd732290fbacaf133, 0xa97c177947ad4095), // 5^285
+    (0x867f59a9d4bed6c0, 0x49ed8eabcccc485d), // 5^286
+    (0xa81f301449ee8c70, 0x5c68f256bfff5a74), // 5^287
+    (0xd226fc195c6a2f8c, 0x73832eec6fff3111), // 5^288
+    (0x83585d8fd9c25db7, 0xc831fd53c5ff7eab), // 5^289
+    (0xa42e74f3d032f525, 0xba3e7ca8b77f5e55), // 5^290
+    (0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb), // 5^291
+    (0x80444b5e7aa7cf85, 0x7980d163cf5b81b3), // 5^292
+    (0xa0555e361951c366, 0xd7e105bcc332621f), // 5^293
+    (0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7), // 5^294
+    (0xfa856334878fc150, 0xb14f98f6f0feb951), // 5^295
+    (0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3), // 5^296
+    (0xc3b8358109e84f07, 0xa862f80ec4700c8),  // 5^297
+    (0xf4a642e14c6262c8, 0xcd27bb612758c0fa), // 5^298
+    (0x98e7e9cccfbd7dbd, 0x8038d51cb897789c), // 5^299
+    (0xbf21e44003acdd2c, 0xe0470a63e6bd56c3), // 5^300
+    (0xeeea5d5004981478, 0x1858ccfce06cac74), // 5^301
+    (0x95527a5202df0ccb, 0xf37801e0c43ebc8),  // 5^302
+    (0xbaa718e68396cffd, 0xd30560258f54e6ba), // 5^303
+    (0xe950df20247c83fd, 0x47c6b82ef32a2069), // 5^304
+    (0x91d28b7416cdd27e, 0x4cdc331d57fa5441), // 5^305
+    (0xb6472e511c81471d, 0xe0133fe4adf8e952), // 5^306
+    (0xe3d8f9e563a198e5, 0x58180fddd97723a6), // 5^307
+    (0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648), // 5^308
 ];
diff --git a/library/core/src/num/diy_float.rs b/library/core/src/num/diy_float.rs
index 0a609417dcf..ce7f6475d05 100644
--- a/library/core/src/num/diy_float.rs
+++ b/library/core/src/num/diy_float.rs
@@ -65,7 +65,7 @@ impl Fp {
             f <<= 1;
             e -= 1;
         }
-        debug_assert!(f >= (1 >> 63));
+        debug_assert!(f >= (1 << 63));
         Fp { f, e }
     }
 
diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs
index e2cc8faf854..cdeba9c0792 100644
--- a/library/core/src/num/error.rs
+++ b/library/core/src/num/error.rs
@@ -74,26 +74,20 @@ pub struct ParseIntError {
 /// # Example
 ///
 /// ```
-/// #![feature(int_error_matching)]
-///
 /// # fn main() {
 /// if let Err(e) = i32::from_str_radix("a12", 10) {
 ///     println!("Failed conversion to i32: {:?}", e.kind());
 /// }
 /// # }
 /// ```
-#[unstable(
-    feature = "int_error_matching",
-    reason = "it can be useful to match errors when making error messages \
-              for integer parsing",
-    issue = "22639"
-)]
+#[stable(feature = "int_error_matching", since = "1.55.0")]
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[non_exhaustive]
 pub enum IntErrorKind {
     /// Value being parsed is empty.
     ///
-    /// Among other causes, this variant will be constructed when parsing an empty string.
+    /// This variant will be constructed when parsing an empty string.
+    #[stable(feature = "int_error_matching", since = "1.55.0")]
     Empty,
     /// Contains an invalid digit in its context.
     ///
@@ -102,26 +96,25 @@ pub enum IntErrorKind {
     ///
     /// This variant is also constructed when a `+` or `-` is misplaced within a string
     /// either on its own or in the middle of a number.
+    #[stable(feature = "int_error_matching", since = "1.55.0")]
     InvalidDigit,
     /// Integer is too large to store in target integer type.
+    #[stable(feature = "int_error_matching", since = "1.55.0")]
     PosOverflow,
     /// Integer is too small to store in target integer type.
+    #[stable(feature = "int_error_matching", since = "1.55.0")]
     NegOverflow,
     /// Value was Zero
     ///
     /// This variant will be emitted when the parsing string has a value of zero, which
     /// would be illegal for non-zero types.
+    #[stable(feature = "int_error_matching", since = "1.55.0")]
     Zero,
 }
 
 impl ParseIntError {
     /// Outputs the detailed cause of parsing an integer failing.
-    #[unstable(
-        feature = "int_error_matching",
-        reason = "it can be useful to match errors when making error messages \
-              for integer parsing",
-        issue = "22639"
-    )]
+    #[stable(feature = "int_error_matching", since = "1.55.0")]
     pub fn kind(&self) -> &IntErrorKind {
         &self.kind
     }
diff --git a/library/core/src/num/flt2dec/decoder.rs b/library/core/src/num/flt2dec/decoder.rs
index c43536c6fcc..5763860540a 100644
--- a/library/core/src/num/flt2dec/decoder.rs
+++ b/library/core/src/num/flt2dec/decoder.rs
@@ -1,6 +1,6 @@
 //! Decodes a floating-point value into individual parts and error ranges.
 
-use crate::num::dec2flt::rawfp::RawFloat;
+use crate::num::dec2flt::float::RawFloat;
 use crate::num::FpCategory;
 
 /// Decoded unsigned finite value, such that:
diff --git a/library/core/src/num/flt2dec/mod.rs b/library/core/src/num/flt2dec/mod.rs
index 93bdf5040e0..1ff2e8c8228 100644
--- a/library/core/src/num/flt2dec/mod.rs
+++ b/library/core/src/num/flt2dec/mod.rs
@@ -49,7 +49,7 @@ the supplied buffer and let the algorithm to return.
 # Implementation overview
 
 It is easy to get the floating point printing correct but slow (Russ Cox has
-[demonstrated](http://research.swtch.com/ftoa) how it's easy), or incorrect but
+[demonstrated](https://research.swtch.com/ftoa) how it's easy), or incorrect but
 fast (naïve division and modulo). But it is surprisingly hard to print
 floating point numbers correctly *and* efficiently.
 
@@ -124,6 +124,7 @@ functions.
 
 pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
 
+use super::fmt::{Formatted, Part};
 use crate::mem::MaybeUninit;
 
 pub mod decoder;
@@ -170,107 +171,6 @@ pub fn round_up(d: &mut [u8]) -> Option<u8> {
     }
 }
 
-/// Formatted parts.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum Part<'a> {
-    /// Given number of zero digits.
-    Zero(usize),
-    /// A literal number up to 5 digits.
-    Num(u16),
-    /// A verbatim copy of given bytes.
-    Copy(&'a [u8]),
-}
-
-impl<'a> Part<'a> {
-    /// Returns the exact byte length of given part.
-    pub fn len(&self) -> usize {
-        match *self {
-            Part::Zero(nzeroes) => nzeroes,
-            Part::Num(v) => {
-                if v < 1_000 {
-                    if v < 10 {
-                        1
-                    } else if v < 100 {
-                        2
-                    } else {
-                        3
-                    }
-                } else {
-                    if v < 10_000 { 4 } else { 5 }
-                }
-            }
-            Part::Copy(buf) => buf.len(),
-        }
-    }
-
-    /// Writes a part into the supplied buffer.
-    /// Returns the number of written bytes, or `None` if the buffer is not enough.
-    /// (It may still leave partially written bytes in the buffer; do not rely on that.)
-    pub fn write(&self, out: &mut [u8]) -> Option<usize> {
-        let len = self.len();
-        if out.len() >= len {
-            match *self {
-                Part::Zero(nzeroes) => {
-                    for c in &mut out[..nzeroes] {
-                        *c = b'0';
-                    }
-                }
-                Part::Num(mut v) => {
-                    for c in out[..len].iter_mut().rev() {
-                        *c = b'0' + (v % 10) as u8;
-                        v /= 10;
-                    }
-                }
-                Part::Copy(buf) => {
-                    out[..buf.len()].copy_from_slice(buf);
-                }
-            }
-            Some(len)
-        } else {
-            None
-        }
-    }
-}
-
-/// Formatted result containing one or more parts.
-/// This can be written to the byte buffer or converted to the allocated string.
-#[allow(missing_debug_implementations)]
-#[derive(Clone)]
-pub struct Formatted<'a> {
-    /// A byte slice representing a sign, either `""`, `"-"` or `"+"`.
-    pub sign: &'static str,
-    /// Formatted parts to be rendered after a sign and optional zero padding.
-    pub parts: &'a [Part<'a>],
-}
-
-impl<'a> Formatted<'a> {
-    /// Returns the exact byte length of combined formatted result.
-    pub fn len(&self) -> usize {
-        let mut len = self.sign.len();
-        for part in self.parts {
-            len += part.len();
-        }
-        len
-    }
-
-    /// Writes all formatted parts into the supplied buffer.
-    /// Returns the number of written bytes, or `None` if the buffer is not enough.
-    /// (It may still leave partially written bytes in the buffer; do not rely on that.)
-    pub fn write(&self, out: &mut [u8]) -> Option<usize> {
-        if out.len() < self.sign.len() {
-            return None;
-        }
-        out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());
-
-        let mut written = self.sign.len();
-        for part in self.parts {
-            let len = part.write(&mut out[written..])?;
-            written += len;
-        }
-        Some(written)
-    }
-}
-
 /// Formats given decimal digits `0.<...buf...> * 10^exp` into the decimal form
 /// with at least given number of fractional digits. The result is stored to
 /// the supplied parts array and a slice of written parts is returned.
diff --git a/library/core/src/num/fmt.rs b/library/core/src/num/fmt.rs
new file mode 100644
index 00000000000..578288bda25
--- /dev/null
+++ b/library/core/src/num/fmt.rs
@@ -0,0 +1,108 @@
+//! Shared utilties used by both float and integer formatting.
+#![doc(hidden)]
+#![unstable(
+    feature = "numfmt",
+    reason = "internal routines only exposed for testing",
+    issue = "none"
+)]
+
+/// Formatted parts.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum Part<'a> {
+    /// Given number of zero digits.
+    Zero(usize),
+    /// A literal number up to 5 digits.
+    Num(u16),
+    /// A verbatim copy of given bytes.
+    Copy(&'a [u8]),
+}
+
+impl<'a> Part<'a> {
+    /// Returns the exact byte length of given part.
+    pub fn len(&self) -> usize {
+        match *self {
+            Part::Zero(nzeroes) => nzeroes,
+            Part::Num(v) => {
+                if v < 1_000 {
+                    if v < 10 {
+                        1
+                    } else if v < 100 {
+                        2
+                    } else {
+                        3
+                    }
+                } else {
+                    if v < 10_000 { 4 } else { 5 }
+                }
+            }
+            Part::Copy(buf) => buf.len(),
+        }
+    }
+
+    /// Writes a part into the supplied buffer.
+    /// Returns the number of written bytes, or `None` if the buffer is not enough.
+    /// (It may still leave partially written bytes in the buffer; do not rely on that.)
+    pub fn write(&self, out: &mut [u8]) -> Option<usize> {
+        let len = self.len();
+        if out.len() >= len {
+            match *self {
+                Part::Zero(nzeroes) => {
+                    for c in &mut out[..nzeroes] {
+                        *c = b'0';
+                    }
+                }
+                Part::Num(mut v) => {
+                    for c in out[..len].iter_mut().rev() {
+                        *c = b'0' + (v % 10) as u8;
+                        v /= 10;
+                    }
+                }
+                Part::Copy(buf) => {
+                    out[..buf.len()].copy_from_slice(buf);
+                }
+            }
+            Some(len)
+        } else {
+            None
+        }
+    }
+}
+
+/// Formatted result containing one or more parts.
+/// This can be written to the byte buffer or converted to the allocated string.
+#[allow(missing_debug_implementations)]
+#[derive(Clone)]
+pub struct Formatted<'a> {
+    /// A byte slice representing a sign, either `""`, `"-"` or `"+"`.
+    pub sign: &'static str,
+    /// Formatted parts to be rendered after a sign and optional zero padding.
+    pub parts: &'a [Part<'a>],
+}
+
+impl<'a> Formatted<'a> {
+    /// Returns the exact byte length of combined formatted result.
+    pub fn len(&self) -> usize {
+        let mut len = self.sign.len();
+        for part in self.parts {
+            len += part.len();
+        }
+        len
+    }
+
+    /// Writes all formatted parts into the supplied buffer.
+    /// Returns the number of written bytes, or `None` if the buffer is not enough.
+    /// (It may still leave partially written bytes in the buffer; do not rely on that.)
+    pub fn write(&self, out: &mut [u8]) -> Option<usize> {
+        if out.len() < self.sign.len() {
+            return None;
+        }
+        out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());
+
+        let mut written = self.sign.len();
+        for part in self.parts {
+            let len = part.write(&mut out[written..])?;
+            written += len;
+        }
+        Some(written)
+    }
+}
diff --git a/library/core/src/num/int_log10.rs b/library/core/src/num/int_log10.rs
new file mode 100644
index 00000000000..a23ca51ef87
--- /dev/null
+++ b/library/core/src/num/int_log10.rs
@@ -0,0 +1,134 @@
+mod unchecked {
+    // 0 < val <= u8::MAX
+    pub const fn u8(val: u8) -> u32 {
+        if val >= 100 {
+            2
+        } else if val >= 10 {
+            1
+        } else {
+            0
+        }
+    }
+
+    // 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_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 <= 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;
+        }
+        log + less_than_8(val as u32)
+    }
+
+    // 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;
+        }
+        log + less_than_16(val)
+    }
+
+    // 0 < val <= u128::MAX
+    pub const fn u128(mut val: u128) -> u32 {
+        let mut log = 0;
+        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);
+        }
+        if val >= 10_000_000_000_000_000 {
+            val /= 10_000_000_000_000_000;
+            log += 16;
+        }
+        log + less_than_16(val as u64)
+    }
+
+    // 0 < val <= i8::MAX
+    pub const fn i8(val: i8) -> u32 {
+        u8(val as u8)
+    }
+
+    // 0 < val <= i16::MAX
+    pub const fn i16(val: i16) -> u32 {
+        u16(val as u16)
+    }
+
+    // 0 < val <= i32::MAX
+    pub const fn i32(val: i32) -> u32 {
+        u32(val as u32)
+    }
+
+    // 0 < val <= i64::MAX
+    pub const fn i64(val: i64) -> u32 {
+        u64(val as u64)
+    }
+
+    // 0 < val <= i128::MAX
+    pub const fn i128(val: i128) -> u32 {
+        u128(val as u128)
+    }
+}
+
+macro_rules! impl_checked {
+    ($T:ident) => {
+        pub const fn $T(val: $T) -> Option<$T> {
+            if val > 0 { Some(unchecked::$T(val) as $T) } else { None }
+        }
+    };
+}
+
+impl_checked! { u8 }
+impl_checked! { u16 }
+impl_checked! { u32 }
+impl_checked! { u64 }
+impl_checked! { u128 }
+impl_checked! { i8 }
+impl_checked! { i16 }
+impl_checked! { i32 }
+impl_checked! { i64 }
+impl_checked! { i128 }
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index a0efe681285..0bc646995c7 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1,9 +1,10 @@
 macro_rules! int_impl {
-    ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr,
+    ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $BITS_MINUS_ONE:expr, $Min:expr, $Max:expr,
      $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
      $reversed:expr, $le_bytes:expr, $be_bytes:expr,
      $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
-        /// The smallest value that can be represented by this integer type.
+        /// The smallest value that can be represented by this integer type,
+        #[doc = concat!("-2<sup>", $BITS_MINUS_ONE, "</sup>.")]
         ///
         /// # Examples
         ///
@@ -15,7 +16,8 @@ macro_rules! int_impl {
         #[stable(feature = "assoc_int_consts", since = "1.43.0")]
         pub const MIN: Self = !0 ^ ((!0 as $UnsignedT) >> 1) as Self;
 
-        /// The largest value that can be represented by this integer type.
+        /// The largest value that can be represented by this integer type,
+        #[doc = concat!("2<sup>", $BITS_MINUS_ONE, "</sup> - 1.")]
         ///
         /// # Examples
         ///
@@ -1130,9 +1132,9 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
-        #[inline]
+        #[inline(always)]
         pub const fn wrapping_neg(self) -> Self {
-            self.overflowing_neg().0
+            (0 as $SelfT).wrapping_sub(self)
         }
 
         /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes
@@ -1744,6 +1746,197 @@ macro_rules! int_impl {
             }
         }
 
+        /// Returns the logarithm of the number with respect to an arbitrary base.
+        ///
+        /// This method might not be optimized owing to implementation details;
+        /// `log2` can produce results more efficiently for base 2, and `log10`
+        /// can produce results more efficiently for base 10.
+        ///
+        /// # 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).
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".log(5), 1);")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        #[track_caller]
+        #[rustc_inherit_overflow_checks]
+        #[allow(arithmetic_overflow)]
+        pub const fn log(self, base: Self) -> Self {
+            match self.checked_log(base) {
+                Some(n) => n,
+                None => {
+                    // In debug builds, trigger a panic on None.
+                    // This should optimize completely out in release builds.
+                    let _ = Self::MAX + 1;
+
+                    0
+                },
+            }
+        }
+
+        /// Returns the base 2 logarithm of the number.
+        ///
+        /// # 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).
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".log2(), 1);")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        #[track_caller]
+        #[rustc_inherit_overflow_checks]
+        #[allow(arithmetic_overflow)]
+        pub const fn log2(self) -> Self {
+            match self.checked_log2() {
+                Some(n) => n,
+                None => {
+                    // In debug builds, trigger a panic on None.
+                    // This should optimize completely out in release builds.
+                    let _ = Self::MAX + 1;
+
+                    0
+                },
+            }
+        }
+
+        /// Returns the base 10 logarithm of the number.
+        ///
+        /// # 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).
+        ///
+        /// # Example
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".log10(), 1);")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        #[track_caller]
+        #[rustc_inherit_overflow_checks]
+        #[allow(arithmetic_overflow)]
+        pub const fn log10(self) -> Self {
+            match self.checked_log10() {
+                Some(n) => n,
+                None => {
+                    // In debug builds, trigger a panic on None.
+                    // This should optimize completely out in release builds.
+                    let _ = Self::MAX + 1;
+
+                    0
+                },
+            }
+        }
+
+        /// Returns the logarithm of the number with respect to an arbitrary base.
+        ///
+        /// Returns `None` if the number is negative or zero, or if the base is not at least 2.
+        ///
+        /// This method might not be optimized owing to implementation details;
+        /// `checked_log2` can produce results more efficiently for base 2, and
+        /// `checked_log10` can produce results more efficiently for base 10.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_log(5), Some(1));")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        pub const fn checked_log(self, base: Self) -> Option<Self> {
+            if self <= 0 || base <= 1 {
+                None
+            } else {
+                let mut n = 0;
+                let mut r = self;
+
+                // Optimization for 128 bit wide integers.
+                if Self::BITS == 128 {
+                    let b = Self::log2(self) / (Self::log2(base) + 1);
+                    n += b;
+                    r /= base.pow(b as u32);
+                }
+
+                while r >= base {
+                    r /= base;
+                    n += 1;
+                }
+                Some(n)
+            }
+        }
+
+        /// Returns the base 2 logarithm of the number.
+        ///
+        /// Returns `None` if the number is negative or zero.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_log2(), Some(1));")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        pub const fn checked_log2(self) -> Option<Self> {
+            if self <= 0 {
+                None
+            } else {
+                // SAFETY: We just checked that this number is positive
+                let log = (Self::BITS - 1) as Self - unsafe { intrinsics::ctlz_nonzero(self) };
+                Some(log)
+            }
+        }
+
+        /// Returns the base 10 logarithm of the number.
+        ///
+        /// Returns `None` if the number is negative or zero.
+        ///
+        /// # Example
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_log10(), Some(1));")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        pub const fn checked_log10(self) -> Option<Self> {
+            match int_log10::$ActualT(self as $ActualT) {
+                Some(s) => Some(s as Self),
+                None => None,
+            }
+        }
+
         /// Computes the absolute value of `self`.
         ///
         /// # Overflow behavior
@@ -1772,9 +1965,9 @@ macro_rules! int_impl {
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn abs(self) -> Self {
-            // Note that the #[inline] above means that the overflow
-            // semantics of the subtraction depend on the crate we're being
-            // inlined into.
+            // Note that the #[rustc_inherit_overflow_checks] and #[inline]
+            // above mean that the overflow semantics of the subtraction
+            // depend on the crate we're being called from.
             if self.is_negative() {
                 -self
             } else {
@@ -1905,7 +2098,7 @@ 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
-        #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
         #[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
@@ -2011,7 +2204,7 @@ 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 to them
-        #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
         #[inline]
         pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             // SAFETY: integers are plain old datatypes so we can always transmute to them
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 6032dc9a2d3..9788404dd05 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -25,10 +25,15 @@ macro_rules! unlikely {
 }
 
 // All these modules are technically private and only exposed for coretests:
+#[cfg(not(no_fp_fmt_parse))]
 pub mod bignum;
+#[cfg(not(no_fp_fmt_parse))]
 pub mod dec2flt;
+#[cfg(not(no_fp_fmt_parse))]
 pub mod diy_float;
+#[cfg(not(no_fp_fmt_parse))]
 pub mod flt2dec;
+pub mod fmt;
 
 #[macro_use]
 mod int_macros; // import int_impl!
@@ -36,6 +41,7 @@ mod int_macros; // import int_impl!
 mod uint_macros; // import uint_impl!
 
 mod error;
+mod int_log10;
 mod nonzero;
 mod wrapping;
 
@@ -43,6 +49,7 @@ mod wrapping;
 pub use wrapping::Wrapping;
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(no_fp_fmt_parse))]
 pub use dec2flt::ParseFloatError;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -57,12 +64,7 @@ pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, No
 #[stable(feature = "try_from", since = "1.34.0")]
 pub use error::TryFromIntError;
 
-#[unstable(
-    feature = "int_error_matching",
-    reason = "it can be useful to match errors when making error messages \
-              for integer parsing",
-    issue = "22639"
-)]
+#[stable(feature = "int_error_matching", since = "1.55.0")]
 pub use error::IntErrorKind;
 
 macro_rules! usize_isize_to_xe_bytes_doc {
@@ -89,26 +91,26 @@ depending on the target pointer size.
 
 #[lang = "i8"]
 impl i8 {
-    int_impl! { i8, i8, u8, 8, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
+    int_impl! { i8, i8, u8, 8, 7, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
     "[0x12]", "[0x12]", "", "" }
 }
 
 #[lang = "i16"]
 impl i16 {
-    int_impl! { i16, i16, u16, 16, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
+    int_impl! { i16, i16, u16, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
     "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
 }
 
 #[lang = "i32"]
 impl i32 {
-    int_impl! { i32, i32, u32, 32, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
+    int_impl! { i32, i32, u32, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78]", "", "" }
 }
 
 #[lang = "i64"]
 impl i64 {
-    int_impl! { i64, i64, u64, 64, -9223372036854775808, 9223372036854775807, 12,
+    int_impl! { i64, i64, u64, 64, 63, -9223372036854775808, 9223372036854775807, 12,
     "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412",
     "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "" }
@@ -116,7 +118,7 @@ impl i64 {
 
 #[lang = "i128"]
 impl i128 {
-    int_impl! { i128, i128, u128, 128, -170141183460469231731687303715884105728,
+    int_impl! { i128, i128, u128, 128, 127, -170141183460469231731687303715884105728,
     170141183460469231731687303715884105727, 16,
     "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
     "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
@@ -129,7 +131,7 @@ impl i128 {
 #[cfg(target_pointer_width = "16")]
 #[lang = "isize"]
 impl isize {
-    int_impl! { isize, i16, usize, 16, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234",
+    int_impl! { isize, i16, usize, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234",
     "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
@@ -137,7 +139,7 @@ impl isize {
 #[cfg(target_pointer_width = "32")]
 #[lang = "isize"]
 impl isize {
-    int_impl! { isize, i32, usize, 32, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
+    int_impl! { isize, i32, usize, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
@@ -146,7 +148,7 @@ impl isize {
 #[cfg(target_pointer_width = "64")]
 #[lang = "isize"]
 impl isize {
-    int_impl! { isize, i64, usize, 64, -9223372036854775808, 9223372036854775807,
+    int_impl! { isize, i64, usize, 64, 63, -9223372036854775808, 9223372036854775807,
     12, "0xaa00000000006e1", "0x6e10aa",  "0x1234567890123456", "0x5634129078563412",
      "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
      "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
@@ -595,8 +597,8 @@ impl u8 {
     /// before using this function.
     ///
     /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
-    /// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
-    /// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
+    /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
+    /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
     ///
     /// # Examples
     ///
@@ -845,7 +847,7 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par
     use self::ParseIntError as PIE;
 
     assert!(
-        radix >= 2 && radix <= 36,
+        (2..=36).contains(&radix),
         "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
         radix
     );
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 6b9b435d47f..dd9b9330aee 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -42,7 +42,8 @@ macro_rules! nonzero_integers {
             pub struct $Ty($Int);
 
             impl $Ty {
-                /// Creates a non-zero without checking the value.
+                /// Creates a non-zero without checking whether the value is non-zero.
+                /// This results in undefined behaviour if the value is zero.
                 ///
                 /// # Safety
                 ///
@@ -285,6 +286,576 @@ nonzero_integers_div! {
     NonZeroUsize(usize);
 }
 
+// A bunch of methods for unsigned nonzero types only.
+macro_rules! nonzero_unsigned_operations {
+    ( $( $Ty: ident($Int: ty); )+ ) => {
+        $(
+            impl $Ty {
+                /// Add an unsigned integer to a non-zero value.
+                /// Check for overflow and return [`None`] on overflow
+                /// As a consequence, the result cannot wrap to zero.
+                ///
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(Some(two), one.checked_add(1));
+                /// assert_eq!(None, max.checked_add(1));
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
+                    if let Some(result) = self.get().checked_add(other) {
+                        // SAFETY: $Int::checked_add returns None on overflow
+                        // so the result cannot be zero.
+                        Some(unsafe { $Ty::new_unchecked(result) })
+                    } else {
+                        None
+                    }
+                }
+
+                /// Add an unsigned integer to a non-zero value.
+                #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(two, one.saturating_add(1));
+                /// assert_eq!(max, max.saturating_add(1));
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn saturating_add(self, other: $Int) -> $Ty {
+                    // SAFETY: $Int::saturating_add returns $Int::MAX on overflow
+                    // so the result cannot be zero.
+                    unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) }
+                }
+
+                /// Add an unsigned integer to a non-zero value,
+                /// assuming overflow cannot occur.
+                /// Overflow is unchecked, and it is undefined behaviour to overflow
+                /// *even if the result would wrap to a non-zero value*.
+                /// The behaviour is undefined as soon as
+                #[doc = concat!("`self + rhs > ", stringify!($Int), "::MAX`.")]
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                ///
+                /// assert_eq!(two, unsafe { one.unchecked_add(1) });
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub unsafe fn unchecked_add(self, other: $Int) -> $Ty {
+                    // SAFETY: The caller ensures there is no overflow.
+                    unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) }
+                }
+
+                /// Returns the smallest power of two greater than or equal to n.
+                /// Check for overflow and return [`None`]
+                /// if the next power of two is greater than the type’s maximum value.
+                /// As a consequence, the result cannot wrap to zero.
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
+                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(Some(two), two.checked_next_power_of_two() );
+                /// assert_eq!(Some(four), three.checked_next_power_of_two() );
+                /// assert_eq!(None, max.checked_next_power_of_two() );
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn checked_next_power_of_two(self) -> Option<$Ty> {
+                    if let Some(nz) = self.get().checked_next_power_of_two() {
+                        // SAFETY: The next power of two is positive
+                        // and overflow is checked.
+                        Some(unsafe { $Ty::new_unchecked(nz) })
+                    } else {
+                        None
+                    }
+                }
+            }
+        )+
+    }
+}
+
+nonzero_unsigned_operations! {
+    NonZeroU8(u8);
+    NonZeroU16(u16);
+    NonZeroU32(u32);
+    NonZeroU64(u64);
+    NonZeroU128(u128);
+    NonZeroUsize(usize);
+}
+
+// A bunch of methods for signed nonzero types only.
+macro_rules! nonzero_signed_operations {
+    ( $( $Ty: ident($Int: ty) -> $Uty: ident($Uint: ty); )+ ) => {
+        $(
+            impl $Ty {
+                /// Computes the absolute value of self.
+                #[doc = concat!("See [`", stringify!($Int), "::abs`]")]
+                /// for documentation on overflow behaviour.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+                ///
+                /// assert_eq!(pos, pos.abs());
+                /// assert_eq!(pos, neg.abs());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn abs(self) -> $Ty {
+                    // SAFETY: This cannot overflow to zero.
+                    unsafe { $Ty::new_unchecked(self.get().abs()) }
+                }
+
+                /// Checked absolute value.
+                /// Check for overflow and returns [`None`] if
+                #[doc = concat!("`self == ", stringify!($Int), "::MIN`.")]
+                /// The result cannot be zero.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                ///
+                /// assert_eq!(Some(pos), neg.checked_abs());
+                /// assert_eq!(None, min.checked_abs());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn checked_abs(self) -> Option<$Ty> {
+                    if let Some(nz) = self.get().checked_abs() {
+                        // SAFETY: absolute value of nonzero cannot yield zero values.
+                        Some(unsafe { $Ty::new_unchecked(nz) })
+                    } else {
+                        None
+                    }
+                }
+
+                /// Computes the absolute value of self,
+                /// with overflow information, see
+                #[doc = concat!("[`", stringify!($Int), "::overflowing_abs`].")]
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                ///
+                /// assert_eq!((pos, false), pos.overflowing_abs());
+                /// assert_eq!((pos, false), neg.overflowing_abs());
+                /// assert_eq!((min, true), min.overflowing_abs());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn overflowing_abs(self) -> ($Ty, bool) {
+                    let (nz, flag) = self.get().overflowing_abs();
+                    (
+                        // SAFETY: absolute value of nonzero cannot yield zero values.
+                        unsafe { $Ty::new_unchecked(nz) },
+                        flag,
+                    )
+                }
+
+                /// Saturating absolute value, see
+                #[doc = concat!("[`", stringify!($Int), "::saturating_abs`].")]
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                #[doc = concat!("let min_plus = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN + 1)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(pos, pos.saturating_abs());
+                /// assert_eq!(pos, neg.saturating_abs());
+                /// assert_eq!(max, min.saturating_abs());
+                /// assert_eq!(max, min_plus.saturating_abs());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn saturating_abs(self) -> $Ty {
+                    // SAFETY: absolute value of nonzero cannot yield zero values.
+                    unsafe { $Ty::new_unchecked(self.get().saturating_abs()) }
+                }
+
+                /// Wrapping absolute value, see
+                #[doc = concat!("[`", stringify!($Int), "::wrapping_abs`].")]
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(pos, pos.wrapping_abs());
+                /// assert_eq!(pos, neg.wrapping_abs());
+                /// assert_eq!(min, min.wrapping_abs());
+                /// # // FIXME: add once Neg is implemented?
+                /// # // assert_eq!(max, (-max).wrapping_abs());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn wrapping_abs(self) -> $Ty {
+                    // SAFETY: absolute value of nonzero cannot yield zero values.
+                    unsafe { $Ty::new_unchecked(self.get().wrapping_abs()) }
+                }
+
+                /// Computes the absolute value of self
+                /// without any wrapping or panicking.
+                ///
+                /// # Example
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                #[doc = concat!("# use std::num::", stringify!($Uty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let u_pos = ", stringify!($Uty), "::new(1)?;")]
+                #[doc = concat!("let i_pos = ", stringify!($Ty), "::new(1)?;")]
+                #[doc = concat!("let i_neg = ", stringify!($Ty), "::new(-1)?;")]
+                #[doc = concat!("let i_min = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MIN)?;")]
+                #[doc = concat!("let u_max = ", stringify!($Uty), "::new(",
+                                stringify!($Uint), "::MAX / 2 + 1)?;")]
+                ///
+                /// assert_eq!(u_pos, i_pos.unsigned_abs());
+                /// assert_eq!(u_pos, i_neg.unsigned_abs());
+                /// assert_eq!(u_max, i_min.unsigned_abs());
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn unsigned_abs(self) -> $Uty {
+                    // SAFETY: absolute value of nonzero cannot yield zero values.
+                    unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
+                }
+            }
+        )+
+    }
+}
+
+nonzero_signed_operations! {
+    NonZeroI8(i8) -> NonZeroU8(u8);
+    NonZeroI16(i16) -> NonZeroU16(u16);
+    NonZeroI32(i32) -> NonZeroU32(u32);
+    NonZeroI64(i64) -> NonZeroU64(u64);
+    NonZeroI128(i128) -> NonZeroU128(u128);
+    NonZeroIsize(isize) -> NonZeroUsize(usize);
+}
+
+// A bunch of methods for both signed and unsigned nonzero types.
+macro_rules! nonzero_unsigned_signed_operations {
+    ( $( $signedness:ident $Ty: ident($Int: ty); )+ ) => {
+        $(
+            impl $Ty {
+                /// Multiply two non-zero integers together.
+                /// Check for overflow and return [`None`] on overflow.
+                /// As a consequence, the result cannot wrap to zero.
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(Some(four), two.checked_mul(two));
+                /// assert_eq!(None, max.checked_mul(two));
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
+                    if let Some(result) = self.get().checked_mul(other.get()) {
+                        // SAFETY: checked_mul returns None on overflow
+                        // and `other` is also non-null
+                        // so the result cannot be zero.
+                        Some(unsafe { $Ty::new_unchecked(result) })
+                    } else {
+                        None
+                    }
+                }
+
+                /// Multiply two non-zero integers together.
+                #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(four, two.saturating_mul(two));
+                /// assert_eq!(max, four.saturating_mul(max));
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn saturating_mul(self, other: $Ty) -> $Ty {
+                    // SAFETY: saturating_mul returns u*::MAX on overflow
+                    // and `other` is also non-null
+                    // so the result cannot be zero.
+                    unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) }
+                }
+
+                /// Multiply two non-zero integers together,
+                /// assuming overflow cannot occur.
+                /// Overflow is unchecked, and it is undefined behaviour to overflow
+                /// *even if the result would wrap to a non-zero value*.
+                /// The behaviour is undefined as soon as
+                #[doc = sign_dependent_expr!{
+                    $signedness ?
+                    if signed {
+                        concat!("`self * rhs > ", stringify!($Int), "::MAX`, ",
+                                "or `self * rhs < ", stringify!($Int), "::MIN`.")
+                    }
+                    if unsigned {
+                        concat!("`self * rhs > ", stringify!($Int), "::MAX`.")
+                    }
+                }]
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+                ///
+                /// assert_eq!(four, unsafe { two.unchecked_mul(two) });
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
+                    // SAFETY: The caller ensures there is no overflow.
+                    unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
+                }
+
+                /// Raise non-zero value to an integer power.
+                /// Check for overflow and return [`None`] on overflow.
+                /// As a consequence, the result cannot wrap to zero.
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
+                #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
+                #[doc = concat!("let half_max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX / 2)?;")]
+                ///
+                /// assert_eq!(Some(twenty_seven), three.checked_pow(3));
+                /// assert_eq!(None, half_max.checked_pow(3));
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
+                    if let Some(result) = self.get().checked_pow(other) {
+                        // SAFETY: checked_pow returns None on overflow
+                        // so the result cannot be zero.
+                        Some(unsafe { $Ty::new_unchecked(result) })
+                    } else {
+                        None
+                    }
+                }
+
+                /// Raise non-zero value to an integer power.
+                #[doc = sign_dependent_expr!{
+                    $signedness ?
+                    if signed {
+                        concat!("Return [`", stringify!($Int), "::MIN`] ",
+                                    "or [`", stringify!($Int), "::MAX`] on overflow.")
+                    }
+                    if unsigned {
+                        concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")
+                    }
+                }]
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(nonzero_ops)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                /// # fn main() { test().unwrap(); }
+                /// # fn test() -> Option<()> {
+                #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
+                #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
+                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                                stringify!($Int), "::MAX)?;")]
+                ///
+                /// assert_eq!(twenty_seven, three.saturating_pow(3));
+                /// assert_eq!(max, max.saturating_pow(3));
+                /// # Some(())
+                /// # }
+                /// ```
+                #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[inline]
+                pub const fn saturating_pow(self, other: u32) -> $Ty {
+                    // SAFETY: saturating_pow returns u*::MAX on overflow
+                    // so the result cannot be zero.
+                    unsafe { $Ty::new_unchecked(self.get().saturating_pow(other)) }
+                }
+            }
+        )+
+    }
+}
+
+// Use this when the generated code should differ between signed and unsigned types.
+macro_rules! sign_dependent_expr {
+    (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
+        $signed_case
+    };
+    (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
+        $unsigned_case
+    };
+}
+
+nonzero_unsigned_signed_operations! {
+    unsigned NonZeroU8(u8);
+    unsigned NonZeroU16(u16);
+    unsigned NonZeroU32(u32);
+    unsigned NonZeroU64(u64);
+    unsigned NonZeroU128(u128);
+    unsigned NonZeroUsize(usize);
+    signed NonZeroI8(i8);
+    signed NonZeroI16(i16);
+    signed NonZeroI32(i32);
+    signed NonZeroI64(i64);
+    signed NonZeroI128(i128);
+    signed NonZeroIsize(isize);
+}
+
 macro_rules! nonzero_unsigned_is_power_of_two {
     ( $( $Ty: ident )+ ) => {
         $(
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index e512d90ef37..ae113a47e95 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1,5 +1,5 @@
 macro_rules! uint_impl {
-    ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr,
+    ($SelfT:ty, $ActualT:ident, $BITS:expr, $MaxV:expr,
         $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
         $reversed:expr, $le_bytes:expr, $be_bytes:expr,
         $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
@@ -15,7 +15,8 @@ macro_rules! uint_impl {
         #[stable(feature = "assoc_int_consts", since = "1.43.0")]
         pub const MIN: Self = 0;
 
-        /// The largest value that can be represented by this integer type.
+        /// The largest value that can be represented by this integer type,
+        #[doc = concat!("2<sup>", $BITS, "</sup> - 1.")]
         ///
         /// # Examples
         ///
@@ -634,6 +635,197 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Returns the logarithm of the number with respect to an arbitrary base.
+        ///
+        /// This method might not be optimized owing to implementation details;
+        /// `log2` can produce results more efficiently for base 2, and `log10`
+        /// can produce results more efficiently for base 10.
+        ///
+        /// # 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).
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".log(5), 1);")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        #[track_caller]
+        #[rustc_inherit_overflow_checks]
+        #[allow(arithmetic_overflow)]
+        pub const fn log(self, base: Self) -> Self {
+            match self.checked_log(base) {
+                Some(n) => n,
+                None => {
+                    // In debug builds, trigger a panic on None.
+                    // This should optimize completely out in release builds.
+                    let _ = Self::MAX + 1;
+
+                    0
+                },
+            }
+        }
+
+        /// Returns the base 2 logarithm of the number.
+        ///
+        /// # 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).
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".log2(), 1);")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        #[track_caller]
+        #[rustc_inherit_overflow_checks]
+        #[allow(arithmetic_overflow)]
+        pub const fn log2(self) -> Self {
+            match self.checked_log2() {
+                Some(n) => n,
+                None => {
+                    // In debug builds, trigger a panic on None.
+                    // This should optimize completely out in release builds.
+                    let _ = Self::MAX + 1;
+
+                    0
+                },
+            }
+        }
+
+        /// Returns the base 10 logarithm of the number.
+        ///
+        /// # 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).
+        ///
+        /// # Example
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".log10(), 1);")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        #[track_caller]
+        #[rustc_inherit_overflow_checks]
+        #[allow(arithmetic_overflow)]
+        pub const fn log10(self) -> Self {
+            match self.checked_log10() {
+                Some(n) => n,
+                None => {
+                    // In debug builds, trigger a panic on None.
+                    // This should optimize completely out in release builds.
+                    let _ = Self::MAX + 1;
+
+                    0
+                },
+            }
+        }
+
+        /// Returns the logarithm of the number with respect to an arbitrary base.
+        ///
+        /// Returns `None` if the number is zero, or if the base is not at least 2.
+        ///
+        /// This method might not be optimized owing to implementation details;
+        /// `checked_log2` can produce results more efficiently for base 2, and
+        /// `checked_log10` can produce results more efficiently for base 10.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".checked_log(5), Some(1));")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        pub const fn checked_log(self, base: Self) -> Option<Self> {
+            if self <= 0 || base <= 1 {
+                None
+            } else {
+                let mut n = 0;
+                let mut r = self;
+
+                // Optimization for 128 bit wide integers.
+                if Self::BITS == 128 {
+                    let b = Self::log2(self) / (Self::log2(base) + 1);
+                    n += b;
+                    r /= base.pow(b as u32);
+                }
+
+                while r >= base {
+                    r /= base;
+                    n += 1;
+                }
+                Some(n)
+            }
+        }
+
+        /// Returns the base 2 logarithm of the number.
+        ///
+        /// Returns `None` if the number is zero.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".checked_log2(), Some(1));")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        pub const fn checked_log2(self) -> Option<Self> {
+            if self <= 0 {
+                None
+            } else {
+                // SAFETY: We just checked that this number is positive
+                let log = (Self::BITS - 1) as Self - unsafe { intrinsics::ctlz_nonzero(self) };
+                Some(log)
+            }
+        }
+
+        /// Returns the base 10 logarithm of the number.
+        ///
+        /// Returns `None` if the number is zero.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(int_log)]
+        #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_log10(), Some(1));")]
+        /// ```
+        #[unstable(feature = "int_log", issue = "70887")]
+        #[must_use = "this returns the result of the operation, \
+                        without modifying the original"]
+        #[inline]
+        pub const fn checked_log10(self) -> Option<Self> {
+            match int_log10::$ActualT(self as $ActualT) {
+                Some(s) => Some(s as Self),
+                None => None,
+            }
+        }
+
         /// Checked negation. Computes `-self`, returning `None` unless `self ==
         /// 0`.
         ///
@@ -1054,9 +1246,9 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
-        #[inline]
+        #[inline(always)]
         pub const fn wrapping_neg(self) -> Self {
-            self.overflowing_neg().0
+            (0 as $SelfT).wrapping_sub(self)
         }
 
         /// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
@@ -1735,7 +1927,7 @@ macro_rules! uint_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
-        #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
         #[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
@@ -1841,7 +2033,7 @@ macro_rules! uint_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 to them
-        #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
         #[inline]
         pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             // SAFETY: integers are plain old datatypes so we can always transmute to them
diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs
index 9d9398fb56d..c2270c864df 100644
--- a/library/core/src/ops/control_flow.rs
+++ b/library/core/src/ops/control_flow.rs
@@ -11,7 +11,6 @@ use crate::{convert, ops};
 ///
 /// Early-exiting from [`Iterator::try_for_each`]:
 /// ```
-/// #![feature(control_flow_enum)]
 /// use std::ops::ControlFlow;
 ///
 /// let r = (2..100).try_for_each(|x| {
@@ -26,7 +25,6 @@ use crate::{convert, ops};
 ///
 /// A basic tree traversal:
 /// ```no_run
-/// #![feature(control_flow_enum)]
 /// use std::ops::ControlFlow;
 ///
 /// pub struct TreeNode<T> {
@@ -48,42 +46,22 @@ use crate::{convert, ops};
 ///     }
 /// }
 /// ```
-#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+#[stable(feature = "control_flow_enum_type", since = "1.55.0")]
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub enum ControlFlow<B, C = ()> {
     /// Move on to the next phase of the operation as normal.
-    #[cfg_attr(not(bootstrap), lang = "Continue")]
+    #[stable(feature = "control_flow_enum_type", since = "1.55.0")]
+    #[lang = "Continue"]
     Continue(C),
     /// Exit the operation without running subsequent phases.
-    #[cfg_attr(not(bootstrap), lang = "Break")]
+    #[stable(feature = "control_flow_enum_type", since = "1.55.0")]
+    #[lang = "Break"]
     Break(B),
     // Yes, the order of the variants doesn't match the type parameters.
     // They're in this order so that `ControlFlow<A, B>` <-> `Result<B, A>`
     // is a no-op conversion in the `Try` implementation.
 }
 
-#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
-#[cfg(bootstrap)]
-impl<B, C> ops::TryV1 for ControlFlow<B, C> {
-    type Output = C;
-    type Error = B;
-    #[inline]
-    fn into_result(self) -> Result<Self::Output, Self::Error> {
-        match self {
-            ControlFlow::Continue(y) => Ok(y),
-            ControlFlow::Break(x) => Err(x),
-        }
-    }
-    #[inline]
-    fn from_error(v: Self::Error) -> Self {
-        ControlFlow::Break(v)
-    }
-    #[inline]
-    fn from_ok(v: Self::Output) -> Self {
-        ControlFlow::Continue(v)
-    }
-}
-
 #[unstable(feature = "try_trait_v2", issue = "84277")]
 impl<B, C> ops::TryV2 for ControlFlow<B, C> {
     type Output = C;
@@ -184,31 +162,9 @@ impl<B, C> ControlFlow<B, C> {
     }
 }
 
-#[cfg(bootstrap)]
-impl<R: ops::TryV1> ControlFlow<R, R::Output> {
-    /// Create a `ControlFlow` from any type implementing `Try`.
-    #[inline]
-    pub(crate) fn from_try(r: R) -> Self {
-        match R::into_result(r) {
-            Ok(v) => ControlFlow::Continue(v),
-            Err(v) => ControlFlow::Break(R::from_error(v)),
-        }
-    }
-
-    /// Convert a `ControlFlow` into any type implementing `Try`;
-    #[inline]
-    pub(crate) fn into_try(self) -> R {
-        match self {
-            ControlFlow::Continue(v) => R::from_ok(v),
-            ControlFlow::Break(v) => v,
-        }
-    }
-}
-
 /// These are used only as part of implementing the iterator adapters.
 /// They have mediocre names and non-obvious semantics, so aren't
 /// currently on a path to potential stabilization.
-#[cfg(not(bootstrap))]
 impl<R: ops::TryV2> ControlFlow<R, R::Output> {
     /// Create a `ControlFlow` from any type implementing `Try`.
     #[inline]
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index f4b1ec377d4..aa654aa5570 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -11,7 +11,7 @@
 /// This destructor consists of two components:
 /// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
 /// - The automatically generated "drop glue" which recursively calls the destructors
-///     of the all fields of this value.
+///     of all the fields of this value.
 ///
 /// As Rust automatically calls the destructors of all contained fields,
 /// you don't have to implement `Drop` in most cases. But there are some cases where
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index 139a8c0eec9..85e04740d96 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -147,8 +147,6 @@ mod function;
 mod generator;
 mod index;
 mod range;
-#[cfg(bootstrap)]
-mod r#try;
 mod try_trait;
 mod unsize;
 
@@ -183,19 +181,10 @@ pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
 #[stable(feature = "inclusive_range", since = "1.26.0")]
 pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
 
-#[unstable(feature = "try_trait", issue = "42327")]
-#[cfg(bootstrap)]
-pub use self::r#try::Try;
-
-#[unstable(feature = "try_trait_transition", reason = "for bootstrap", issue = "none")]
-#[cfg(bootstrap)]
-pub(crate) use self::r#try::Try as TryV1;
-
 #[unstable(feature = "try_trait_v2", issue = "84277")]
 pub use self::try_trait::FromResidual;
 
 #[unstable(feature = "try_trait_v2", issue = "84277")]
-#[cfg(not(bootstrap))]
 pub use self::try_trait::Try;
 
 #[unstable(feature = "try_trait_transition", reason = "for bootstrap", issue = "none")]
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index 684e6bb4a0f..347a346359f 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -686,7 +686,7 @@ impl<T> Bound<T> {
         }
     }
 
-    /// Converts from `&mut Bound<T>` to `Bound<&T>`.
+    /// Converts from `&mut Bound<T>` to `Bound<&mut T>`.
     #[inline]
     #[unstable(feature = "bound_as_ref", issue = "80996")]
     pub fn as_mut(&mut self) -> Bound<&mut T> {
@@ -737,14 +737,13 @@ impl<T: Clone> Bound<&T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(bound_cloned)]
     /// use std::ops::Bound::*;
     /// use std::ops::RangeBounds;
     ///
     /// assert_eq!((1..12).start_bound(), Included(&1));
     /// assert_eq!((1..12).start_bound().cloned(), Included(1));
     /// ```
-    #[unstable(feature = "bound_cloned", issue = "61356")]
+    #[stable(feature = "bound_cloned", since = "1.55.0")]
     pub fn cloned(self) -> Bound<T> {
         match self {
             Bound::Unbounded => Bound::Unbounded,
@@ -813,12 +812,12 @@ pub trait RangeBounds<T: ?Sized> {
         U: ?Sized + PartialOrd<T>,
     {
         (match self.start_bound() {
-            Included(ref start) => *start <= item,
-            Excluded(ref start) => *start < item,
+            Included(start) => start <= item,
+            Excluded(start) => start < item,
             Unbounded => true,
         }) && (match self.end_bound() {
-            Included(ref end) => item <= *end,
-            Excluded(ref end) => item < *end,
+            Included(end) => item <= end,
+            Excluded(end) => item < end,
             Unbounded => true,
         })
     }
diff --git a/library/core/src/ops/try.rs b/library/core/src/ops/try.rs
deleted file mode 100644
index 9d659e78d3c..00000000000
--- a/library/core/src/ops/try.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-/// A trait for customizing the behavior of the `?` operator.
-///
-/// A type implementing `Try` is one that has a canonical way to view it
-/// in terms of a success/failure dichotomy. This trait allows both
-/// extracting those success or failure values from an existing instance and
-/// creating a new instance from a success or failure value.
-#[unstable(feature = "try_trait", issue = "42327")]
-#[rustc_on_unimplemented(
-    on(
-        all(
-            any(from_method = "from_error", from_method = "from_ok"),
-            from_desugaring = "QuestionMark"
-        ),
-        message = "the `?` operator can only be used in {ItemContext} \
-                    that returns `Result` or `Option` \
-                    (or another type that implements `{Try}`)",
-        label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
-        enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
-    ),
-    on(
-        all(from_method = "into_result", from_desugaring = "QuestionMark"),
-        message = "the `?` operator can only be applied to values \
-                    that implement `{Try}`",
-        label = "the `?` operator cannot be applied to type `{Self}`"
-    )
-)]
-#[doc(alias = "?")]
-#[cfg_attr(bootstrap, lang = "try")]
-pub trait Try {
-    /// The type of this value when viewed as successful.
-    #[unstable(feature = "try_trait", issue = "42327")]
-    type Output; // This no longer follows its RFC, but is only used in bootstrap.
-    /// The type of this value when viewed as failed.
-    #[unstable(feature = "try_trait", issue = "42327")]
-    type Error;
-
-    /// Applies the "?" operator. A return of `Ok(t)` means that the
-    /// execution should continue normally, and the result of `?` is the
-    /// value `t`. A return of `Err(e)` means that execution should branch
-    /// to the innermost enclosing `catch`, or return from the function.
-    ///
-    /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
-    /// in the return type of the enclosing scope (which must itself implement
-    /// `Try`). Specifically, the value `X::from_error(From::from(e))`
-    /// is returned, where `X` is the return type of the enclosing function.
-    #[cfg_attr(bootstrap, lang = "into_result")]
-    #[unstable(feature = "try_trait", issue = "42327")]
-    fn into_result(self) -> Result<Self::Output, Self::Error>;
-
-    /// Wrap an error value to construct the composite result. For example,
-    /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
-    #[cfg_attr(bootstrap, lang = "from_error")]
-    #[unstable(feature = "try_trait", issue = "42327")]
-    fn from_error(v: Self::Error) -> Self;
-
-    /// Wrap an OK value to construct the composite result. For example,
-    /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
-    #[cfg_attr(bootstrap, lang = "from_ok")]
-    #[unstable(feature = "try_trait", issue = "42327")]
-    fn from_ok(v: Self::Output) -> Self;
-}
diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs
index 1d9bc452618..6bdcda775ee 100644
--- a/library/core/src/ops/try_trait.rs
+++ b/library/core/src/ops/try_trait.rs
@@ -55,7 +55,6 @@ use crate::ops::ControlFlow;
 /// into the return type using [`Try::from_output`]:
 /// ```
 /// # #![feature(try_trait_v2)]
-/// # #![feature(control_flow_enum)]
 /// # use std::ops::{ControlFlow, Try};
 /// fn simple_try_fold_2<A, T, R: Try<Output = A>>(
 ///     iter: impl Iterator<Item = T>,
@@ -79,7 +78,6 @@ use crate::ops::ControlFlow;
 /// recreated from their corresponding residual, so we'll just call it:
 /// ```
 /// # #![feature(try_trait_v2)]
-/// # #![feature(control_flow_enum)]
 /// # use std::ops::{ControlFlow, Try};
 /// pub fn simple_try_fold_3<A, T, R: Try<Output = A>>(
 ///     iter: impl Iterator<Item = T>,
@@ -130,7 +128,7 @@ use crate::ops::ControlFlow;
     )
 )]
 #[doc(alias = "?")]
-#[cfg_attr(not(bootstrap), lang = "Try")]
+#[lang = "Try"]
 pub trait Try: FromResidual {
     /// The type of the value produced by `?` when *not* short-circuiting.
     #[unstable(feature = "try_trait_v2", issue = "84277")]
@@ -170,7 +168,6 @@ pub trait Try: FromResidual {
     ///
     /// ```
     /// #![feature(try_trait_v2)]
-    /// #![feature(control_flow_enum)]
     /// use std::ops::Try;
     ///
     /// assert_eq!(<Result<_, String> as Try>::from_output(3), Ok(3));
@@ -189,7 +186,7 @@ pub trait Try: FromResidual {
     /// let r = std::iter::empty().try_fold(4, |_, ()| -> Option<_> { unreachable!() });
     /// assert_eq!(r, Some(4));
     /// ```
-    #[cfg_attr(not(bootstrap), lang = "from_output")]
+    #[lang = "from_output"]
     #[unstable(feature = "try_trait_v2", issue = "84277")]
     fn from_output(output: Self::Output) -> Self;
 
@@ -202,7 +199,6 @@ pub trait Try: FromResidual {
     ///
     /// ```
     /// #![feature(try_trait_v2)]
-    /// #![feature(control_flow_enum)]
     /// use std::ops::{ControlFlow, Try};
     ///
     /// assert_eq!(Ok::<_, String>(3).branch(), ControlFlow::Continue(3));
@@ -217,7 +213,7 @@ pub trait Try: FromResidual {
     ///     ControlFlow::Break(ControlFlow::Break(3)),
     /// );
     /// ```
-    #[cfg_attr(not(bootstrap), lang = "branch")]
+    #[lang = "branch"]
     #[unstable(feature = "try_trait_v2", issue = "84277")]
     fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
 }
@@ -323,13 +319,12 @@ pub trait FromResidual<R = <Self as Try>::Residual> {
     /// This should be implemented consistently with the `branch` method such
     /// that applying the `?` operator will get back an equivalent residual:
     /// `FromResidual::from_residual(r).branch() --> ControlFlow::Break(r)`.
-    /// (It may not be an *identical* residual when interconversion is involved.)
+    /// (It must not be an *identical* residual when interconversion is involved.)
     ///
     /// # Examples
     ///
     /// ```
     /// #![feature(try_trait_v2)]
-    /// #![feature(control_flow_enum)]
     /// use std::ops::{ControlFlow, FromResidual};
     ///
     /// assert_eq!(Result::<String, i64>::from_residual(Err(3_u8)), Err(3));
@@ -339,7 +334,7 @@ pub trait FromResidual<R = <Self as Try>::Residual> {
     ///     ControlFlow::Break(5),
     /// );
     /// ```
-    #[cfg_attr(not(bootstrap), lang = "from_residual")]
+    #[lang = "from_residual"]
     #[unstable(feature = "try_trait_v2", issue = "84277")]
     fn from_residual(residual: R) -> Self;
 }
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 4e7afca6a49..78f5954532f 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -49,9 +49,11 @@
 //! no "null" references. Instead, Rust has *optional* pointers, like
 //! the optional owned box, [`Option`]`<`[`Box<T>`]`>`.
 //!
+//! [`Box<T>`]: ../../std/boxed/struct.Box.html
+//!
 //! The following example uses [`Option`] to create an optional box of
-//! [`i32`]. Notice that in order to use the inner [`i32`] value first, the
-//! `check_optional` function needs to use pattern matching to
+//! [`i32`]. Notice that in order to use the inner [`i32`] value, the
+//! `check_optional` function first needs to use pattern matching to
 //! determine whether the box has a value (i.e., it is [`Some(...)`][`Some`]) or
 //! not ([`None`]).
 //!
@@ -83,6 +85,10 @@
 //! * [`ptr::NonNull<U>`]
 //! * `#[repr(transparent)]` struct around one of the types in this list.
 //!
+//! [`Box<U>`]: ../../std/boxed/struct.Box.html
+//! [`num::NonZero*`]: crate::num
+//! [`ptr::NonNull<U>`]: crate::ptr::NonNull
+//!
 //! This is called the "null pointer optimization" or NPO.
 //!
 //! It is further guaranteed that, for the cases above, one can
@@ -90,6 +96,352 @@
 //! from `Some::<T>(_)` to `T` (but transmuting `None::<T>` to `T`
 //! is undefined behaviour).
 //!
+//! # Method overview
+//!
+//! In addition to working with pattern matching, [`Option`] provides a wide
+//! variety of different methods.
+//!
+//! ## Querying the variant
+//!
+//! The [`is_some`] and [`is_none`] methods return [`true`] if the [`Option`]
+//! is [`Some`] or [`None`], respectively.
+//!
+//! [`is_none`]: Option::is_none
+//! [`is_some`]: Option::is_some
+//!
+//! ## Adapters for working with references
+//!
+//! * [`as_ref`] converts from `&Option<T>` to `Option<&T>`
+//! * [`as_mut`] converts from `&mut Option<T>` to `Option<&mut T>`
+//! * [`as_deref`] converts from `&Option<T>` to `Option<&T::Target>`
+//! * [`as_deref_mut`] converts from `&mut Option<T>` to
+//!   `Option<&mut T::Target>`
+//! * [`as_pin_ref`] converts from [`Pin`]`<&Option<T>>` to
+//!   `Option<`[`Pin`]`<&T>>`
+//! * [`as_pin_mut`] converts from [`Pin`]`<&mut Option<T>>` to
+//!   `Option<`[`Pin`]`<&mut T>>`
+//!
+//! [`as_deref`]: Option::as_deref
+//! [`as_deref_mut`]: Option::as_deref_mut
+//! [`as_mut`]: Option::as_mut
+//! [`as_pin_mut`]: Option::as_pin_mut
+//! [`as_pin_ref`]: Option::as_pin_ref
+//! [`as_ref`]: Option::as_ref
+//!
+//! ## Extracting the contained value
+//!
+//! These methods extract the contained value in an [`Option<T>`] when it
+//! is the [`Some`] variant. If the [`Option`] is [`None`]:
+//!
+//! * [`expect`] panics with a provided custom message
+//! * [`unwrap`] panics with a generic message
+//! * [`unwrap_or`] returns the provided default value
+//! * [`unwrap_or_default`] returns the default value of the type `T`
+//!   (which must implement the [`Default`] trait)
+//! * [`unwrap_or_else`] returns the result of evaluating the provided
+//!   function
+//!
+//! [`expect`]: Option::expect
+//! [`unwrap`]: Option::unwrap
+//! [`unwrap_or`]: Option::unwrap_or
+//! [`unwrap_or_default`]: Option::unwrap_or_default
+//! [`unwrap_or_else`]: Option::unwrap_or_else
+//!
+//! ## Transforming contained values
+//!
+//! These methods transform [`Option`] to [`Result`]:
+//!
+//! * [`ok_or`] transforms [`Some(v)`] to [`Ok(v)`], and [`None`] to
+//!   [`Err(err)`] using the provided default `err` value
+//! * [`ok_or_else`] transforms [`Some(v)`] to [`Ok(v)`], and [`None`] to
+//!   a value of [`Err`] using the provided function
+//! * [`transpose`] transposes an [`Option`] of a [`Result`] into a
+//!   [`Result`] of an [`Option`]
+//!
+//! [`Err(err)`]: Err
+//! [`Ok(v)`]: Ok
+//! [`Some(v)`]: Some
+//! [`ok_or`]: Option::ok_or
+//! [`ok_or_else`]: Option::ok_or_else
+//! [`transpose`]: Option::transpose
+//!
+//! These methods transform the [`Some`] variant:
+//!
+//! * [`filter`] calls the provided predicate function on the contained
+//!   value `t` if the [`Option`] is [`Some(t)`], and returns [`Some(t)`]
+//!   if the function returns `true`; otherwise, returns [`None`]
+//! * [`flatten`] removes one level of nesting from an
+//!   [`Option<Option<T>>`]
+//! * [`map`] transforms [`Option<T>`] to [`Option<U>`] by applying the
+//!   provided function to the contained value of [`Some`] and leaving
+//!   [`None`] values unchanged
+//!
+//! [`Some(t)`]: Some
+//! [`filter`]: Option::filter
+//! [`flatten`]: Option::flatten
+//! [`map`]: Option::map
+//!
+//! These methods transform [`Option<T>`] to a value of a possibly
+//! different type `U`:
+//!
+//! * [`map_or`] applies the provided function to the contained value of
+//!   [`Some`], or returns the provided default value if the [`Option`] is
+//!   [`None`]
+//! * [`map_or_else`] applies the provided function to the contained value
+//!   of [`Some`], or returns the result of evaluating the provided
+//!   fallback function if the [`Option`] is [`None`]
+//!
+//! [`map_or`]: Option::map_or
+//! [`map_or_else`]: Option::map_or_else
+//!
+//! These methods combine the [`Some`] variants of two [`Option`] values:
+//!
+//! * [`zip`] returns [`Some((s, o))`] if `self` is [`Some(s)`] and the
+//!   provided [`Option`] value is [`Some(o)`]; otherwise, returns [`None`]
+//! * [`zip_with`] calls the provided function `f` and returns
+//!   [`Some(f(s, o))`] if `self` is [`Some(s)`] and the provided
+//!   [`Option`] value is [`Some(o)`]; otherwise, returns [`None`]
+//!
+//! [`Some(f(s, o))`]: Some
+//! [`Some(o)`]: Some
+//! [`Some(s)`]: Some
+//! [`Some((s, o))`]: Some
+//! [`zip`]: Option::zip
+//! [`zip_with`]: Option::zip_with
+//!
+//! ## Boolean operators
+//!
+//! These methods treat the [`Option`] as a boolean value, where [`Some`]
+//! acts like [`true`] and [`None`] acts like [`false`]. There are two
+//! categories of these methods: ones that take an [`Option`] as input, and
+//! ones that take a function as input (to be lazily evaluated).
+//!
+//! The [`and`], [`or`], and [`xor`] methods take another [`Option`] as
+//! input, and produce an [`Option`] as output. Only the [`and`] method can
+//! produce an [`Option<U>`] value having a different inner type `U` than
+//! [`Option<T>`].
+//!
+//! | method  | self      | input     | output    |
+//! |---------|-----------|-----------|-----------|
+//! | [`and`] | `None`    | (ignored) | `None`    |
+//! | [`and`] | `Some(x)` | `None`    | `None`    |
+//! | [`and`] | `Some(x)` | `Some(y)` | `Some(y)` |
+//! | [`or`]  | `None`    | `None`    | `None`    |
+//! | [`or`]  | `None`    | `Some(y)` | `Some(y)` |
+//! | [`or`]  | `Some(x)` | (ignored) | `Some(x)` |
+//! | [`xor`] | `None`    | `None`    | `None`    |
+//! | [`xor`] | `None`    | `Some(y)` | `Some(y)` |
+//! | [`xor`] | `Some(x)` | `None`    | `Some(x)` |
+//! | [`xor`] | `Some(x)` | `Some(y)` | `None`    |
+//!
+//! [`and`]: Option::and
+//! [`or`]: Option::or
+//! [`xor`]: Option::xor
+//!
+//! The [`and_then`] and [`or_else`] methods take a function as input, and
+//! only evaluate the function when they need to produce a new value. Only
+//! the [`and_then`] method can produce an [`Option<U>`] value having a
+//! different inner type `U` than [`Option<T>`].
+//!
+//! | method       | self      | function input | function result | output    |
+//! |--------------|-----------|----------------|-----------------|-----------|
+//! | [`and_then`] | `None`    | (not provided) | (not evaluated) | `None`    |
+//! | [`and_then`] | `Some(x)` | `x`            | `None`          | `None`    |
+//! | [`and_then`] | `Some(x)` | `x`            | `Some(y)`       | `Some(y)` |
+//! | [`or_else`]  | `None`    | (not provided) | `None`          | `None`    |
+//! | [`or_else`]  | `None`    | (not provided) | `Some(y)`       | `Some(y)` |
+//! | [`or_else`]  | `Some(x)` | (not provided) | (not evaluated) | `Some(x)` |
+//!
+//! [`and_then`]: Option::and_then
+//! [`or_else`]: Option::or_else
+//!
+//! This is an example of using methods like [`and_then`] and [`or`] in a
+//! pipeline of method calls. Early stages of the pipeline pass failure
+//! values ([`None`]) through unchanged, and continue processing on
+//! success values ([`Some`]). Toward the end, [`or`] substitutes an error
+//! message if it receives [`None`].
+//!
+//! ```
+//! # use std::collections::BTreeMap;
+//! let mut bt = BTreeMap::new();
+//! bt.insert(20u8, "foo");
+//! bt.insert(42u8, "bar");
+//! let res = vec![0u8, 1, 11, 200, 22]
+//!     .into_iter()
+//!     .map(|x| {
+//!         // `checked_sub()` returns `None` on error
+//!         x.checked_sub(1)
+//!             // same with `checked_mul()`
+//!             .and_then(|x| x.checked_mul(2))
+//!             // `BTreeMap::get` returns `None` on error
+//!             .and_then(|x| bt.get(&x))
+//!             // Substitute an error message if we have `None` so far
+//!             .or(Some(&"error!"))
+//!             .copied()
+//!             // Won't panic because we unconditionally used `Some` above
+//!             .unwrap()
+//!     })
+//!     .collect::<Vec<_>>();
+//! assert_eq!(res, ["error!", "error!", "foo", "error!", "bar"]);
+//! ```
+//!
+//! ## Comparison operators
+//!
+//! If `T` implements [`PartialOrd`] then [`Option<T>`] will derive its
+//! [`PartialOrd`] implementation.  With this order, [`None`] compares as
+//! less than any [`Some`], and two [`Some`] compare the same way as their
+//! contained values would in `T`.  If `T` also implements
+//! [`Ord`], then so does [`Option<T>`].
+//!
+//! ```
+//! assert!(None < Some(0));
+//! assert!(Some(0) < Some(1));
+//! ```
+//!
+//! ## Iterating over `Option`
+//!
+//! An [`Option`] can be iterated over. This can be helpful if you need an
+//! iterator that is conditionally empty. The iterator will either produce
+//! a single value (when the [`Option`] is [`Some`]), or produce no values
+//! (when the [`Option`] is [`None`]). For example, [`into_iter`] acts like
+//! [`once(v)`] if the [`Option`] is [`Some(v)`], and like [`empty()`] if
+//! the [`Option`] is [`None`].
+//!
+//! [`Some(v)`]: Some
+//! [`empty()`]: crate::iter::empty
+//! [`once(v)`]: crate::iter::once
+//!
+//! Iterators over [`Option<T>`] come in three types:
+//!
+//! * [`into_iter`] consumes the [`Option`] and produces the contained
+//!   value
+//! * [`iter`] produces an immutable reference of type `&T` to the
+//!   contained value
+//! * [`iter_mut`] produces a mutable reference of type `&mut T` to the
+//!   contained value
+//!
+//! [`into_iter`]: Option::into_iter
+//! [`iter`]: Option::iter
+//! [`iter_mut`]: Option::iter_mut
+//!
+//! An iterator over [`Option`] can be useful when chaining iterators, for
+//! example, to conditionally insert items. (It's not always necessary to
+//! explicitly call an iterator constructor: many [`Iterator`] methods that
+//! accept other iterators will also accept iterable types that implement
+//! [`IntoIterator`], which includes [`Option`].)
+//!
+//! ```
+//! let yep = Some(42);
+//! let nope = None;
+//! // chain() already calls into_iter(), so we don't have to do so
+//! let nums: Vec<i32> = (0..4).chain(yep).chain(4..8).collect();
+//! assert_eq!(nums, [0, 1, 2, 3, 42, 4, 5, 6, 7]);
+//! let nums: Vec<i32> = (0..4).chain(nope).chain(4..8).collect();
+//! assert_eq!(nums, [0, 1, 2, 3, 4, 5, 6, 7]);
+//! ```
+//!
+//! One reason to chain iterators in this way is that a function returning
+//! `impl Iterator` must have all possible return values be of the same
+//! concrete type. Chaining an iterated [`Option`] can help with that.
+//!
+//! ```
+//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
+//!     // Explicit returns to illustrate return types matching
+//!     match do_insert {
+//!         true => return (0..4).chain(Some(42)).chain(4..8),
+//!         false => return (0..4).chain(None).chain(4..8),
+//!     }
+//! }
+//! println!("{:?}", make_iter(true).collect::<Vec<_>>());
+//! println!("{:?}", make_iter(false).collect::<Vec<_>>());
+//! ```
+//!
+//! If we try to do the same thing, but using [`once()`] and [`empty()`],
+//! we can't return `impl Iterator` anymore because the concrete types of
+//! the return values differ.
+//!
+//! [`empty()`]: crate::iter::empty
+//! [`once()`]: crate::iter::once
+//!
+//! ```compile_fail,E0308
+//! # use std::iter::{empty, once};
+//! // This won't compile because all possible returns from the function
+//! // must have the same concrete type.
+//! fn make_iter(do_insert: bool) -> impl Iterator<Item = i32> {
+//!     // Explicit returns to illustrate return types not matching
+//!     match do_insert {
+//!         true => return (0..4).chain(once(42)).chain(4..8),
+//!         false => return (0..4).chain(empty()).chain(4..8),
+//!     }
+//! }
+//! ```
+//!
+//! ## Collecting into `Option`
+//!
+//! [`Option`] implements the [`FromIterator`][impl-FromIterator] trait,
+//! which allows an iterator over [`Option`] values to be collected into an
+//! [`Option`] of a collection of each contained value of the original
+//! [`Option`] values, or [`None`] if any of the elements was [`None`].
+//!
+//! [impl-FromIterator]: Option#impl-FromIterator%3COption%3CA%3E%3E
+//!
+//! ```
+//! let v = vec![Some(2), Some(4), None, Some(8)];
+//! let res: Option<Vec<_>> = v.into_iter().collect();
+//! assert_eq!(res, None);
+//! let v = vec![Some(2), Some(4), Some(8)];
+//! let res: Option<Vec<_>> = v.into_iter().collect();
+//! assert_eq!(res, Some(vec![2, 4, 8]));
+//! ```
+//!
+//! [`Option`] also implements the [`Product`][impl-Product] and
+//! [`Sum`][impl-Sum] traits, allowing an iterator over [`Option`] values
+//! to provide the [`product`][Iterator::product] and
+//! [`sum`][Iterator::sum] methods.
+//!
+//! [impl-Product]: Option#impl-Product%3COption%3CU%3E%3E
+//! [impl-Sum]: Option#impl-Sum%3COption%3CU%3E%3E
+//!
+//! ```
+//! let v = vec![None, Some(1), Some(2), Some(3)];
+//! let res: Option<i32> = v.into_iter().sum();
+//! assert_eq!(res, None);
+//! let v = vec![Some(1), Some(2), Some(21)];
+//! let res: Option<i32> = v.into_iter().product();
+//! assert_eq!(res, Some(42));
+//! ```
+//!
+//! ## Modifying an [`Option`] in-place
+//!
+//! These methods return a mutable reference to the contained value of an
+//! [`Option<T>`]:
+//!
+//! * [`insert`] inserts a value, dropping any old contents
+//! * [`get_or_insert`] gets the current value, inserting a provided
+//!   default value if it is [`None`]
+//! * [`get_or_insert_default`] gets the current value, inserting the
+//!   default value of type `T` (which must implement [`Default`]) if it is
+//!   [`None`]
+//! * [`get_or_insert_with`] gets the current value, inserting a default
+//!   computed by the provided function if it is [`None`]
+//!
+//! [`get_or_insert`]: Option::get_or_insert
+//! [`get_or_insert_default`]: Option::get_or_insert_default
+//! [`get_or_insert_with`]: Option::get_or_insert_with
+//! [`insert`]: Option::insert
+//!
+//! These methods transfer ownership of the contained value of an
+//! [`Option`]:
+//!
+//! * [`take`] takes ownership of the contained value of an [`Option`], if
+//!   any, replacing the [`Option`] with [`None`]
+//! * [`replace`] takes ownership of the contained value of an [`Option`],
+//!   if any, replacing the [`Option`] with a [`Some`] containing the
+//!   provided value
+//!
+//! [`replace`]: Option::replace
+//! [`take`]: Option::take
+//!
 //! # Examples
 //!
 //! Basic pattern matching on [`Option`]:
@@ -141,11 +493,6 @@
 //!     None => println!("there are no animals :("),
 //! }
 //! ```
-//!
-//! [`Box<T>`]: ../../std/boxed/struct.Box.html
-//! [`Box<U>`]: ../../std/boxed/struct.Box.html
-//! [`num::NonZero*`]: crate::num
-//! [`ptr::NonNull<U>`]: crate::ptr::NonNull
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -845,6 +1192,7 @@ impl<T> Option<T> {
     /// *val = 3;
     /// assert_eq!(opt.unwrap(), 3);
     /// ```
+    #[must_use = "if you intended to set a value, consider assignment instead"]
     #[inline]
     #[stable(feature = "option_insert", since = "1.53.0")]
     pub fn insert(&mut self, value: T) -> &mut T {
@@ -1051,6 +1399,33 @@ impl<T> Option<T> {
     }
 }
 
+impl<T, U> Option<(T, U)> {
+    /// Unzips an option containing a tuple of two options
+    ///
+    /// If `self` is `Some((a, b))` this method returns `(Some(a), Some(b))`.
+    /// Otherwise, `(None, None)` is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(unzip_option)]
+    ///
+    /// let x = Some((1, "hi"));
+    /// let y = None::<(u8, u32)>;
+    ///
+    /// assert_eq!(x.unzip(), (Some(1), Some("hi")));
+    /// assert_eq!(y.unzip(), (None, None));
+    /// ```
+    #[inline]
+    #[unstable(feature = "unzip_option", issue = "87800", reason = "recently added")]
+    pub const fn unzip(self) -> (Option<T>, Option<U>) {
+        match self {
+            Some((a, b)) => (Some(a), Some(b)),
+            None => (None, None),
+        }
+    }
+}
+
 impl<T: Copy> Option<&T> {
     /// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the
     /// option.
@@ -1267,7 +1642,8 @@ impl<T: Clone> Clone for Option<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for Option<T> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> const Default for Option<T> {
     /// Returns [`None`][Option::None].
     ///
     /// # Examples
@@ -1350,7 +1726,7 @@ impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
     ///
     /// Converts an `Option<`[`String`]`>` into an `Option<`[`usize`]`>`, preserving the original.
     /// The [`map`] method takes the `self` argument by value, consuming the original,
-    /// so this technique uses `as_ref` to first take an `Option` to a reference
+    /// so this technique uses `from` to first take an `Option` to a reference
     /// to the value inside the original.
     ///
     /// [`map`]: Option::map
@@ -1636,38 +2012,6 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     }
 }
 
-/// The error type that results from applying the try operator (`?`) to a `None` value. If you wish
-/// to allow `x?` (where `x` is an `Option<T>`) to be converted into your error type, you can
-/// implement `impl From<NoneError>` for `YourErrorType`. In that case, `x?` within a function that
-/// returns `Result<_, YourErrorType>` will translate a `None` value into an `Err` result.
-#[rustc_diagnostic_item = "none_error"]
-#[unstable(feature = "try_trait", issue = "42327")]
-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
-#[cfg(bootstrap)]
-pub struct NoneError;
-
-#[unstable(feature = "try_trait", issue = "42327")]
-#[cfg(bootstrap)]
-impl<T> ops::TryV1 for Option<T> {
-    type Output = T;
-    type Error = NoneError;
-
-    #[inline]
-    fn into_result(self) -> Result<T, NoneError> {
-        self.ok_or(NoneError)
-    }
-
-    #[inline]
-    fn from_ok(v: T) -> Self {
-        Some(v)
-    }
-
-    #[inline]
-    fn from_error(_: NoneError) -> Self {
-        None
-    }
-}
-
 #[unstable(feature = "try_trait_v2", issue = "84277")]
 impl<T> ops::TryV2 for Option<T> {
     type Output = T;
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index cbb10c324c4..463bec37265 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -2,12 +2,22 @@
 
 #![stable(feature = "core_panic_info", since = "1.41.0")]
 
+mod location;
+mod panic_info;
+mod unwind_safe;
+
 use crate::any::Any;
-use crate::fmt;
+
+#[stable(feature = "panic_hooks", since = "1.10.0")]
+pub use self::location::Location;
+#[stable(feature = "panic_hooks", since = "1.10.0")]
+pub use self::panic_info::PanicInfo;
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+pub use self::unwind_safe::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};
 
 #[doc(hidden)]
 #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
-#[allow_internal_unstable(core_panic)]
+#[allow_internal_unstable(core_panic, const_format_args)]
 #[rustc_diagnostic_item = "core_panic_2015_macro"]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro panic_2015 {
@@ -21,13 +31,13 @@ pub macro panic_2015 {
         $crate::panicking::panic_str($msg)
     ),
     ($fmt:expr, $($arg:tt)+) => (
-        $crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
+        $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
     ),
 }
 
 #[doc(hidden)]
 #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
-#[allow_internal_unstable(core_panic)]
+#[allow_internal_unstable(core_panic, const_format_args)]
 #[rustc_diagnostic_item = "core_panic_2021_macro"]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro panic_2021 {
@@ -35,338 +45,10 @@ pub macro panic_2021 {
         $crate::panicking::panic("explicit panic")
     ),
     ($($t:tt)+) => (
-        $crate::panicking::panic_fmt($crate::format_args!($($t)+))
+        $crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
     ),
 }
 
-/// A struct providing information about a panic.
-///
-/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
-/// function.
-///
-/// [`set_hook`]: ../../std/panic/fn.set_hook.html
-///
-/// # Examples
-///
-/// ```should_panic
-/// use std::panic;
-///
-/// panic::set_hook(Box::new(|panic_info| {
-///     if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
-///         println!("panic occurred: {:?}", s);
-///     } else {
-///         println!("panic occurred");
-///     }
-/// }));
-///
-/// panic!("Normal panic");
-/// ```
-#[lang = "panic_info"]
-#[stable(feature = "panic_hooks", since = "1.10.0")]
-#[derive(Debug)]
-pub struct PanicInfo<'a> {
-    payload: &'a (dyn Any + Send),
-    message: Option<&'a fmt::Arguments<'a>>,
-    location: &'a Location<'a>,
-}
-
-impl<'a> PanicInfo<'a> {
-    #[unstable(
-        feature = "panic_internals",
-        reason = "internal details of the implementation of the `panic!` and related macros",
-        issue = "none"
-    )]
-    #[doc(hidden)]
-    #[inline]
-    pub fn internal_constructor(
-        message: Option<&'a fmt::Arguments<'a>>,
-        location: &'a Location<'a>,
-    ) -> Self {
-        struct NoPayload;
-        PanicInfo { location, message, payload: &NoPayload }
-    }
-
-    #[unstable(
-        feature = "panic_internals",
-        reason = "internal details of the implementation of the `panic!` and related macros",
-        issue = "none"
-    )]
-    #[doc(hidden)]
-    #[inline]
-    pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {
-        self.payload = info;
-    }
-
-    /// Returns the payload associated with the panic.
-    ///
-    /// This will commonly, but not always, be a `&'static str` or [`String`].
-    ///
-    /// [`String`]: ../../std/string/struct.String.html
-    ///
-    /// # Examples
-    ///
-    /// ```should_panic
-    /// use std::panic;
-    ///
-    /// panic::set_hook(Box::new(|panic_info| {
-    ///     if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
-    ///         println!("panic occurred: {:?}", s);
-    ///     } else {
-    ///         println!("panic occurred");
-    ///     }
-    /// }));
-    ///
-    /// panic!("Normal panic");
-    /// ```
-    #[stable(feature = "panic_hooks", since = "1.10.0")]
-    pub fn payload(&self) -> &(dyn Any + Send) {
-        self.payload
-    }
-
-    /// If the `panic!` macro from the `core` crate (not from `std`)
-    /// was used with a formatting string and some additional arguments,
-    /// returns that message ready to be used for example with [`fmt::write`]
-    #[unstable(feature = "panic_info_message", issue = "66745")]
-    pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
-        self.message
-    }
-
-    /// Returns information about the location from which the panic originated,
-    /// if available.
-    ///
-    /// This method will currently always return [`Some`], but this may change
-    /// in future versions.
-    ///
-    /// # Examples
-    ///
-    /// ```should_panic
-    /// use std::panic;
-    ///
-    /// panic::set_hook(Box::new(|panic_info| {
-    ///     if let Some(location) = panic_info.location() {
-    ///         println!("panic occurred in file '{}' at line {}",
-    ///             location.file(),
-    ///             location.line(),
-    ///         );
-    ///     } else {
-    ///         println!("panic occurred but can't get location information...");
-    ///     }
-    /// }));
-    ///
-    /// panic!("Normal panic");
-    /// ```
-    #[stable(feature = "panic_hooks", since = "1.10.0")]
-    pub fn location(&self) -> Option<&Location<'_>> {
-        // NOTE: If this is changed to sometimes return None,
-        // deal with that case in std::panicking::default_hook and std::panicking::begin_panic_fmt.
-        Some(&self.location)
-    }
-}
-
-#[stable(feature = "panic_hook_display", since = "1.26.0")]
-impl fmt::Display for PanicInfo<'_> {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        formatter.write_str("panicked at ")?;
-        if let Some(message) = self.message {
-            write!(formatter, "'{}', ", message)?
-        } else if let Some(payload) = self.payload.downcast_ref::<&'static str>() {
-            write!(formatter, "'{}', ", payload)?
-        }
-        // NOTE: we cannot use downcast_ref::<String>() here
-        // since String is not available in libcore!
-        // The payload is a String when `std::panic!` is called with multiple arguments,
-        // but in that case the message is also available.
-
-        self.location.fmt(formatter)
-    }
-}
-
-/// A struct containing information about the location of a panic.
-///
-/// This structure is created by [`PanicInfo::location()`].
-///
-/// # Examples
-///
-/// ```should_panic
-/// use std::panic;
-///
-/// panic::set_hook(Box::new(|panic_info| {
-///     if let Some(location) = panic_info.location() {
-///         println!("panic occurred in file '{}' at line {}", location.file(), location.line());
-///     } else {
-///         println!("panic occurred but can't get location information...");
-///     }
-/// }));
-///
-/// panic!("Normal panic");
-/// ```
-///
-/// # Comparisons
-///
-/// Comparisons for equality and ordering are made in file, line, then column priority.
-/// Files are compared as strings, not `Path`, which could be unexpected.
-/// See [`Location::file`]'s documentation for more discussion.
-#[lang = "panic_location"]
-#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
-#[stable(feature = "panic_hooks", since = "1.10.0")]
-pub struct Location<'a> {
-    file: &'a str,
-    line: u32,
-    col: u32,
-}
-
-impl<'a> Location<'a> {
-    /// Returns the source location of the caller of this function. If that function's caller is
-    /// annotated then its call location will be returned, and so on up the stack to the first call
-    /// within a non-tracked function body.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::panic::Location;
-    ///
-    /// /// Returns the [`Location`] at which it is called.
-    /// #[track_caller]
-    /// fn get_caller_location() -> &'static Location<'static> {
-    ///     Location::caller()
-    /// }
-    ///
-    /// /// Returns a [`Location`] from within this function's definition.
-    /// fn get_just_one_location() -> &'static Location<'static> {
-    ///     get_caller_location()
-    /// }
-    ///
-    /// let fixed_location = get_just_one_location();
-    /// assert_eq!(fixed_location.file(), file!());
-    /// assert_eq!(fixed_location.line(), 14);
-    /// assert_eq!(fixed_location.column(), 5);
-    ///
-    /// // running the same untracked function in a different location gives us the same result
-    /// let second_fixed_location = get_just_one_location();
-    /// assert_eq!(fixed_location.file(), second_fixed_location.file());
-    /// assert_eq!(fixed_location.line(), second_fixed_location.line());
-    /// assert_eq!(fixed_location.column(), second_fixed_location.column());
-    ///
-    /// let this_location = get_caller_location();
-    /// assert_eq!(this_location.file(), file!());
-    /// assert_eq!(this_location.line(), 28);
-    /// assert_eq!(this_location.column(), 21);
-    ///
-    /// // running the tracked function in a different location produces a different value
-    /// let another_location = get_caller_location();
-    /// assert_eq!(this_location.file(), another_location.file());
-    /// assert_ne!(this_location.line(), another_location.line());
-    /// assert_ne!(this_location.column(), another_location.column());
-    /// ```
-    #[stable(feature = "track_caller", since = "1.46.0")]
-    #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
-    #[track_caller]
-    pub const fn caller() -> &'static Location<'static> {
-        crate::intrinsics::caller_location()
-    }
-}
-
-impl<'a> Location<'a> {
-    #![unstable(
-        feature = "panic_internals",
-        reason = "internal details of the implementation of the `panic!` and related macros",
-        issue = "none"
-    )]
-    #[doc(hidden)]
-    pub const fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
-        Location { file, line, col }
-    }
-
-    /// Returns the name of the source file from which the panic originated.
-    ///
-    /// # `&str`, not `&Path`
-    ///
-    /// The returned name refers to a source path on the compiling system, but it isn't valid to
-    /// represent this directly as a `&Path`. The compiled code may run on a different system with
-    /// a different `Path` implementation than the system providing the contents and this library
-    /// does not currently have a different "host path" type.
-    ///
-    /// The most surprising behavior occurs when "the same" file is reachable via multiple paths in
-    /// the module system (usually using the `#[path = "..."]` attribute or similar), which can
-    /// cause what appears to be identical code to return differing values from this function.
-    ///
-    /// # Cross-compilation
-    ///
-    /// This value is not suitable for passing to `Path::new` or similar constructors when the host
-    /// platform and target platform differ.
-    ///
-    /// # Examples
-    ///
-    /// ```should_panic
-    /// use std::panic;
-    ///
-    /// panic::set_hook(Box::new(|panic_info| {
-    ///     if let Some(location) = panic_info.location() {
-    ///         println!("panic occurred in file '{}'", location.file());
-    ///     } else {
-    ///         println!("panic occurred but can't get location information...");
-    ///     }
-    /// }));
-    ///
-    /// panic!("Normal panic");
-    /// ```
-    #[stable(feature = "panic_hooks", since = "1.10.0")]
-    pub fn file(&self) -> &str {
-        self.file
-    }
-
-    /// Returns the line number from which the panic originated.
-    ///
-    /// # Examples
-    ///
-    /// ```should_panic
-    /// use std::panic;
-    ///
-    /// panic::set_hook(Box::new(|panic_info| {
-    ///     if let Some(location) = panic_info.location() {
-    ///         println!("panic occurred at line {}", location.line());
-    ///     } else {
-    ///         println!("panic occurred but can't get location information...");
-    ///     }
-    /// }));
-    ///
-    /// panic!("Normal panic");
-    /// ```
-    #[stable(feature = "panic_hooks", since = "1.10.0")]
-    pub fn line(&self) -> u32 {
-        self.line
-    }
-
-    /// Returns the column from which the panic originated.
-    ///
-    /// # Examples
-    ///
-    /// ```should_panic
-    /// use std::panic;
-    ///
-    /// panic::set_hook(Box::new(|panic_info| {
-    ///     if let Some(location) = panic_info.location() {
-    ///         println!("panic occurred at column {}", location.column());
-    ///     } else {
-    ///         println!("panic occurred but can't get location information...");
-    ///     }
-    /// }));
-    ///
-    /// panic!("Normal panic");
-    /// ```
-    #[stable(feature = "panic_col", since = "1.25.0")]
-    pub fn column(&self) -> u32 {
-        self.col
-    }
-}
-
-#[stable(feature = "panic_hook_display", since = "1.26.0")]
-impl fmt::Display for Location<'_> {
-    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(formatter, "{}:{}:{}", self.file, self.line, self.col)
-    }
-}
-
 /// An internal trait used by libstd to pass data from libstd to `panic_unwind`
 /// and other panic runtimes. Not intended to be stabilized any time soon, do
 /// not use.
diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs
new file mode 100644
index 00000000000..a482414caaf
--- /dev/null
+++ b/library/core/src/panic/location.rs
@@ -0,0 +1,189 @@
+use crate::fmt;
+
+/// A struct containing information about the location of a panic.
+///
+/// This structure is created by [`PanicInfo::location()`].
+///
+/// [`PanicInfo::location()`]: crate::panic::PanicInfo::location
+///
+/// # Examples
+///
+/// ```should_panic
+/// use std::panic;
+///
+/// panic::set_hook(Box::new(|panic_info| {
+///     if let Some(location) = panic_info.location() {
+///         println!("panic occurred in file '{}' at line {}", location.file(), location.line());
+///     } else {
+///         println!("panic occurred but can't get location information...");
+///     }
+/// }));
+///
+/// panic!("Normal panic");
+/// ```
+///
+/// # Comparisons
+///
+/// Comparisons for equality and ordering are made in file, line, then column priority.
+/// Files are compared as strings, not `Path`, which could be unexpected.
+/// See [`Location::file`]'s documentation for more discussion.
+#[lang = "panic_location"]
+#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
+pub struct Location<'a> {
+    file: &'a str,
+    line: u32,
+    col: u32,
+}
+
+impl<'a> Location<'a> {
+    /// Returns the source location of the caller of this function. If that function's caller is
+    /// annotated then its call location will be returned, and so on up the stack to the first call
+    /// within a non-tracked function body.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::panic::Location;
+    ///
+    /// /// Returns the [`Location`] at which it is called.
+    /// #[track_caller]
+    /// fn get_caller_location() -> &'static Location<'static> {
+    ///     Location::caller()
+    /// }
+    ///
+    /// /// Returns a [`Location`] from within this function's definition.
+    /// fn get_just_one_location() -> &'static Location<'static> {
+    ///     get_caller_location()
+    /// }
+    ///
+    /// let fixed_location = get_just_one_location();
+    /// assert_eq!(fixed_location.file(), file!());
+    /// assert_eq!(fixed_location.line(), 14);
+    /// assert_eq!(fixed_location.column(), 5);
+    ///
+    /// // running the same untracked function in a different location gives us the same result
+    /// let second_fixed_location = get_just_one_location();
+    /// assert_eq!(fixed_location.file(), second_fixed_location.file());
+    /// assert_eq!(fixed_location.line(), second_fixed_location.line());
+    /// assert_eq!(fixed_location.column(), second_fixed_location.column());
+    ///
+    /// let this_location = get_caller_location();
+    /// assert_eq!(this_location.file(), file!());
+    /// assert_eq!(this_location.line(), 28);
+    /// assert_eq!(this_location.column(), 21);
+    ///
+    /// // running the tracked function in a different location produces a different value
+    /// let another_location = get_caller_location();
+    /// assert_eq!(this_location.file(), another_location.file());
+    /// assert_ne!(this_location.line(), another_location.line());
+    /// assert_ne!(this_location.column(), another_location.column());
+    /// ```
+    #[stable(feature = "track_caller", since = "1.46.0")]
+    #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
+    #[track_caller]
+    pub const fn caller() -> &'static Location<'static> {
+        crate::intrinsics::caller_location()
+    }
+
+    /// Returns the name of the source file from which the panic originated.
+    ///
+    /// # `&str`, not `&Path`
+    ///
+    /// The returned name refers to a source path on the compiling system, but it isn't valid to
+    /// represent this directly as a `&Path`. The compiled code may run on a different system with
+    /// a different `Path` implementation than the system providing the contents and this library
+    /// does not currently have a different "host path" type.
+    ///
+    /// The most surprising behavior occurs when "the same" file is reachable via multiple paths in
+    /// the module system (usually using the `#[path = "..."]` attribute or similar), which can
+    /// cause what appears to be identical code to return differing values from this function.
+    ///
+    /// # Cross-compilation
+    ///
+    /// This value is not suitable for passing to `Path::new` or similar constructors when the host
+    /// platform and target platform differ.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred in file '{}'", location.file());
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn file(&self) -> &str {
+        self.file
+    }
+
+    /// Returns the line number from which the panic originated.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred at line {}", location.line());
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn line(&self) -> u32 {
+        self.line
+    }
+
+    /// Returns the column from which the panic originated.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred at column {}", location.column());
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_col", since = "1.25.0")]
+    pub fn column(&self) -> u32 {
+        self.col
+    }
+}
+
+#[unstable(
+    feature = "panic_internals",
+    reason = "internal details of the implementation of the `panic!` and related macros",
+    issue = "none"
+)]
+impl<'a> Location<'a> {
+    #[doc(hidden)]
+    pub const fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
+        Location { file, line, col }
+    }
+}
+
+#[stable(feature = "panic_hook_display", since = "1.26.0")]
+impl fmt::Display for Location<'_> {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(formatter, "{}:{}:{}", self.file, self.line, self.col)
+    }
+}
diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs
new file mode 100644
index 00000000000..a52a0022e5d
--- /dev/null
+++ b/library/core/src/panic/panic_info.rs
@@ -0,0 +1,145 @@
+use crate::any::Any;
+use crate::fmt;
+use crate::panic::Location;
+
+/// A struct providing information about a panic.
+///
+/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
+/// function.
+///
+/// [`set_hook`]: ../../std/panic/fn.set_hook.html
+///
+/// # Examples
+///
+/// ```should_panic
+/// use std::panic;
+///
+/// panic::set_hook(Box::new(|panic_info| {
+///     if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
+///         println!("panic occurred: {:?}", s);
+///     } else {
+///         println!("panic occurred");
+///     }
+/// }));
+///
+/// panic!("Normal panic");
+/// ```
+#[lang = "panic_info"]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
+#[derive(Debug)]
+pub struct PanicInfo<'a> {
+    payload: &'a (dyn Any + Send),
+    message: Option<&'a fmt::Arguments<'a>>,
+    location: &'a Location<'a>,
+}
+
+impl<'a> PanicInfo<'a> {
+    #[unstable(
+        feature = "panic_internals",
+        reason = "internal details of the implementation of the `panic!` and related macros",
+        issue = "none"
+    )]
+    #[doc(hidden)]
+    #[inline]
+    pub fn internal_constructor(
+        message: Option<&'a fmt::Arguments<'a>>,
+        location: &'a Location<'a>,
+    ) -> Self {
+        struct NoPayload;
+        PanicInfo { location, message, payload: &NoPayload }
+    }
+
+    #[unstable(
+        feature = "panic_internals",
+        reason = "internal details of the implementation of the `panic!` and related macros",
+        issue = "none"
+    )]
+    #[doc(hidden)]
+    #[inline]
+    pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {
+        self.payload = info;
+    }
+
+    /// Returns the payload associated with the panic.
+    ///
+    /// This will commonly, but not always, be a `&'static str` or [`String`].
+    ///
+    /// [`String`]: ../../std/string/struct.String.html
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
+    ///         println!("panic occurred: {:?}", s);
+    ///     } else {
+    ///         println!("panic occurred");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn payload(&self) -> &(dyn Any + Send) {
+        self.payload
+    }
+
+    /// If the `panic!` macro from the `core` crate (not from `std`)
+    /// was used with a formatting string and some additional arguments,
+    /// returns that message ready to be used for example with [`fmt::write`]
+    #[unstable(feature = "panic_info_message", issue = "66745")]
+    pub fn message(&self) -> Option<&fmt::Arguments<'_>> {
+        self.message
+    }
+
+    /// Returns information about the location from which the panic originated,
+    /// if available.
+    ///
+    /// This method will currently always return [`Some`], but this may change
+    /// in future versions.
+    ///
+    /// # Examples
+    ///
+    /// ```should_panic
+    /// use std::panic;
+    ///
+    /// panic::set_hook(Box::new(|panic_info| {
+    ///     if let Some(location) = panic_info.location() {
+    ///         println!("panic occurred in file '{}' at line {}",
+    ///             location.file(),
+    ///             location.line(),
+    ///         );
+    ///     } else {
+    ///         println!("panic occurred but can't get location information...");
+    ///     }
+    /// }));
+    ///
+    /// panic!("Normal panic");
+    /// ```
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
+    pub fn location(&self) -> Option<&Location<'_>> {
+        // NOTE: If this is changed to sometimes return None,
+        // deal with that case in std::panicking::default_hook and std::panicking::begin_panic_fmt.
+        Some(&self.location)
+    }
+}
+
+#[stable(feature = "panic_hook_display", since = "1.26.0")]
+impl fmt::Display for PanicInfo<'_> {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        formatter.write_str("panicked at ")?;
+        if let Some(message) = self.message {
+            write!(formatter, "'{}', ", message)?
+        } else if let Some(payload) = self.payload.downcast_ref::<&'static str>() {
+            write!(formatter, "'{}', ", payload)?
+        }
+        // NOTE: we cannot use downcast_ref::<String>() here
+        // since String is not available in libcore!
+        // The payload is a String when `std::panic!` is called with multiple arguments,
+        // but in that case the message is also available.
+
+        self.location.fmt(formatter)
+    }
+}
diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs
new file mode 100644
index 00000000000..092b7cf0f2c
--- /dev/null
+++ b/library/core/src/panic/unwind_safe.rs
@@ -0,0 +1,305 @@
+use crate::cell::UnsafeCell;
+use crate::fmt;
+use crate::future::Future;
+use crate::ops::{Deref, DerefMut};
+use crate::pin::Pin;
+use crate::ptr::{NonNull, Unique};
+use crate::stream::Stream;
+use crate::task::{Context, Poll};
+
+/// A marker trait which represents "panic safe" types in Rust.
+///
+/// This trait is implemented by default for many types and behaves similarly in
+/// terms of inference of implementation to the [`Send`] and [`Sync`] traits. The
+/// purpose of this trait is to encode what types are safe to cross a [`catch_unwind`]
+/// boundary with no fear of unwind safety.
+///
+/// [`catch_unwind`]: ../../std/panic/fn.catch_unwind.html
+///
+/// ## What is unwind safety?
+///
+/// In Rust a function can "return" early if it either panics or calls a
+/// function which transitively panics. This sort of control flow is not always
+/// anticipated, and has the possibility of causing subtle bugs through a
+/// combination of two critical components:
+///
+/// 1. A data structure is in a temporarily invalid state when the thread
+///    panics.
+/// 2. This broken invariant is then later observed.
+///
+/// Typically in Rust, it is difficult to perform step (2) because catching a
+/// panic involves either spawning a thread (which in turns makes it difficult
+/// to later witness broken invariants) or using the `catch_unwind` function in this
+/// module. Additionally, even if an invariant is witnessed, it typically isn't a
+/// problem in Rust because there are no uninitialized values (like in C or C++).
+///
+/// It is possible, however, for **logical** invariants to be broken in Rust,
+/// which can end up causing behavioral bugs. Another key aspect of unwind safety
+/// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
+/// memory unsafety.
+///
+/// That was a bit of a whirlwind tour of unwind safety, but for more information
+/// about unwind safety and how it applies to Rust, see an [associated RFC][rfc].
+///
+/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
+///
+/// ## What is `UnwindSafe`?
+///
+/// Now that we've got an idea of what unwind safety is in Rust, it's also
+/// important to understand what this trait represents. As mentioned above, one
+/// way to witness broken invariants is through the `catch_unwind` function in this
+/// module as it allows catching a panic and then re-using the environment of
+/// the closure.
+///
+/// Simply put, a type `T` implements `UnwindSafe` if it cannot easily allow
+/// witnessing a broken invariant through the use of `catch_unwind` (catching a
+/// panic). This trait is an auto trait, so it is automatically implemented for
+/// many types, and it is also structurally composed (e.g., a struct is unwind
+/// safe if all of its components are unwind safe).
+///
+/// Note, however, that this is not an unsafe trait, so there is not a succinct
+/// contract that this trait is providing. Instead it is intended as more of a
+/// "speed bump" to alert users of `catch_unwind` that broken invariants may be
+/// witnessed and may need to be accounted for.
+///
+/// ## Who implements `UnwindSafe`?
+///
+/// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
+/// unwind safe. The general idea is that any mutable state which can be shared
+/// across `catch_unwind` is not unwind safe by default. This is because it is very
+/// easy to witness a broken invariant outside of `catch_unwind` as the data is
+/// simply accessed as usual.
+///
+/// Types like `&Mutex<T>`, however, are unwind safe because they implement
+/// poisoning by default. They still allow witnessing a broken invariant, but
+/// they already provide their own "speed bumps" to do so.
+///
+/// ## When should `UnwindSafe` be used?
+///
+/// It is not intended that most types or functions need to worry about this trait.
+/// It is only used as a bound on the `catch_unwind` function and as mentioned
+/// above, the lack of `unsafe` means it is mostly an advisory. The
+/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
+/// implemented for any closed over variables passed to `catch_unwind`.
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "unwind_safe_trait")]
+#[rustc_on_unimplemented(
+    message = "the type `{Self}` may not be safely transferred across an unwind boundary",
+    label = "`{Self}` may not be safely transferred across an unwind boundary"
+)]
+pub auto trait UnwindSafe {}
+
+/// A marker trait representing types where a shared reference is considered
+/// unwind safe.
+///
+/// This trait is namely not implemented by [`UnsafeCell`], the root of all
+/// interior mutability.
+///
+/// This is a "helper marker trait" used to provide impl blocks for the
+/// [`UnwindSafe`] trait, for more information see that documentation.
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "ref_unwind_safe_trait")]
+#[rustc_on_unimplemented(
+    message = "the type `{Self}` may contain interior mutability and a reference may not be safely \
+               transferrable across a catch_unwind boundary",
+    label = "`{Self}` may contain interior mutability and a reference may not be safely \
+             transferrable across a catch_unwind boundary"
+)]
+pub auto trait RefUnwindSafe {}
+
+/// A simple wrapper around a type to assert that it is unwind safe.
+///
+/// When using [`catch_unwind`] it may be the case that some of the closed over
+/// variables are not unwind safe. For example if `&mut T` is captured the
+/// compiler will generate a warning indicating that it is not unwind safe. It
+/// might not be the case, however, that this is actually a problem due to the
+/// specific usage of [`catch_unwind`] if unwind safety is specifically taken into
+/// account. This wrapper struct is useful for a quick and lightweight
+/// annotation that a variable is indeed unwind safe.
+///
+/// [`catch_unwind`]: ../../std/panic/fn.catch_unwind.html
+///
+/// # Examples
+///
+/// One way to use `AssertUnwindSafe` is to assert that the entire closure
+/// itself is unwind safe, bypassing all checks for all variables:
+///
+/// ```
+/// use std::panic::{self, AssertUnwindSafe};
+///
+/// let mut variable = 4;
+///
+/// // This code will not compile because the closure captures `&mut variable`
+/// // which is not considered unwind safe by default.
+///
+/// // panic::catch_unwind(|| {
+/// //     variable += 3;
+/// // });
+///
+/// // This, however, will compile due to the `AssertUnwindSafe` wrapper
+/// let result = panic::catch_unwind(AssertUnwindSafe(|| {
+///     variable += 3;
+/// }));
+/// // ...
+/// ```
+///
+/// Wrapping the entire closure amounts to a blanket assertion that all captured
+/// variables are unwind safe. This has the downside that if new captures are
+/// added in the future, they will also be considered unwind safe. Therefore,
+/// you may prefer to just wrap individual captures, as shown below. This is
+/// more annotation, but it ensures that if a new capture is added which is not
+/// unwind safe, you will get a compilation error at that time, which will
+/// allow you to consider whether that new capture in fact represent a bug or
+/// not.
+///
+/// ```
+/// use std::panic::{self, AssertUnwindSafe};
+///
+/// let mut variable = 4;
+/// let other_capture = 3;
+///
+/// let result = {
+///     let mut wrapper = AssertUnwindSafe(&mut variable);
+///     panic::catch_unwind(move || {
+///         **wrapper += other_capture;
+///     })
+/// };
+/// // ...
+/// ```
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+pub struct AssertUnwindSafe<T>(#[stable(feature = "catch_unwind", since = "1.9.0")] pub T);
+
+// Implementations of the `UnwindSafe` trait:
+//
+// * By default everything is unwind safe
+// * pointers T contains mutability of some form are not unwind safe
+// * Unique, an owning pointer, lifts an implementation
+// * Types like Mutex/RwLock which are explicitly poisoned are unwind safe
+// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
+
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: ?Sized> !UnwindSafe for &mut T {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for &T {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
+#[unstable(feature = "ptr_internals", issue = "none")]
+impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
+#[stable(feature = "nonnull", since = "1.25.0")]
+impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> UnwindSafe for AssertUnwindSafe<T> {}
+
+// Pretty simple implementations for the `RefUnwindSafe` marker trait,
+// basically just saying that `UnsafeCell` is the
+// only thing which doesn't implement it (which then transitively applies to
+// everything else).
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
+
+#[cfg(target_has_atomic_load_store = "ptr")]
+#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicIsize {}
+#[cfg(target_has_atomic_load_store = "8")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicI8 {}
+#[cfg(target_has_atomic_load_store = "16")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicI16 {}
+#[cfg(target_has_atomic_load_store = "32")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicI32 {}
+#[cfg(target_has_atomic_load_store = "64")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicI64 {}
+#[cfg(target_has_atomic_load_store = "128")]
+#[unstable(feature = "integer_atomics", issue = "32976")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicI128 {}
+
+#[cfg(target_has_atomic_load_store = "ptr")]
+#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicUsize {}
+#[cfg(target_has_atomic_load_store = "8")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicU8 {}
+#[cfg(target_has_atomic_load_store = "16")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicU16 {}
+#[cfg(target_has_atomic_load_store = "32")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicU32 {}
+#[cfg(target_has_atomic_load_store = "64")]
+#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicU64 {}
+#[cfg(target_has_atomic_load_store = "128")]
+#[unstable(feature = "integer_atomics", issue = "32976")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicU128 {}
+
+#[cfg(target_has_atomic_load_store = "8")]
+#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
+impl RefUnwindSafe for crate::sync::atomic::AtomicBool {}
+
+#[cfg(target_has_atomic_load_store = "ptr")]
+#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
+impl<T> RefUnwindSafe for crate::sync::atomic::AtomicPtr<T> {}
+
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> Deref for AssertUnwindSafe<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<T> DerefMut for AssertUnwindSafe<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
+
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+impl<R, F: FnOnce() -> R> FnOnce<()> for AssertUnwindSafe<F> {
+    type Output = R;
+
+    extern "rust-call" fn call_once(self, _args: ()) -> R {
+        (self.0)()
+    }
+}
+
+#[stable(feature = "std_debug", since = "1.16.0")]
+impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("AssertUnwindSafe").field(&self.0).finish()
+    }
+}
+
+#[stable(feature = "futures_api", since = "1.36.0")]
+impl<F: Future> Future for AssertUnwindSafe<F> {
+    type Output = F::Output;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        // SAFETY: pin projection. AssertUnwindSafe follows structural pinning.
+        let pinned_field = unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) };
+        F::poll(pinned_field, cx)
+    }
+}
+
+#[unstable(feature = "async_stream", issue = "79024")]
+impl<S: Stream> Stream for AssertUnwindSafe<S> {
+    type Item = S::Item;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
+        // SAFETY: pin projection. AssertUnwindSafe follows structural pinning.
+        unsafe { self.map_unchecked_mut(|x| &mut x.0) }.poll_next(cx)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 3e3e96fcd7f..2ec6b4d15ff 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -74,6 +74,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[track_caller]
+#[cfg_attr(not(bootstrap), lang = "panic_fmt")] // needed for const-evaluated panics
 pub fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
         super::intrinsics::abort()
@@ -92,6 +93,20 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
     unsafe { panic_impl(&pi) }
 }
 
+/// This function is used instead of panic_fmt in const eval.
+#[cfg(not(bootstrap))]
+#[lang = "const_panic_fmt"]
+pub const fn const_panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
+    if let Some(msg) = fmt.as_str() {
+        panic_str(msg);
+    } else {
+        // SAFETY: This is only evaluated at compile time, which reliably
+        // handles this UB (in case this branch turns out to be reachable
+        // somehow).
+        unsafe { crate::hint::unreachable_unchecked() };
+    }
+}
+
 #[derive(Debug)]
 #[doc(hidden)]
 pub enum AssertKind {
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 3d888299485..6a1a84bafa3 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -159,9 +159,9 @@
 //! section needs to function correctly.
 //!
 //! Notice that this guarantee does *not* mean that memory does not leak! It is still
-//! completely okay not ever to call [`drop`] on a pinned element (e.g., you can still
+//! completely okay to not ever call [`drop`] on a pinned element (e.g., you can still
 //! call [`mem::forget`] on a <code>[Pin]<[Box]\<T>></code>). In the example of the doubly-linked
-//! list, that element would just stay in the list. However you may not free or reuse the storage
+//! list, that element would just stay in the list. However you must not free or reuse the storage
 //! *without calling [`drop`]*.
 //!
 //! # `Drop` implementation
@@ -802,6 +802,44 @@ impl<T: ?Sized> Pin<&'static T> {
     }
 }
 
+impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> {
+    /// Gets a pinned mutable reference from this nested pinned pointer.
+    ///
+    /// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
+    /// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
+    /// move in the future, and this method does not enable the pointee to move. "Malicious"
+    /// implementations of `P::DerefMut` are likewise ruled out by the contract of
+    /// `Pin::new_unchecked`.
+    #[unstable(feature = "pin_deref_mut", issue = "86918")]
+    #[inline(always)]
+    pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> {
+        // SAFETY: What we're asserting here is that going from
+        //
+        //     Pin<&mut Pin<P>>
+        //
+        // to
+        //
+        //     Pin<&mut P::Target>
+        //
+        // is safe.
+        //
+        // We need to ensure that two things hold for that to be the case:
+        //
+        // 1) Once we give out a `Pin<&mut P::Target>`, an `&mut P::Target` will not be given out.
+        // 2) By giving out a `Pin<&mut P::Target>`, we do not risk of violating `Pin<&mut Pin<P>>`
+        //
+        // The existence of `Pin<P>` is sufficient to guarantee #1: since we already have a
+        // `Pin<P>`, it must already uphold the pinning guarantees, which must mean that
+        // `Pin<&mut P::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
+        // on the fact that P is _also_ pinned.
+        //
+        // For #2, we need to ensure that code given a `Pin<&mut P::Target>` cannot cause the
+        // `Pin<P>` to move? That is not possible, since `Pin<&mut P::Target>` no longer retains
+        // any access to the `P` itself, much less the `Pin<P>`.
+        unsafe { self.get_unchecked_mut() }.as_mut()
+    }
+}
+
 impl<T: ?Sized> Pin<&'static mut T> {
     /// Get a pinned mutable reference from a static mutable reference.
     ///
diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs
index 79753c1fb66..ccd36a428e2 100644
--- a/library/core/src/prelude/mod.rs
+++ b/library/core/src/prelude/mod.rs
@@ -11,9 +11,9 @@ pub mod v1;
 /// The 2015 version of the core prelude.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2015", issue = "85684")]
+#[stable(feature = "prelude_2015", since = "1.55.0")]
 pub mod rust_2015 {
-    #[unstable(feature = "prelude_2015", issue = "85684")]
+    #[stable(feature = "prelude_2015", since = "1.55.0")]
     #[doc(no_inline)]
     pub use super::v1::*;
 }
@@ -21,9 +21,9 @@ pub mod rust_2015 {
 /// The 2018 version of the core prelude.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2018", issue = "85684")]
+#[stable(feature = "prelude_2018", since = "1.55.0")]
 pub mod rust_2018 {
-    #[unstable(feature = "prelude_2018", issue = "85684")]
+    #[stable(feature = "prelude_2018", since = "1.55.0")]
     #[doc(no_inline)]
     pub use super::v1::*;
 }
@@ -31,17 +31,17 @@ pub mod rust_2018 {
 /// The 2021 version of the core prelude.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2021", issue = "85684")]
+#[stable(feature = "prelude_2021", since = "1.55.0")]
 pub mod rust_2021 {
-    #[unstable(feature = "prelude_2021", issue = "85684")]
+    #[stable(feature = "prelude_2021", since = "1.55.0")]
     #[doc(no_inline)]
     pub use super::v1::*;
 
-    #[unstable(feature = "prelude_2021", issue = "85684")]
+    #[stable(feature = "prelude_2021", since = "1.55.0")]
     #[doc(no_inline)]
     pub use crate::iter::FromIterator;
 
-    #[unstable(feature = "prelude_2021", issue = "85684")]
+    #[stable(feature = "prelude_2021", since = "1.55.0")]
     #[doc(no_inline)]
     pub use crate::convert::{TryFrom, TryInto};
 }
diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
index c89fe57cb05..6b51ef5b012 100644
--- a/library/core/src/prelude/v1.rs
+++ b/library/core/src/prelude/v1.rs
@@ -55,11 +55,27 @@ pub use crate::hash::macros::Hash;
 #[allow(deprecated)]
 #[doc(no_inline)]
 pub use crate::{
-    asm, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
-    format_args_nl, global_asm, include, include_bytes, include_str, line, llvm_asm, log_syntax,
-    module_path, option_env, stringify, trace_macros,
+    assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
+    format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path,
+    option_env, stringify, trace_macros,
 };
 
+#[unstable(
+    feature = "asm",
+    issue = "72016",
+    reason = "inline assembly is not stable enough for use and is subject to change"
+)]
+#[doc(no_inline)]
+pub use crate::arch::asm;
+
+#[unstable(
+    feature = "global_asm",
+    issue = "35119",
+    reason = "`global_asm!` is not stable enough for use and is subject to change"
+)]
+#[doc(no_inline)]
+pub use crate::arch::global_asm;
+
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow(deprecated, deprecated_in_future)]
 #[doc(no_inline)]
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 8348afb2a56..95e86a688be 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -48,7 +48,7 @@ impl<T: ?Sized> *const T {
         self as _
     }
 
-    /// Decompose a (possibly wide) pointer into is address and metadata components.
+    /// Decompose a (possibly wide) pointer into its address and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts`].
     #[unstable(feature = "ptr_metadata", issue = "81513")]
@@ -244,7 +244,7 @@ impl<T: ?Sized> *const T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
     /// be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z`
@@ -404,7 +404,7 @@ impl<T: ?Sized> *const T {
     ///
     /// [`guaranteed_ne`]: #method.guaranteed_ne
     ///
-    /// The return value may change depending on the compiler version and unsafe code may not
+    /// The return value may change depending on the compiler version and unsafe code might not
     /// rely on the result of this function for soundness. It is suggested to only use this function
     /// for performance optimizations where spurious `false` return values by this function do not
     /// affect the outcome, but just the performance.
@@ -435,7 +435,7 @@ impl<T: ?Sized> *const T {
     ///
     /// [`guaranteed_eq`]: #method.guaranteed_eq
     ///
-    /// The return value may change depending on the compiler version and unsafe code may not
+    /// The return value may change depending on the compiler version and unsafe code might not
     /// rely on the result of this function for soundness. It is suggested to only use this function
     /// for performance optimizations where spurious `false` return values by this function do not
     /// affect the outcome, but just the performance.
@@ -590,7 +590,7 @@ impl<T: ?Sized> *const T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
     /// be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z`
@@ -652,7 +652,7 @@ impl<T: ?Sized> *const T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
     /// be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z`
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index 7c7dce0ce74..287ae69acd1 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -101,7 +101,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
 ///
 /// This function is safe but the returned pointer is not necessarily safe to dereference.
 /// For slices, see the documentation of [`slice::from_raw_parts`] for safety requirements.
-/// For trait objects, the metadata must come from a pointer to the same underlying ereased type.
+/// For trait objects, the metadata must come from a pointer to the same underlying erased type.
 ///
 /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts
 #[unstable(feature = "ptr_metadata", issue = "81513")]
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 214d7c8bc15..47fad15e333 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -685,6 +685,13 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
 pub const unsafe fn read<T>(src: *const T) -> T {
+    // We are calling the intrinsics directly to avoid function calls in the generated code
+    // as `intrinsics::copy_nonoverlapping` is a wrapper function.
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
     let mut tmp = MaybeUninit::<T>::uninit();
     // SAFETY: the caller must guarantee that `src` is valid for reads.
     // `src` cannot overlap `tmp` because `tmp` was just allocated on
@@ -871,14 +878,20 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
+#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
 pub const unsafe fn write<T>(dst: *mut T, src: T) {
+    // We are calling the intrinsics directly to avoid function calls in the generated code
+    // as `intrinsics::copy_nonoverlapping` is a wrapper function.
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
     // SAFETY: the caller must guarantee that `dst` is valid for writes.
     // `dst` cannot overlap `src` because the caller has mutable access
     // to `dst` while `src` is owned by this function.
     unsafe {
         copy_nonoverlapping(&src as *const T, dst, 1);
-        // We are calling the intrinsic directly to avoid function calls in the generated code.
         intrinsics::forget(src);
     }
 }
@@ -962,7 +975,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 /// ```
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
-#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
+#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
 pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
     // SAFETY: the caller must guarantee that `dst` is valid for writes.
     // `dst` cannot overlap `src` because the caller has mutable access
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 750279ac0db..adc64cb2bd3 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -47,7 +47,7 @@ impl<T: ?Sized> *mut T {
         self as _
     }
 
-    /// Decompose a (possibly wide) pointer into is address and metadata components.
+    /// Decompose a (possibly wide) pointer into its address and metadata components.
     ///
     /// The pointer can be later reconstructed with [`from_raw_parts_mut`].
     #[unstable(feature = "ptr_metadata", issue = "81513")]
@@ -250,7 +250,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
     /// be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z`
@@ -419,7 +419,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`guaranteed_ne`]: #method.guaranteed_ne
     ///
-    /// The return value may change depending on the compiler version and unsafe code may not
+    /// The return value may change depending on the compiler version and unsafe code might not
     /// rely on the result of this function for soundness. It is suggested to only use this function
     /// for performance optimizations where spurious `false` return values by this function do not
     /// affect the outcome, but just the performance.
@@ -450,7 +450,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`guaranteed_eq`]: #method.guaranteed_eq
     ///
-    /// The return value may change depending on the compiler version and unsafe code may not
+    /// The return value may change depending on the compiler version and unsafe code might not
     /// rely on the result of this function for soundness. It is suggested to only use this function
     /// for performance optimizations where spurious `false` return values by this function do not
     /// affect the outcome, but just the performance.
@@ -596,6 +596,7 @@ impl<T: ?Sized> *mut T {
     /// enables more aggressive compiler optimizations.
     ///
     /// [`wrapping_add`]: #method.wrapping_add
+    /// [allocated object]: crate::ptr#allocated-object
     ///
     /// # Examples
     ///
@@ -696,7 +697,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
     /// be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z`
@@ -758,7 +759,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it may not
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
     /// be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z`
@@ -1002,7 +1003,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::write`]: crate::ptr::write()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
+    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     #[inline(always)]
     pub const unsafe fn write(self, val: T)
     where
@@ -1057,7 +1058,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
+    #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     #[inline(always)]
     pub const unsafe fn write_unaligned(self, val: T)
     where
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 1c65518af04..87c8674af0d 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -71,6 +71,16 @@ impl<T: Sized> NonNull<T> {
     /// a `T`, which means this must not be used as a "not yet initialized"
     /// sentinel value. Types that lazily allocate must track initialization by
     /// some other means.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let ptr = NonNull::<u32>::dangling();
+    /// // Important: don't try to access the value of `ptr` without
+    /// // initializing it first! The pointer is not null but isn't valid either!
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.36.0")]
     #[inline]
@@ -155,6 +165,24 @@ impl<T: ?Sized> NonNull<T> {
     /// # Safety
     ///
     /// `ptr` must be non-null.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = unsafe { NonNull::new_unchecked(&mut x as *mut _) };
+    /// ```
+    ///
+    /// *Incorrect* usage of this function:
+    ///
+    /// ```rust,no_run
+    /// use std::ptr::NonNull;
+    ///
+    /// // NEVER DO THAT!!! This is undefined behavior. ⚠️
+    /// let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) };
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.25.0")]
     #[inline]
@@ -164,6 +192,19 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::<u32>::new(&mut x as *mut _).expect("ptr is null!");
+    ///
+    /// if let Some(ptr) = NonNull::<u32>::new(std::ptr::null_mut()) {
+    ///     unreachable!();
+    /// }
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
@@ -194,7 +235,7 @@ impl<T: ?Sized> NonNull<T> {
         }
     }
 
-    /// Decompose a (possibly wide) pointer into is address and metadata components.
+    /// Decompose a (possibly wide) pointer into its address and metadata components.
     ///
     /// The pointer can be later reconstructed with [`NonNull::from_raw_parts`].
     #[unstable(feature = "ptr_metadata", issue = "81513")]
@@ -205,6 +246,22 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Acquires the underlying `*mut` pointer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x).expect("ptr is null!");
+    ///
+    /// let x_value = unsafe { *ptr.as_ptr() };
+    /// assert_eq!(x_value, 0);
+    ///
+    /// unsafe { *ptr.as_ptr() += 2; }
+    /// let x_value = unsafe { *ptr.as_ptr() };
+    /// assert_eq!(x_value, 2);
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")]
     #[inline]
@@ -239,6 +296,18 @@ impl<T: ?Sized> NonNull<T> {
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
     ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x as *mut _).expect("ptr is null!");
+    ///
+    /// let ref_x = unsafe { ptr.as_ref() };
+    /// println!("{}", ref_x);
+    /// ```
+    ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
@@ -274,6 +343,19 @@ impl<T: ?Sized> NonNull<T> {
     /// This applies even if the result of this method is unused!
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let mut ptr = NonNull::new(&mut x).expect("null pointer");
+    ///
+    /// let x_ref = unsafe { ptr.as_mut() };
+    /// assert_eq!(*x_ref, 0);
+    /// *x_ref += 2;
+    /// assert_eq!(*x_ref, 2);
+    /// ```
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
@@ -285,6 +367,18 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Casts to a pointer of another type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x as *mut _).expect("null pointer");
+    ///
+    /// let casted_ptr = ptr.cast::<i8>();
+    /// let raw_ptr: *mut i8 = casted_ptr.as_ptr();
+    /// ```
     #[stable(feature = "nonnull_cast", since = "1.27.0")]
     #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.36.0")]
     #[inline]
diff --git a/library/core/src/raw.rs b/library/core/src/raw.rs
deleted file mode 100644
index 6d1e28f4cd7..00000000000
--- a/library/core/src/raw.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-#![allow(missing_docs)]
-#![unstable(feature = "raw", issue = "27751")]
-#![rustc_deprecated(
-    since = "1.53.0",
-    reason = "use pointer metadata APIs instead https://github.com/rust-lang/rust/issues/81513"
-)]
-
-//! Contains struct definitions for the layout of compiler built-in types.
-//!
-//! They can be used as targets of transmutes in unsafe code for manipulating
-//! the raw representations directly.
-//!
-//! Their definition should always match the ABI defined in
-//! `rustc_middle::ty::layout`.
-
-/// The representation of a trait object like `&dyn SomeTrait`.
-///
-/// This struct has the same layout as types like `&dyn SomeTrait` and
-/// `Box<dyn AnotherTrait>`.
-///
-/// `TraitObject` is guaranteed to match layouts, but it is not the
-/// type of trait objects (e.g., the fields are not directly accessible
-/// on a `&dyn SomeTrait`) nor does it control that layout (changing the
-/// definition will not change the layout of a `&dyn SomeTrait`). It is
-/// only designed to be used by unsafe code that needs to manipulate
-/// the low-level details.
-///
-/// There is no way to refer to all trait objects generically, so the only
-/// way to create values of this type is with functions like
-/// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true
-/// trait object from a `TraitObject` value is with `transmute`.
-///
-/// [transmute]: crate::intrinsics::transmute
-///
-/// Synthesizing a trait object with mismatched types—one where the
-/// vtable does not correspond to the type of the value to which the
-/// data pointer points—is highly likely to lead to undefined
-/// behavior.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(raw)]
-///
-/// use std::{mem, raw};
-///
-/// // an example trait
-/// trait Foo {
-///     fn bar(&self) -> i32;
-/// }
-///
-/// impl Foo for i32 {
-///     fn bar(&self) -> i32 {
-///          *self + 1
-///     }
-/// }
-///
-/// let value: i32 = 123;
-///
-/// // let the compiler make a trait object
-/// let object: &dyn Foo = &value;
-///
-/// // look at the raw representation
-/// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) };
-///
-/// // the data pointer is the address of `value`
-/// assert_eq!(raw_object.data as *const i32, &value as *const _);
-///
-/// let other_value: i32 = 456;
-///
-/// // construct a new object, pointing to a different `i32`, being
-/// // careful to use the `i32` vtable from `object`
-/// let synthesized: &dyn Foo = unsafe {
-///      mem::transmute(raw::TraitObject {
-///          data: &other_value as *const _ as *mut (),
-///          vtable: raw_object.vtable,
-///      })
-/// };
-///
-/// // it should work just as if we had constructed a trait object out of
-/// // `other_value` directly
-/// assert_eq!(synthesized.bar(), 457);
-/// ```
-#[repr(C)]
-#[derive(Copy, Clone)]
-#[allow(missing_debug_implementations)]
-pub struct TraitObject {
-    pub data: *mut (),
-    pub vtable: *mut (),
-}
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index babd0a0b552..861790e8a40 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -224,6 +224,268 @@
 //! [`Ok(T)`]: Ok
 //! [`Err(E)`]: Err
 //! [`io::Error`]: ../../std/io/struct.Error.html
+//!
+//! # Method overview
+//!
+//! In addition to working with pattern matching, [`Result`] provides a
+//! wide variety of different methods.
+//!
+//! ## Querying the variant
+//!
+//! The [`is_ok`] and [`is_err`] methods return [`true`] if the [`Result`]
+//! is [`Ok`] or [`Err`], respectively.
+//!
+//! [`is_err`]: Result::is_err
+//! [`is_ok`]: Result::is_ok
+//!
+//! ## Adapters for working with references
+//!
+//! * [`as_ref`] converts from `&Result<T, E>` to `Result<&T, &E>`
+//! * [`as_mut`] converts from `&mut Result<T, E>` to `Result<&mut T, &mut E>`
+//! * [`as_deref`] converts from `&Result<T, E>` to `Result<&T::Target, &E>`
+//! * [`as_deref_mut`] converts from `&mut Result<T, E>` to
+//!   `Result<&mut T::Target, &mut E>`
+//!
+//! [`as_deref`]: Result::as_deref
+//! [`as_deref_mut`]: Result::as_deref_mut
+//! [`as_mut`]: Result::as_mut
+//! [`as_ref`]: Result::as_ref
+//!
+//! ## Extracting contained values
+//!
+//! These methods extract the contained value in a [`Result<T, E>`] when it
+//! is the [`Ok`] variant. If the [`Result`] is [`Err`]:
+//!
+//! * [`expect`] panics with a provided custom message
+//! * [`unwrap`] panics with a generic message
+//! * [`unwrap_or`] returns the provided default value
+//! * [`unwrap_or_default`] returns the default value of the type `T`
+//!   (which must implement the [`Default`] trait)
+//! * [`unwrap_or_else`] returns the result of evaluating the provided
+//!   function
+//!
+//! The panicking methods [`expect`] and [`unwrap`] require `E` to
+//! implement the [`Debug`] trait.
+//!
+//! [`Debug`]: crate::fmt::Debug
+//! [`expect`]: Result::expect
+//! [`unwrap`]: Result::unwrap
+//! [`unwrap_or`]: Result::unwrap_or
+//! [`unwrap_or_default`]: Result::unwrap_or_default
+//! [`unwrap_or_else`]: Result::unwrap_or_else
+//!
+//! These methods extract the contained value in a [`Result<T, E>`] when it
+//! is the [`Err`] variant. They require `T` to implement the [`Debug`]
+//! trait. If the [`Result`] is [`Ok`]:
+//!
+//! * [`expect_err`] panics with a provided custom message
+//! * [`unwrap_err`] panics with a generic message
+//!
+//! [`Debug`]: crate::fmt::Debug
+//! [`expect_err`]: Result::expect_err
+//! [`unwrap_err`]: Result::unwrap_err
+//!
+//! ## Transforming contained values
+//!
+//! These methods transform [`Result`] to [`Option`]:
+//!
+//! * [`err`][Result::err] transforms [`Result<T, E>`] into [`Option<E>`],
+//!   mapping [`Err(e)`] to [`Some(e)`] and [`Ok(v)`] to [`None`]
+//! * [`ok`][Result::ok] transforms [`Result<T, E>`] into [`Option<T>`],
+//!   mapping [`Ok(v)`] to [`Some(v)`] and [`Err(e)`] to [`None`]
+//! * [`transpose`] transposes a [`Result`] of an [`Option`] into an
+//!   [`Option`] of a [`Result`]
+//!
+// Do NOT add link reference definitions for `err` or `ok`, because they
+// will generate numerous incorrect URLs for `Err` and `Ok` elsewhere, due
+// to case folding.
+//!
+//! [`Err(e)`]: Err
+//! [`Ok(v)`]: Ok
+//! [`Some(e)`]: Option::Some
+//! [`Some(v)`]: Option::Some
+//! [`transpose`]: Result::transpose
+//!
+//! This method transforms the contained value of the [`Ok`] variant:
+//!
+//! * [`map`] transforms [`Result<T, E>`] into [`Result<U, E>`] by applying
+//!   the provided function to the contained value of [`Ok`] and leaving
+//!   [`Err`] values unchanged
+//!
+//! [`map`]: Result::map
+//!
+//! This method transforms the contained value of the [`Err`] variant:
+//!
+//! * [`map_err`] transforms [`Result<T, E>`] into [`Result<T, F>`] by
+//!   applying the provided function to the contained value of [`Err`] and
+//!   leaving [`Ok`] values unchanged
+//!
+//! [`map_err`]: Result::map_err
+//!
+//! These methods transform a [`Result<T, E>`] into a value of a possibly
+//! different type `U`:
+//!
+//! * [`map_or`] applies the provided function to the contained value of
+//!   [`Ok`], or returns the provided default value if the [`Result`] is
+//!   [`Err`]
+//! * [`map_or_else`] applies the provided function to the contained value
+//!   of [`Ok`], or applies the provided fallback function to the contained
+//!   value of [`Err`]
+//!
+//! [`map_or`]: Result::map_or
+//! [`map_or_else`]: Result::map_or_else
+//!
+//! ## Boolean operators
+//!
+//! These methods treat the [`Result`] as a boolean value, where [`Ok`]
+//! acts like [`true`] and [`Err`] acts like [`false`]. There are two
+//! categories of these methods: ones that take a [`Result`] as input, and
+//! ones that take a function as input (to be lazily evaluated).
+//!
+//! The [`and`] and [`or`] methods take another [`Result`] as input, and
+//! produce a [`Result`] as output. The [`and`] method can produce a
+//! [`Result<U, E>`] value having a different inner type `U` than
+//! [`Result<T, E>`]. The [`or`] method can produce a [`Result<T, F>`]
+//! value having a different error type `F` than [`Result<T, E>`].
+//!
+//! | method  | self     | input     | output   |
+//! |---------|----------|-----------|----------|
+//! | [`and`] | `Err(e)` | (ignored) | `Err(e)` |
+//! | [`and`] | `Ok(x)`  | `Err(d)`  | `Err(d)` |
+//! | [`and`] | `Ok(x)`  | `Ok(y)`   | `Ok(y)`  |
+//! | [`or`]  | `Err(e)` | `Err(d)`  | `Err(d)` |
+//! | [`or`]  | `Err(e)` | `Ok(y)`   | `Ok(y)`  |
+//! | [`or`]  | `Ok(x)`  | (ignored) | `Ok(x)`  |
+//!
+//! [`and`]: Result::and
+//! [`or`]: Result::or
+//!
+//! The [`and_then`] and [`or_else`] methods take a function as input, and
+//! only evaluate the function when they need to produce a new value. The
+//! [`and_then`] method can produce a [`Result<U, E>`] value having a
+//! different inner type `U` than [`Result<T, E>`]. The [`or_else`] method
+//! can produce a [`Result<T, F>`] value having a different error type `F`
+//! than [`Result<T, E>`].
+//!
+//! | method       | self     | function input | function result | output   |
+//! |--------------|----------|----------------|-----------------|----------|
+//! | [`and_then`] | `Err(e)` | (not provided) | (not evaluated) | `Err(e)` |
+//! | [`and_then`] | `Ok(x)`  | `x`            | `Err(d)`        | `Err(d)` |
+//! | [`and_then`] | `Ok(x)`  | `x`            | `Ok(y)`         | `Ok(y)`  |
+//! | [`or_else`]  | `Err(e)` | `e`            | `Err(d)`        | `Err(d)` |
+//! | [`or_else`]  | `Err(e)` | `e`            | `Ok(y)`         | `Ok(y)`  |
+//! | [`or_else`]  | `Ok(x)`  | (not provided) | (not evaluated) | `Ok(x)`  |
+//!
+//! [`and_then`]: Result::and_then
+//! [`or_else`]: Result::or_else
+//!
+//! ## Comparison operators
+//!
+//! If `T` and `E` both implement [`PartialOrd`] then [`Result<T, E>`] will
+//! derive its [`PartialOrd`] implementation.  With this order, an [`Ok`]
+//! compares as less than any [`Err`], while two [`Ok`] or two [`Err`]
+//! compare as their contained values would in `T` or `E` respectively.  If `T`
+//! and `E` both also implement [`Ord`], then so does [`Result<T, E>`].
+//!
+//! ```
+//! assert!(Ok(1) < Err(0));
+//! let x: Result<i32, ()> = Ok(0);
+//! let y = Ok(1);
+//! assert!(x < y);
+//! let x: Result<(), i32> = Err(0);
+//! let y = Err(1);
+//! assert!(x < y);
+//! ```
+//!
+//! ## Iterating over `Result`
+//!
+//! A [`Result`] can be iterated over. This can be helpful if you need an
+//! iterator that is conditionally empty. The iterator will either produce
+//! a single value (when the [`Result`] is [`Ok`]), or produce no values
+//! (when the [`Result`] is [`Err`]). For example, [`into_iter`] acts like
+//! [`once(v)`] if the [`Result`] is [`Ok(v)`], and like [`empty()`] if the
+//! [`Result`] is [`Err`].
+//!
+//! [`Ok(v)`]: Ok
+//! [`empty()`]: crate::iter::empty
+//! [`once(v)`]: crate::iter::once
+//!
+//! Iterators over [`Result<T, E>`] come in three types:
+//!
+//! * [`into_iter`] consumes the [`Result`] and produces the contained
+//!   value
+//! * [`iter`] produces an immutable reference of type `&T` to the
+//!   contained value
+//! * [`iter_mut`] produces a mutable reference of type `&mut T` to the
+//!   contained value
+//!
+//! See [Iterating over `Option`] for examples of how this can be useful.
+//!
+//! [Iterating over `Option`]: crate::option#iterating-over-option
+//! [`into_iter`]: Result::into_iter
+//! [`iter`]: Result::iter
+//! [`iter_mut`]: Result::iter_mut
+//!
+//! You might want to use an iterator chain to do multiple instances of an
+//! operation that can fail, but would like to ignore failures while
+//! continuing to process the successful results. In this example, we take
+//! advantage of the iterable nature of [`Result`] to select only the
+//! [`Ok`] values using [`flatten`][Iterator::flatten].
+//!
+//! ```
+//! # use std::str::FromStr;
+//! let mut results = vec![];
+//! let mut errs = vec![];
+//! let nums: Vec<_> = vec!["17", "not a number", "99", "-27", "768"]
+//!    .into_iter()
+//!    .map(u8::from_str)
+//!    // Save clones of the raw `Result` values to inspect
+//!    .inspect(|x| results.push(x.clone()))
+//!    // Challenge: explain how this captures only the `Err` values
+//!    .inspect(|x| errs.extend(x.clone().err()))
+//!    .flatten()
+//!    .collect();
+//! assert_eq!(errs.len(), 3);
+//! assert_eq!(nums, [17, 99]);
+//! println!("results {:?}", results);
+//! println!("errs {:?}", errs);
+//! println!("nums {:?}", nums);
+//! ```
+//!
+//! ## Collecting into `Result`
+//!
+//! [`Result`] implements the [`FromIterator`][impl-FromIterator] trait,
+//! which allows an iterator over [`Result`] values to be collected into a
+//! [`Result`] of a collection of each contained value of the original
+//! [`Result`] values, or [`Err`] if any of the elements was [`Err`].
+//!
+//! [impl-FromIterator]: Result#impl-FromIterator%3CResult%3CA%2C%20E%3E%3E
+//!
+//! ```
+//! let v = vec![Ok(2), Ok(4), Err("err!"), Ok(8)];
+//! let res: Result<Vec<_>, &str> = v.into_iter().collect();
+//! assert_eq!(res, Err("err!"));
+//! let v = vec![Ok(2), Ok(4), Ok(8)];
+//! let res: Result<Vec<_>, &str> = v.into_iter().collect();
+//! assert_eq!(res, Ok(vec![2, 4, 8]));
+//! ```
+//!
+//! [`Result`] also implements the [`Product`][impl-Product] and
+//! [`Sum`][impl-Sum] traits, allowing an iterator over [`Result`] values
+//! to provide the [`product`][Iterator::product] and
+//! [`sum`][Iterator::sum] methods.
+//!
+//! [impl-Product]: Result#impl-Product%3CResult%3CU%2C%20E%3E%3E
+//! [impl-Sum]: Result#impl-Sum%3CResult%3CU%2C%20E%3E%3E
+//!
+//! ```
+//! let v = vec![Err("error!"), Ok(1), Ok(2), Ok(3), Err("foo")];
+//! let res: Result<i32, &str> = v.into_iter().sum();
+//! assert_eq!(res, Err("error!"));
+//! let v: Vec<Result<i32, &str>> = vec![Ok(1), Ok(2), Ok(21)];
+//! let res: Result<i32, &str> = v.into_iter().product();
+//! assert_eq!(res, Ok(42));
+//! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -1626,28 +1888,6 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     }
 }
 
-#[unstable(feature = "try_trait", issue = "42327")]
-#[cfg(bootstrap)]
-impl<T, E> ops::TryV1 for Result<T, E> {
-    type Output = T;
-    type Error = E;
-
-    #[inline]
-    fn into_result(self) -> Self {
-        self
-    }
-
-    #[inline]
-    fn from_ok(v: T) -> Self {
-        Ok(v)
-    }
-
-    #[inline]
-    fn from_error(v: E) -> Self {
-        Err(v)
-    }
-}
-
 #[unstable(feature = "try_trait_v2", issue = "84277")]
 impl<T, E> ops::TryV2 for Result<T, E> {
     type Output = T;
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 1ee662c6c8e..c0dfba490ec 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-filelength
 //! Definitions of a bunch of iterators for `[T]`.
 
 #[macro_use] // import iterator! and forward_iterator!
@@ -8,7 +7,7 @@ use crate::cmp;
 use crate::cmp::Ordering;
 use crate::fmt;
 use crate::intrinsics::{assume, exact_div, unchecked_sub};
-use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
+use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use crate::marker::{PhantomData, Send, Sized, Sync};
 use crate::mem;
 use crate::num::NonZeroUsize;
@@ -401,7 +400,13 @@ where
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) }
+        if self.finished {
+            (0, Some(0))
+        } else {
+            // If the predicate doesn't match anything, we yield one slice.
+            // If it matches every element, we yield `len() + 1` empty slices.
+            (1, Some(self.v.len() + 1))
+        }
     }
 }
 
@@ -526,7 +531,14 @@ where
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) }
+        if self.finished {
+            (0, Some(0))
+        } else {
+            // If the predicate doesn't match anything, we yield one slice.
+            // If it matches every element, we yield `len()` one-element slices,
+            // or a single empty slice.
+            (1, Some(cmp::max(1, self.v.len())))
+        }
     }
 }
 
@@ -648,8 +660,8 @@ where
         if self.finished {
             (0, Some(0))
         } else {
-            // if the predicate doesn't match anything, we yield one slice
-            // if it matches every element, we yield len+1 empty slices.
+            // If the predicate doesn't match anything, we yield one slice.
+            // If it matches every element, we yield `len() + 1` empty slices.
             (1, Some(self.v.len() + 1))
         }
     }
@@ -764,9 +776,10 @@ where
         if self.finished {
             (0, Some(0))
         } else {
-            // if the predicate doesn't match anything, we yield one slice
-            // if it matches every element, we yield len+1 empty slices.
-            (1, Some(self.v.len() + 1))
+            // If the predicate doesn't match anything, we yield one slice.
+            // If it matches every element, we yield `len()` one-element slices,
+            // or a single empty slice.
+            (1, Some(cmp::max(1, self.v.len())))
         }
     }
 }
@@ -1009,7 +1022,10 @@ impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         let (lower, upper_opt) = self.iter.size_hint();
-        (lower, upper_opt.map(|upper| cmp::min(self.count, upper)))
+        (
+            cmp::min(self.count, lower),
+            Some(upper_opt.map_or(self.count, |upper| cmp::min(self.count, upper))),
+        )
     }
 }
 
@@ -1312,7 +1328,11 @@ impl<T> FusedIterator for Windows<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Windows<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -1418,18 +1438,17 @@ impl<'a, T> Iterator for Chunks<'a, T> {
     #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
         let start = idx * self.chunk_size;
-        let end = match start.checked_add(self.chunk_size) {
-            None => self.v.len(),
-            Some(end) => cmp::min(end, self.v.len()),
-        };
         // SAFETY: the caller guarantees that `i` is in bounds,
         // which means that `start` must be in bounds of the
-        // underlying `self.v` slice, and we made sure that `end`
+        // underlying `self.v` slice, and we made sure that `len`
         // is also in bounds of `self.v`. Thus, `start` cannot overflow
         // an `isize`, and the slice constructed by `from_raw_parts`
         // is a subslice of `self.v` which is guaranteed to be valid
         // for the lifetime `'a` of `self.v`.
-        unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
+        unsafe {
+            let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
+            from_raw_parts(self.v.as_ptr().add(start), len)
+        }
     }
 }
 
@@ -1457,7 +1476,7 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
         } else {
             let start = (len - 1 - n) * self.chunk_size;
             let end = match start.checked_add(self.chunk_size) {
-                Some(res) => cmp::min(res, self.v.len()),
+                Some(res) => cmp::min(self.v.len(), res),
                 None => self.v.len(),
             };
             let nth_back = &self.v[start..end];
@@ -1478,7 +1497,11 @@ impl<T> FusedIterator for Chunks<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -1579,17 +1602,16 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
     #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
         let start = idx * self.chunk_size;
-        let end = match start.checked_add(self.chunk_size) {
-            None => self.v.len(),
-            Some(end) => cmp::min(end, self.v.len()),
-        };
         // SAFETY: see comments for `Chunks::__iterator_get_unchecked`.
         //
         // Also note that the caller also guarantees that we're never called
         // with the same index again, and that no other methods that will
         // access this subslice are called, so it is valid for the returned
         // slice to be mutable.
-        unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
+        unsafe {
+            let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
+            from_raw_parts_mut(self.v.as_mut_ptr().add(start), len)
+        }
     }
 }
 
@@ -1619,7 +1641,7 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
         } else {
             let start = (len - 1 - n) * self.chunk_size;
             let end = match start.checked_add(self.chunk_size) {
-                Some(res) => cmp::min(res, self.v.len()),
+                Some(res) => cmp::min(self.v.len(), res),
                 None => self.v.len(),
             };
             let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
@@ -1641,7 +1663,11 @@ impl<T> FusedIterator for ChunksMut<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksMut<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -1795,7 +1821,11 @@ impl<T> FusedIterator for ChunksExact<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -1946,7 +1976,11 @@ impl<T> FusedIterator for ChunksExactMut<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExactMut<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -2148,6 +2182,7 @@ impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> {
         self.iter.last()
     }
 
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a [T; N] {
         // SAFETY: The safety guarantees of `__iterator_get_unchecked` are
         // transferred to the caller.
@@ -2183,7 +2218,11 @@ impl<T, const N: usize> FusedIterator for ArrayChunks<'_, T, N> {}
 
 #[doc(hidden)]
 #[unstable(feature = "array_chunks", issue = "74985")]
-unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N> {
+unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N> {}
+
+#[doc(hidden)]
+#[unstable(feature = "array_chunks", issue = "74985")]
+unsafe impl<'a, T, const N: usize> TrustedRandomAccessNoCoerce for ArrayChunks<'a, T, N> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -2260,6 +2299,7 @@ impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> {
         self.iter.last()
     }
 
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a mut [T; N] {
         // SAFETY: The safety guarantees of `__iterator_get_unchecked` are transferred to
         // the caller.
@@ -2295,7 +2335,11 @@ impl<T, const N: usize> FusedIterator for ArrayChunksMut<'_, T, N> {}
 
 #[doc(hidden)]
 #[unstable(feature = "array_chunks", issue = "74985")]
-unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T, N> {
+unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T, N> {}
+
+#[doc(hidden)]
+#[unstable(feature = "array_chunks", issue = "74985")]
+unsafe impl<'a, T, const N: usize> TrustedRandomAccessNoCoerce for ArrayChunksMut<'a, T, N> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -2457,7 +2501,11 @@ impl<T> FusedIterator for RChunks<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -2618,7 +2666,11 @@ impl<T> FusedIterator for RChunksMut<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksMut<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -2776,7 +2828,11 @@ impl<T> FusedIterator for RChunksExact<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
@@ -2931,19 +2987,31 @@ impl<T> FusedIterator for RChunksExactMut<'_, T> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExactMut<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Iter<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
+unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index 457b2a3605e..cf15756868e 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -186,6 +186,14 @@ macro_rules! iterator {
             }
 
             #[inline]
+            fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+                let advance = cmp::min(len!(self), n);
+                // SAFETY: By construction, `advance` does not exceed `self.len()`.
+                unsafe { self.post_inc_start(advance as isize) };
+                if advance == n { Ok(()) } else { Err(advance) }
+            }
+
+            #[inline]
             fn last(mut self) -> Option<$elem> {
                 self.next_back()
             }
@@ -371,6 +379,14 @@ macro_rules! iterator {
                     Some(next_back_unchecked!(self))
                 }
             }
+
+            #[inline]
+            fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+                let advance = cmp::min(len!(self), n);
+                // SAFETY: By construction, `advance` does not exceed `self.len()`.
+                unsafe { self.pre_dec_end(advance as isize) };
+                if advance == n { Ok(()) } else { Err(advance) }
+            }
         }
 
         #[stable(feature = "fused", since = "1.26.0")]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 3bcea4e6d25..361a9b03aeb 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! Slice management and manipulation.
 //!
 //! For more details see [`std::slice`].
@@ -95,12 +93,12 @@ impl<T> [T] {
     /// let a = [1, 2, 3];
     /// assert_eq!(a.len(), 3);
     /// ```
-    #[doc(alias = "length")]
+    #[lang = "slice_len_fn"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")]
     #[inline]
     // SAFETY: const sound because we transmute out the length field as a usize (which it must be)
-    #[rustc_allow_const_fn_unstable(const_fn_union)]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_union))]
     pub const fn len(&self) -> usize {
         // FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable.
         // As of this writing this causes a "Const-stable functions can only call other
@@ -139,7 +137,7 @@ impl<T> [T] {
     /// assert_eq!(None, w.first());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
+    #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
     #[inline]
     pub const fn first(&self) -> Option<&T> {
         if let [first, ..] = self { Some(first) } else { None }
@@ -177,7 +175,7 @@ impl<T> [T] {
     /// }
     /// ```
     #[stable(feature = "slice_splits", since = "1.5.0")]
-    #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
+    #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
     #[inline]
     pub const fn split_first(&self) -> Option<(&T, &[T])> {
         if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
@@ -217,7 +215,7 @@ impl<T> [T] {
     /// }
     /// ```
     #[stable(feature = "slice_splits", since = "1.5.0")]
-    #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
+    #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
     #[inline]
     pub const fn split_last(&self) -> Option<(&T, &[T])> {
         if let [init @ .., last] = self { Some((last, init)) } else { None }
@@ -256,7 +254,7 @@ impl<T> [T] {
     /// assert_eq!(None, w.last());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
+    #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
     #[inline]
     pub const fn last(&self) -> Option<&T> {
         if let [.., last] = self { Some(last) } else { None }
@@ -2100,9 +2098,11 @@ impl<T> [T] {
     ///
     /// If the value is found then [`Result::Ok`] is returned, containing the
     /// index of the matching element. If there are multiple matches, then any
-    /// one of the matches could be returned. If the value is not found then
-    /// [`Result::Err`] is returned, containing the index where a matching
-    /// element could be inserted while maintaining sorted order.
+    /// one of the matches could be returned. The index is chosen
+    /// deterministically, but is subject to change in future versions of Rust.
+    /// If the value is not found then [`Result::Err`] is returned, containing
+    /// the index where a matching element could be inserted while maintaining
+    /// sorted order.
     ///
     /// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`].
     ///
@@ -2153,9 +2153,11 @@ impl<T> [T] {
     ///
     /// If the value is found then [`Result::Ok`] is returned, containing the
     /// index of the matching element. If there are multiple matches, then any
-    /// one of the matches could be returned. If the value is not found then
-    /// [`Result::Err`] is returned, containing the index where a matching
-    /// element could be inserted while maintaining sorted order.
+    /// one of the matches could be returned. The index is chosen
+    /// deterministically, but is subject to change in future versions of Rust.
+    /// If the value is not found then [`Result::Err`] is returned, containing
+    /// the index where a matching element could be inserted while maintaining
+    /// sorted order.
     ///
     /// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`].
     ///
@@ -2224,9 +2226,11 @@ impl<T> [T] {
     ///
     /// If the value is found then [`Result::Ok`] is returned, containing the
     /// index of the matching element. If there are multiple matches, then any
-    /// one of the matches could be returned. If the value is not found then
-    /// [`Result::Err`] is returned, containing the index where a matching
-    /// element could be inserted while maintaining sorted order.
+    /// one of the matches could be returned. The index is chosen
+    /// deterministically, but is subject to change in future versions of Rust.
+    /// If the value is not found then [`Result::Err`] is returned, containing
+    /// the index where a matching element could be inserted while maintaining
+    /// sorted order.
     ///
     /// See also [`binary_search`], [`binary_search_by`], and [`partition_point`].
     ///
@@ -2268,7 +2272,7 @@ impl<T> [T] {
         self.binary_search_by(|k| f(k).cmp(b))
     }
 
-    /// Sorts the slice, but may not preserve the order of equal elements.
+    /// Sorts the slice, but might not preserve the order of equal elements.
     ///
     /// This sort is unstable (i.e., may reorder equal elements), in-place
     /// (i.e., does not allocate), and *O*(*n* \* log(*n*)) worst-case.
@@ -2303,7 +2307,7 @@ impl<T> [T] {
         sort::quicksort(self, |a, b| a.lt(b));
     }
 
-    /// Sorts the slice with a comparator function, but may not preserve the order of equal
+    /// Sorts the slice with a comparator function, but might not preserve the order of equal
     /// elements.
     ///
     /// This sort is unstable (i.e., may reorder equal elements), in-place
@@ -2358,7 +2362,7 @@ impl<T> [T] {
         sort::quicksort(self, |a, b| compare(a, b) == Ordering::Less);
     }
 
-    /// Sorts the slice with a key extraction function, but may not preserve the order of equal
+    /// Sorts the slice with a key extraction function, but might not preserve the order of equal
     /// elements.
     ///
     /// This sort is unstable (i.e., may reorder equal elements), in-place
@@ -3462,27 +3466,7 @@ impl<T> [T] {
     where
         P: FnMut(&T) -> bool,
     {
-        let mut left = 0;
-        let mut right = self.len();
-
-        while left != right {
-            let mid = left + (right - left) / 2;
-            // SAFETY: When `left < right`, `left <= mid < right`.
-            // Therefore `left` always increases and `right` always decreases,
-            // and either of them is selected. In both cases `left <= right` is
-            // satisfied. Therefore if `left < right` in a step, `left <= right`
-            // is satisfied in the next step. Therefore as long as `left != right`,
-            // `0 <= left < right <= len` is satisfied and if this case
-            // `0 <= mid < len` is satisfied too.
-            let value = unsafe { self.get_unchecked(mid) };
-            if pred(value) {
-                left = mid + 1;
-            } else {
-                right = mid;
-            }
-        }
-
-        left
+        self.binary_search_by(|x| if pred(x) { Less } else { Greater }).unwrap_or_else(|i| i)
     }
 }
 
@@ -3517,7 +3501,8 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for &[T] {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> const Default for &[T] {
     /// Creates an empty slice.
     fn default() -> Self {
         &[]
@@ -3525,7 +3510,8 @@ impl<T> Default for &[T] {
 }
 
 #[stable(feature = "mut_slice_default", since = "1.5.0")]
-impl<T> Default for &mut [T] {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> const Default for &mut [T] {
     /// Creates a mutable empty slice.
     fn default() -> Self {
         &mut []
diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs
index a89596b15ef..7528927ef33 100644
--- a/library/core/src/slice/rotate.rs
+++ b/library/core/src/slice/rotate.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-undocumented-unsafe
-
 use crate::cmp;
 use crate::mem::{self, MaybeUninit};
 use crate::ptr;
@@ -79,8 +77,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // the way until about `left + right == 32`, but the worst case performance breaks even
             // around 16. 24 was chosen as middle ground. If the size of `T` is larger than 4
             // `usize`s, this algorithm also outperforms other algorithms.
+            // SAFETY: callers must ensure `mid - left` is valid for reading and writing.
             let x = unsafe { mid.sub(left) };
             // beginning of first round
+            // SAFETY: see previous comment.
             let mut tmp: T = unsafe { x.read() };
             let mut i = right;
             // `gcd` can be found before hand by calculating `gcd(left + right, right)`,
@@ -92,6 +92,21 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // the very end. This is possibly due to the fact that swapping or replacing temporaries
             // uses only one memory address in the loop instead of needing to manage two.
             loop {
+                // [long-safety-expl]
+                // SAFETY: callers must ensure `[left, left+mid+right)` are all valid for reading and
+                // writing.
+                //
+                // - `i` start with `right` so `mid-left <= x+i = x+right = mid-left+right < mid+right`
+                // - `i <= left+right-1` is always true
+                //   - if `i < left`, `right` is added so `i < left+right` and on the next
+                //     iteration `left` is removed from `i` so it doesn't go further
+                //   - if `i >= left`, `left` is removed immediately and so it doesn't go further.
+                // - overflows cannot happen for `i` since the function's safety contract ask for
+                //   `mid+right-1 = x+left+right` to be valid for writing
+                // - underflows cannot happen because `i` must be bigger or equal to `left` for
+                //   a substraction of `left` to happen.
+                //
+                // So `x+i` is valid for reading and writing if the caller respected the contract
                 tmp = unsafe { x.add(i).replace(tmp) };
                 // instead of incrementing `i` and then checking if it is outside the bounds, we
                 // check if `i` will go outside the bounds on the next increment. This prevents
@@ -100,6 +115,8 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
                     i -= left;
                     if i == 0 {
                         // end of first round
+                        // SAFETY: tmp has been read from a valid source and x is valid for writing
+                        // according to the caller.
                         unsafe { x.write(tmp) };
                         break;
                     }
@@ -113,13 +130,24 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             }
             // finish the chunk with more rounds
             for start in 1..gcd {
+                // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for
+                // reading and writing as per the function's safety contract, see [long-safety-expl]
+                // above
                 tmp = unsafe { x.add(start).read() };
+                // [safety-expl-addition]
+                //
+                // Here `start < gcd` so `start < right` so `i < right+right`: `right` being the
+                // greatest common divisor of `(left+right, right)` means that `left = right` so
+                // `i < left+right` so `x+i = mid-left+i` is always valid for reading and writing
+                // according to the function's safety contract.
                 i = start + right;
                 loop {
+                    // SAFETY: see [long-safety-expl] and [safety-expl-addition]
                     tmp = unsafe { x.add(i).replace(tmp) };
                     if i >= left {
                         i -= left;
                         if i == start {
+                            // SAFETY: see [long-safety-expl] and [safety-expl-addition]
                             unsafe { x.add(start).write(tmp) };
                             break;
                         }
@@ -135,14 +163,30 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // The `[T; 0]` here is to ensure this is appropriately aligned for T
             let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit();
             let buf = rawarray.as_mut_ptr() as *mut T;
+            // SAFETY: `mid-left <= mid-left+right < mid+right`
             let dim = unsafe { mid.sub(left).add(right) };
             if left <= right {
+                // SAFETY:
+                //
+                // 1) The `else if` condition about the sizes ensures `[mid-left; left]` will fit in
+                //    `buf` without overflow and `buf` was created just above and so cannot be
+                //    overlapped with any value of `[mid-left; left]`
+                // 2) [mid-left, mid+right) are all valid for reading and writing and we don't care
+                //    about overlaps here.
+                // 3) The `if` condition about `left <= right` ensures writing `left` elements to
+                //    `dim = mid-left+right` is valid because:
+                //    - `buf` is valid and `left` elements were written in it in 1)
+                //    - `dim+left = mid-left+right+left = mid+right` and we write `[dim, dim+left)`
                 unsafe {
+                    // 1)
                     ptr::copy_nonoverlapping(mid.sub(left), buf, left);
+                    // 2)
                     ptr::copy(mid, mid.sub(left), right);
+                    // 3)
                     ptr::copy_nonoverlapping(buf, dim, left);
                 }
             } else {
+                // SAFETY: same reasoning as above but with `left` and `right` reversed
                 unsafe {
                     ptr::copy_nonoverlapping(mid, buf, right);
                     ptr::copy(mid.sub(left), dim, left);
@@ -156,6 +200,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
             // of this algorithm would be, and swapping using that last chunk instead of swapping
             // adjacent chunks like this algorithm is doing, but this way is still faster.
             loop {
+                // SAFETY:
+                // `left >= right` so `[mid-right, mid+right)` is valid for reading and writing
+                // Substracting `right` from `mid` each turn is counterbalanced by the addition and
+                // check after it.
                 unsafe {
                     ptr::swap_nonoverlapping(mid.sub(right), mid, right);
                     mid = mid.sub(right);
@@ -168,6 +216,10 @@ pub unsafe fn ptr_rotate<T>(mut left: usize, mut mid: *mut T, mut right: usize)
         } else {
             // Algorithm 3, `left < right`
             loop {
+                // SAFETY: `[mid-left, mid+left)` is valid for reading and writing because
+                // `left < right` so `mid+left < mid+right`.
+                // Adding `left` to `mid` each turn is counterbalanced by the substraction and check
+                // after it.
                 unsafe {
                     ptr::swap_nonoverlapping(mid.sub(left), mid, left);
                     mid = mid.add(left);
diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs
index 2a7693d27ef..36c2c4abdb4 100644
--- a/library/core/src/slice/sort.rs
+++ b/library/core/src/slice/sort.rs
@@ -227,7 +227,7 @@ where
 /// Partitioning is performed block-by-block in order to minimize the cost of branching operations.
 /// This idea is presented in the [BlockQuicksort][pdf] paper.
 ///
-/// [pdf]: http://drops.dagstuhl.de/opus/volltexte/2016/6389/pdf/LIPIcs-ESA-2016-38.pdf
+/// [pdf]: https://drops.dagstuhl.de/opus/volltexte/2016/6389/pdf/LIPIcs-ESA-2016-38.pdf
 fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize
 where
     F: FnMut(&T, &T) -> bool,
diff --git a/library/core/src/slice/specialize.rs b/library/core/src/slice/specialize.rs
index 425cf71626f..80eb590587f 100644
--- a/library/core/src/slice/specialize.rs
+++ b/library/core/src/slice/specialize.rs
@@ -1,6 +1,3 @@
-use crate::mem::{size_of, transmute_copy};
-use crate::ptr::write_bytes;
-
 pub(super) trait SpecFill<T> {
     fn spec_fill(&mut self, value: T);
 }
@@ -19,17 +16,8 @@ impl<T: Clone> SpecFill<T> for [T] {
 
 impl<T: Copy> SpecFill<T> for [T] {
     fn spec_fill(&mut self, value: T) {
-        if size_of::<T>() == 1 {
-            // SAFETY: The size_of check above ensures that values are 1 byte wide, as required
-            // for the transmute and write_bytes
-            unsafe {
-                let value: u8 = transmute_copy(&value);
-                write_bytes(self.as_mut_ptr(), value, self.len());
-            }
-        } else {
-            for item in self.iter_mut() {
-                *item = value;
-            }
+        for item in self.iter_mut() {
+            *item = value;
         }
     }
 }
diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs
index 05ff7bb120d..e67c0d6487c 100644
--- a/library/core/src/str/converts.rs
+++ b/library/core/src/str/converts.rs
@@ -156,8 +156,8 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "75196")]
-#[rustc_allow_const_fn_unstable(const_fn_transmute)]
+#[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
+#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
 pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
     // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
     // Also relies on `&str` and `&[u8]` having the same layout.
diff --git a/library/core/src/str/error.rs b/library/core/src/str/error.rs
index ccf7b20285c..aa735a14cbd 100644
--- a/library/core/src/str/error.rs
+++ b/library/core/src/str/error.rs
@@ -118,10 +118,9 @@ impl fmt::Display for Utf8Error {
 ///
 /// [`from_str`]: super::FromStr::from_str
 #[derive(Debug, Clone, PartialEq, Eq)]
+#[non_exhaustive]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct ParseBoolError {
-    pub(super) _priv: (),
-}
+pub struct ParseBoolError;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for ParseBoolError {
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index 6ec6b70b571..8db9edc6147 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -2,9 +2,9 @@
 
 use crate::char;
 use crate::fmt::{self, Write};
-use crate::iter::TrustedRandomAccess;
 use crate::iter::{Chain, FlatMap, Flatten};
 use crate::iter::{Copied, Filter, FusedIterator, Map, TrustedLen};
+use crate::iter::{TrustedRandomAccess, TrustedRandomAccessNoCoerce};
 use crate::ops::Try;
 use crate::option;
 use crate::slice::{self, Split as SliceSplit};
@@ -295,6 +295,7 @@ impl Iterator for Bytes<'_> {
     }
 
     #[inline]
+    #[doc(hidden)]
     unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
         // SAFETY: the caller must uphold the safety contract
         // for `Iterator::__iterator_get_unchecked`.
@@ -344,7 +345,11 @@ unsafe impl TrustedLen for Bytes<'_> {}
 
 #[doc(hidden)]
 #[unstable(feature = "trusted_random_access", issue = "none")]
-unsafe impl TrustedRandomAccess for Bytes<'_> {
+unsafe impl TrustedRandomAccess for Bytes<'_> {}
+
+#[doc(hidden)]
+#[unstable(feature = "trusted_random_access", issue = "none")]
+unsafe impl TrustedRandomAccessNoCoerce for Bytes<'_> {
     const MAY_HAVE_SIDE_EFFECT: bool = false;
 }
 
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 065acd3f38b..947afbdc68d 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -123,7 +123,7 @@ impl str {
     /// Returns the length of `self`.
     ///
     /// This length is in bytes, not [`char`]s or graphemes. In other words,
-    /// it may not be what a human considers the length of the string.
+    /// it might not be what a human considers the length of the string.
     ///
     /// [`char`]: prim@char
     ///
@@ -138,7 +138,6 @@ impl str {
     /// assert_eq!("ƒoo".len(), 4); // fancy f!
     /// assert_eq!("ƒoo".chars().count(), 3);
     /// ```
-    #[doc(alias = "length")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_str_len", since = "1.39.0")]
     #[inline]
@@ -232,7 +231,7 @@ impl str {
     #[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")]
     #[inline(always)]
     #[allow(unused_attributes)]
-    #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
     pub const fn as_bytes(&self) -> &[u8] {
         // SAFETY: const sound because we transmute two types with the same layout
         unsafe { mem::transmute(self) }
@@ -634,7 +633,7 @@ impl str {
     /// string slice by [`char`]. This method returns such an iterator.
     ///
     /// It's important to remember that [`char`] represents a Unicode Scalar
-    /// Value, and may not match your idea of what a 'character' is. Iteration
+    /// Value, and might not match your idea of what a 'character' is. Iteration
     /// over grapheme clusters may be what you actually want. This functionality
     /// is not provided by Rust's standard library, check crates.io instead.
     ///
@@ -661,7 +660,7 @@ impl str {
     /// assert_eq!(None, chars.next());
     /// ```
     ///
-    /// Remember, [`char`]s may not match your intuition about characters:
+    /// Remember, [`char`]s might not match your intuition about characters:
     ///
     /// [`char`]: prim@char
     ///
@@ -714,7 +713,7 @@ impl str {
     /// assert_eq!(None, char_indices.next());
     /// ```
     ///
-    /// Remember, [`char`]s may not match your intuition about characters:
+    /// Remember, [`char`]s might not match your intuition about characters:
     ///
     /// [`char`]: prim@char
     ///
@@ -2443,7 +2442,8 @@ impl AsRef<[u8]> for str {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for &str {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl const Default for &str {
     /// Creates an empty str
     #[inline]
     fn default() -> Self {
diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs
index 508c522e71a..55ac1aa765c 100644
--- a/library/core/src/str/pattern.rs
+++ b/library/core/src/str/pattern.rs
@@ -928,6 +928,8 @@ struct EmptyNeedle {
     end: usize,
     is_match_fw: bool,
     is_match_bw: bool,
+    // Needed in case of an empty haystack, see #85462
+    is_finished: bool,
 }
 
 impl<'a, 'b> StrSearcher<'a, 'b> {
@@ -941,6 +943,7 @@ impl<'a, 'b> StrSearcher<'a, 'b> {
                     end: haystack.len(),
                     is_match_fw: true,
                     is_match_bw: true,
+                    is_finished: false,
                 }),
             }
         } else {
@@ -966,13 +969,19 @@ unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> {
     fn next(&mut self) -> SearchStep {
         match self.searcher {
             StrSearcherImpl::Empty(ref mut searcher) => {
+                if searcher.is_finished {
+                    return SearchStep::Done;
+                }
                 // empty needle rejects every char and matches every empty string between them
                 let is_match = searcher.is_match_fw;
                 searcher.is_match_fw = !searcher.is_match_fw;
                 let pos = searcher.position;
                 match self.haystack[pos..].chars().next() {
                     _ if is_match => SearchStep::Match(pos, pos),
-                    None => SearchStep::Done,
+                    None => {
+                        searcher.is_finished = true;
+                        SearchStep::Done
+                    }
                     Some(ch) => {
                         searcher.position += ch.len_utf8();
                         SearchStep::Reject(pos, searcher.position)
@@ -1045,12 +1054,18 @@ unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> {
     fn next_back(&mut self) -> SearchStep {
         match self.searcher {
             StrSearcherImpl::Empty(ref mut searcher) => {
+                if searcher.is_finished {
+                    return SearchStep::Done;
+                }
                 let is_match = searcher.is_match_bw;
                 searcher.is_match_bw = !searcher.is_match_bw;
                 let end = searcher.end;
                 match self.haystack[..end].chars().next_back() {
                     _ if is_match => SearchStep::Match(end, end),
-                    None => SearchStep::Done,
+                    None => {
+                        searcher.is_finished = true;
+                        SearchStep::Done
+                    }
                     Some(ch) => {
                         searcher.end -= ch.len_utf8();
                         SearchStep::Reject(searcher.end, end)
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 0a2743b1c31..12d79a56a52 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -585,7 +585,7 @@ impl FromStr for bool {
         match s {
             "true" => Ok(true),
             "false" => Ok(false),
-            _ => Err(ParseBoolError { _priv: () }),
+            _ => Err(ParseBoolError),
         }
     }
 }
diff --git a/library/core/src/stream/from_iter.rs b/library/core/src/stream/from_iter.rs
new file mode 100644
index 00000000000..eb9a0fd2842
--- /dev/null
+++ b/library/core/src/stream/from_iter.rs
@@ -0,0 +1,38 @@
+use crate::pin::Pin;
+
+use crate::stream::Stream;
+use crate::task::{Context, Poll};
+
+/// A stream that was created from iterator.
+///
+/// This stream is created by the [`from_iter`] function.
+/// See it documentation for more.
+///
+/// [`from_iter`]: fn.from_iter.html
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+#[derive(Clone, Debug)]
+pub struct FromIter<I> {
+    iter: I,
+}
+
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+impl<I> Unpin for FromIter<I> {}
+
+/// Converts an iterator into a stream.
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+pub fn from_iter<I: IntoIterator>(iter: I) -> FromIter<I::IntoIter> {
+    FromIter { iter: iter.into_iter() }
+}
+
+#[unstable(feature = "stream_from_iter", issue = "81798")]
+impl<I: Iterator> Stream for FromIter<I> {
+    type Item = I::Item;
+
+    fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        Poll::Ready(self.iter.next())
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
diff --git a/library/core/src/stream/mod.rs b/library/core/src/stream/mod.rs
index 0df18af65eb..58dc8e1e5e6 100644
--- a/library/core/src/stream/mod.rs
+++ b/library/core/src/stream/mod.rs
@@ -122,6 +122,8 @@
 //! warning: unused result that must be used: streams do nothing unless polled
 //! ```
 
+mod from_iter;
 mod stream;
 
+pub use from_iter::{from_iter, FromIter};
 pub use stream::Stream;
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index f1a115563fd..d9de37e9c51 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -41,7 +41,7 @@
 //! instructions to implement `AtomicI8`. Note that this emulation should not
 //! have an impact on correctness of code, it's just something to be aware of.
 //!
-//! The atomic types in this module may not be available on all platforms. The
+//! The atomic types in this module might not be available on all platforms. The
 //! atomic types here are all widely available, however, and can generally be
 //! relied upon existing. Some notable exceptions are:
 //!
@@ -113,6 +113,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
+#![rustc_diagnostic_item = "atomic_mod"]
 
 use self::Ordering::*;
 
@@ -137,7 +138,8 @@ pub struct AtomicBool {
 
 #[cfg(target_has_atomic_load_store = "8")]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for AtomicBool {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl const Default for AtomicBool {
     /// Creates an `AtomicBool` initialized to `false`.
     #[inline]
     fn default() -> Self {
@@ -167,7 +169,8 @@ pub struct AtomicPtr<T> {
 
 #[cfg(target_has_atomic_load_store = "ptr")]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for AtomicPtr<T> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> const Default for AtomicPtr<T> {
     /// Creates a null `AtomicPtr<T>`.
     fn default() -> AtomicPtr<T> {
         AtomicPtr::new(crate::ptr::null_mut())
@@ -198,6 +201,7 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
 #[non_exhaustive]
+#[rustc_diagnostic_item = "Ordering"]
 pub enum Ordering {
     /// No ordering constraints, only atomic operations.
     ///
@@ -1349,7 +1353,8 @@ macro_rules! atomic_int {
         pub const $atomic_init: $atomic_type = $atomic_type::new(0);
 
         #[$stable]
-        impl Default for $atomic_type {
+        #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+        impl const Default for $atomic_type {
             #[inline]
             fn default() -> Self {
                 Self::new(Default::default())
@@ -2648,7 +2653,11 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 ///
 ///     pub fn lock(&self) {
 ///         // Wait until the old value is `false`.
-///         while self.flag.compare_and_swap(false, true, Ordering::Relaxed) != false {}
+///         while self
+///             .flag
+///             .compare_exchange_weak(false, true, Ordering::Relaxed, Ordering::Relaxed)
+///             .is_err()
+///         {}
 ///         // This fence synchronizes-with store in `unlock`.
 ///         fence(Ordering::Acquire);
 ///     }
@@ -2660,6 +2669,7 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_diagnostic_item = "fence"]
 pub fn fence(order: Ordering) {
     // SAFETY: using an atomic fence is safe.
     unsafe {
@@ -2710,7 +2720,7 @@ pub fn fence(order: Ordering) {
 /// Without `compiler_fence`, the `assert_eq!` in following code
 /// is *not* guaranteed to succeed, despite everything happening in a single thread.
 /// To see why, remember that the compiler is free to swap the stores to
-/// `IMPORTANT_VARIABLE` and `IS_READ` since they are both
+/// `IMPORTANT_VARIABLE` and `IS_READY` since they are both
 /// `Ordering::Relaxed`. If it does, and the signal handler is invoked right
 /// after `IS_READY` is updated, then the signal handler will see
 /// `IS_READY=1`, but `IMPORTANT_VARIABLE=0`.
@@ -2741,6 +2751,7 @@ pub fn fence(order: Ordering) {
 /// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
 #[inline]
 #[stable(feature = "compiler_fences", since = "1.21.0")]
+#[rustc_diagnostic_item = "compiler_fence"]
 pub fn compiler_fence(order: Ordering) {
     // SAFETY: using an atomic fence is safe.
     unsafe {
diff --git a/library/core/src/task/mod.rs b/library/core/src/task/mod.rs
index 3d6f4f5971a..5f077f77bbc 100644
--- a/library/core/src/task/mod.rs
+++ b/library/core/src/task/mod.rs
@@ -11,5 +11,5 @@ mod wake;
 pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
 
 mod ready;
-#[unstable(feature = "ready_macro", issue = "70922")]
+#[stable(feature = "ready_macro", since = "1.56.0")]
 pub use ready::ready;
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index 9cf89623d88..fc0a4e74797 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -26,7 +26,21 @@ pub enum Poll<T> {
 }
 
 impl<T> Poll<T> {
-    /// Changes the ready value of this `Poll` with the closure provided.
+    /// Maps a `Poll<T>` to `Poll<U>` by applying a function to a contained value.
+    ///
+    /// # Examples
+    ///
+    /// Converts a `Poll<`[`String`]`>` into an `Poll<`[`usize`]`>`, consuming the original:
+    ///
+    /// [`String`]: ../../std/string/struct.String.html
+    /// ```
+    /// # use core::task::Poll;
+    /// let poll_some_string = Poll::Ready(String::from("Hello, World!"));
+    /// // `Poll::map` takes self *by value*, consuming `poll_some_string`
+    /// let poll_some_len = poll_some_string.map(|s| s.len());
+    ///
+    /// assert_eq!(poll_some_len, Poll::Ready(13));
+    /// ```
     #[stable(feature = "futures_api", since = "1.36.0")]
     pub fn map<U, F>(self, f: F) -> Poll<U>
     where
@@ -38,7 +52,18 @@ impl<T> Poll<T> {
         }
     }
 
-    /// Returns `true` if this is `Poll::Ready`
+    /// Returns `true` if the poll is a [`Poll::Ready`] value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use core::task::Poll;
+    /// let x: Poll<u32> = Poll::Ready(2);
+    /// assert_eq!(x.is_ready(), true);
+    ///
+    /// let x: Poll<u32> = Poll::Pending;
+    /// assert_eq!(x.is_ready(), false);
+    /// ```
     #[inline]
     #[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
     #[stable(feature = "futures_api", since = "1.36.0")]
@@ -46,7 +71,20 @@ impl<T> Poll<T> {
         matches!(*self, Poll::Ready(_))
     }
 
-    /// Returns `true` if this is `Poll::Pending`
+    /// Returns `true` if the poll is a [`Pending`] value.
+    ///
+    /// [`Pending`]: Poll::Pending
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use core::task::Poll;
+    /// let x: Poll<u32> = Poll::Ready(2);
+    /// assert_eq!(x.is_pending(), false);
+    ///
+    /// let x: Poll<u32> = Poll::Pending;
+    /// assert_eq!(x.is_pending(), true);
+    /// ```
     #[inline]
     #[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
     #[stable(feature = "futures_api", since = "1.36.0")]
@@ -56,7 +94,20 @@ impl<T> Poll<T> {
 }
 
 impl<T, E> Poll<Result<T, E>> {
-    /// Changes the success value of this `Poll` with the closure provided.
+    /// Maps a `Poll<Result<T, E>>` to `Poll<Result<U, E>>` by applying a
+    /// function to a contained `Poll::Ready(Ok)` value, leaving all other
+    /// variants untouched.
+    ///
+    /// This function can be used to compose the results of two functions.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use core::task::Poll;
+    /// let res: Poll<Result<u8, _>> = Poll::Ready("12".parse());
+    /// let squared = res.map_ok(|n| n * n);
+    /// assert_eq!(squared, Poll::Ready(Ok(144)));
+    /// ```
     #[stable(feature = "futures_api", since = "1.36.0")]
     pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
     where
@@ -69,7 +120,21 @@ impl<T, E> Poll<Result<T, E>> {
         }
     }
 
-    /// Changes the error value of this `Poll` with the closure provided.
+    /// Maps a `Poll::Ready<Result<T, E>>` to `Poll::Ready<Result<T, F>>` by
+    /// applying a function to a contained `Poll::Ready(Err)` value, leaving all other
+    /// variants untouched.
+    ///
+    /// This function can be used to pass through a successful result while handling
+    /// an error.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use core::task::Poll;
+    /// let res: Poll<Result<u8, _>> = Poll::Ready("oops".parse());
+    /// let res = res.map_err(|_| 0_u8);
+    /// assert_eq!(res, Poll::Ready(Err(0)));
+    /// ```
     #[stable(feature = "futures_api", since = "1.36.0")]
     pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
     where
@@ -84,7 +149,20 @@ impl<T, E> Poll<Result<T, E>> {
 }
 
 impl<T, E> Poll<Option<Result<T, E>>> {
-    /// Changes the success value of this `Poll` with the closure provided.
+    /// Maps a `Poll<Option<Result<T, E>>>` to `Poll<Option<Result<U, E>>>` by
+    /// applying a function to a contained `Poll::Ready(Some(Ok))` value,
+    /// leaving all other variants untouched.
+    ///
+    /// This function can be used to compose the results of two functions.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use core::task::Poll;
+    /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("12".parse()));
+    /// let squared = res.map_ok(|n| n * n);
+    /// assert_eq!(squared, Poll::Ready(Some(Ok(144))));
+    /// ```
     #[stable(feature = "poll_map", since = "1.51.0")]
     pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
     where
@@ -98,7 +176,22 @@ impl<T, E> Poll<Option<Result<T, E>>> {
         }
     }
 
-    /// Changes the error value of this `Poll` with the closure provided.
+    /// Maps a `Poll::Ready<Option<Result<T, E>>>` to
+    /// `Poll::Ready<Option<Result<T, F>>>` by applying a function to a
+    /// contained `Poll::Ready(Some(Err))` value, leaving all other variants
+    /// untouched.
+    ///
+    /// This function can be used to pass through a successful result while handling
+    /// an error.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use core::task::Poll;
+    /// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("oops".parse()));
+    /// let res = res.map_err(|_| 0_u8);
+    /// assert_eq!(res, Poll::Ready(Some(Err(0))));
+    /// ```
     #[stable(feature = "poll_map", since = "1.51.0")]
     pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
     where
@@ -128,32 +221,6 @@ impl<T> From<T> for Poll<T> {
     }
 }
 
-#[stable(feature = "futures_api", since = "1.36.0")]
-#[cfg(bootstrap)]
-impl<T, E> ops::TryV1 for Poll<Result<T, E>> {
-    type Output = Poll<T>;
-    type Error = E;
-
-    #[inline]
-    fn into_result(self) -> Result<Self::Output, Self::Error> {
-        match self {
-            Poll::Ready(Ok(x)) => Ok(Poll::Ready(x)),
-            Poll::Ready(Err(e)) => Err(e),
-            Poll::Pending => Ok(Poll::Pending),
-        }
-    }
-
-    #[inline]
-    fn from_error(e: Self::Error) -> Self {
-        Poll::Ready(Err(e))
-    }
-
-    #[inline]
-    fn from_ok(x: Self::Output) -> Self {
-        x.map(Ok)
-    }
-}
-
 #[unstable(feature = "try_trait_v2", issue = "84277")]
 impl<T, E> ops::TryV2 for Poll<Result<T, E>> {
     type Output = Poll<T>;
@@ -184,33 +251,6 @@ impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Pol
     }
 }
 
-#[stable(feature = "futures_api", since = "1.36.0")]
-#[cfg(bootstrap)]
-impl<T, E> ops::TryV1 for Poll<Option<Result<T, E>>> {
-    type Output = Poll<Option<T>>;
-    type Error = E;
-
-    #[inline]
-    fn into_result(self) -> Result<Self::Output, Self::Error> {
-        match self {
-            Poll::Ready(Some(Ok(x))) => Ok(Poll::Ready(Some(x))),
-            Poll::Ready(Some(Err(e))) => Err(e),
-            Poll::Ready(None) => Ok(Poll::Ready(None)),
-            Poll::Pending => Ok(Poll::Pending),
-        }
-    }
-
-    #[inline]
-    fn from_error(e: Self::Error) -> Self {
-        Poll::Ready(Some(Err(e)))
-    }
-
-    #[inline]
-    fn from_ok(x: Self::Output) -> Self {
-        x.map(|x| x.map(Ok))
-    }
-}
-
 #[unstable(feature = "try_trait_v2", issue = "84277")]
 impl<T, E> ops::TryV2 for Poll<Option<Result<T, E>>> {
     type Output = Poll<Option<T>>;
diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs
index cbf69900015..2834ca5fe22 100644
--- a/library/core/src/task/ready.rs
+++ b/library/core/src/task/ready.rs
@@ -8,8 +8,6 @@
 /// # Examples
 ///
 /// ```
-/// #![feature(ready_macro)]
-///
 /// use std::task::{ready, Context, Poll};
 /// use std::future::{self, Future};
 /// use std::pin::Pin;
@@ -29,8 +27,6 @@
 /// The `ready!` call expands to:
 ///
 /// ```
-/// # #![feature(ready_macro)]
-/// #
 /// # use std::task::{Context, Poll};
 /// # use std::future::{self, Future};
 /// # use std::pin::Pin;
@@ -49,7 +45,7 @@
 ///     # Poll::Ready(())
 /// # }
 /// ```
-#[unstable(feature = "ready_macro", issue = "70922")]
+#[stable(feature = "ready_macro", since = "1.56.0")]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro ready($e:expr) {
     match $e {
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 489b7224403..2d8a1cb1ab0 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -61,6 +61,7 @@ const MICROS_PER_SEC: u64 = 1_000_000;
 /// crate to do so.
 #[stable(feature = "duration", since = "1.3.0")]
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Duration")]
 pub struct Duration {
     secs: u64,
     nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC
@@ -687,21 +688,47 @@ impl Duration {
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn from_secs_f64(secs: f64) -> Duration {
+        match Duration::try_from_secs_f64(secs) {
+            Ok(v) => v,
+            Err(e) => crate::panicking::panic(e.description()),
+        }
+    }
+
+    /// The checked version of [`from_secs_f64`].
+    ///
+    /// [`from_secs_f64`]: Duration::from_secs_f64
+    ///
+    /// This constructor will return an `Err` if `secs` is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_checked_float)]
+    ///
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::try_from_secs_f64(2.7);
+    /// assert_eq!(dur, Ok(Duration::new(2, 700_000_000)));
+    ///
+    /// let negative = Duration::try_from_secs_f64(-5.0);
+    /// assert!(negative.is_err());
+    /// ```
+    #[unstable(feature = "duration_checked_float", issue = "83400")]
+    #[inline]
+    pub const fn try_from_secs_f64(secs: f64) -> Result<Duration, FromSecsError> {
         const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
         let nanos = secs * (NANOS_PER_SEC as f64);
         if !nanos.is_finite() {
-            panic!("got non-finite value when converting float to duration");
-        }
-        if nanos >= MAX_NANOS_F64 {
-            panic!("overflow when converting float to duration");
-        }
-        if nanos < 0.0 {
-            panic!("underflow when converting float to duration");
-        }
-        let nanos = nanos as u128;
-        Duration {
-            secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
-            nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
+            Err(FromSecsError { kind: FromSecsErrorKind::NonFinite })
+        } else if nanos >= MAX_NANOS_F64 {
+            Err(FromSecsError { kind: FromSecsErrorKind::Overflow })
+        } else if nanos < 0.0 {
+            Err(FromSecsError { kind: FromSecsErrorKind::Underflow })
+        } else {
+            let nanos = nanos as u128;
+            Ok(Duration {
+                secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
+                nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
+            })
         }
     }
 
@@ -722,21 +749,47 @@ impl Duration {
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn from_secs_f32(secs: f32) -> Duration {
+        match Duration::try_from_secs_f32(secs) {
+            Ok(v) => v,
+            Err(e) => crate::panicking::panic(e.description()),
+        }
+    }
+
+    /// The checked version of [`from_secs_f32`].
+    ///
+    /// [`from_secs_f32`]: Duration::from_secs_f32
+    ///
+    /// This constructor will return an `Err` if `secs` is not finite, negative or overflows `Duration`.
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(duration_checked_float)]
+    ///
+    /// use std::time::Duration;
+    ///
+    /// let dur = Duration::try_from_secs_f32(2.7);
+    /// assert_eq!(dur, Ok(Duration::new(2, 700_000_000)));
+    ///
+    /// let negative = Duration::try_from_secs_f32(-5.0);
+    /// assert!(negative.is_err());
+    /// ```
+    #[unstable(feature = "duration_checked_float", issue = "83400")]
+    #[inline]
+    pub const fn try_from_secs_f32(secs: f32) -> Result<Duration, FromSecsError> {
         const MAX_NANOS_F32: f32 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f32;
         let nanos = secs * (NANOS_PER_SEC as f32);
         if !nanos.is_finite() {
-            panic!("got non-finite value when converting float to duration");
-        }
-        if nanos >= MAX_NANOS_F32 {
-            panic!("overflow when converting float to duration");
-        }
-        if nanos < 0.0 {
-            panic!("underflow when converting float to duration");
-        }
-        let nanos = nanos as u128;
-        Duration {
-            secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
-            nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
+            Err(FromSecsError { kind: FromSecsErrorKind::NonFinite })
+        } else if nanos >= MAX_NANOS_F32 {
+            Err(FromSecsError { kind: FromSecsErrorKind::Overflow })
+        } else if nanos < 0.0 {
+            Err(FromSecsError { kind: FromSecsErrorKind::Underflow })
+        } else {
+            let nanos = nanos as u128;
+            Ok(Duration {
+                secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
+                nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
+            })
         }
     }
 
@@ -1099,3 +1152,55 @@ impl fmt::Debug for Duration {
         }
     }
 }
+
+/// An error which can be returned when converting a floating-point value of seconds
+/// into a [`Duration`].
+///
+/// This error is used as the error type for [`Duration::try_from_secs_f32`] and
+/// [`Duration::try_from_secs_f64`].
+///
+/// # Example
+///
+/// ```
+/// #![feature(duration_checked_float)]
+///
+/// use std::time::Duration;
+///
+/// if let Err(e) = Duration::try_from_secs_f32(-1.0) {
+///     println!("Failed conversion to Duration: {}", e);
+/// }
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[unstable(feature = "duration_checked_float", issue = "83400")]
+pub struct FromSecsError {
+    kind: FromSecsErrorKind,
+}
+
+impl FromSecsError {
+    const fn description(&self) -> &'static str {
+        match self.kind {
+            FromSecsErrorKind::NonFinite => {
+                "got non-finite value when converting float to duration"
+            }
+            FromSecsErrorKind::Overflow => "overflow when converting float to duration",
+            FromSecsErrorKind::Underflow => "underflow when converting float to duration",
+        }
+    }
+}
+
+#[unstable(feature = "duration_checked_float", issue = "83400")]
+impl fmt::Display for FromSecsError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self.description(), f)
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+enum FromSecsErrorKind {
+    // Value is not a finite value (either infinity or NaN).
+    NonFinite,
+    // Value is too large to store in a `Duration`.
+    Overflow,
+    // Value is less than `0.0`.
+    Underflow,
+}
diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs
index 37ca0a0779b..72fa059b787 100644
--- a/library/core/src/unicode/mod.rs
+++ b/library/core/src/unicode/mod.rs
@@ -4,7 +4,7 @@
 pub(crate) mod printable;
 mod unicode_data;
 
-/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
+/// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
 /// `char` and `str` methods are based on.
 ///
 /// New versions of Unicode are released regularly and subsequently all methods
diff --git a/library/core/src/unicode/printable.py b/library/core/src/unicode/printable.py
index 91db6381c9b..c42850d2324 100755
--- a/library/core/src/unicode/printable.py
+++ b/library/core/src/unicode/printable.py
@@ -130,7 +130,7 @@ def print_normal(normal, normalname):
     print("];")
 
 def main():
-    file = get_file("http://www.unicode.org/Public/UNIDATA/UnicodeData.txt")
+    file = get_file("https://www.unicode.org/Public/UNIDATA/UnicodeData.txt")
 
     codepoints = get_codepoints(file)
 
diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs
index c16f54081ce..51eca1e05d3 100644
--- a/library/core/tests/char.rs
+++ b/library/core/tests/char.rs
@@ -67,10 +67,20 @@ fn test_to_digit() {
     assert_eq!('A'.to_digit(16), Some(10));
     assert_eq!('b'.to_digit(16), Some(11));
     assert_eq!('B'.to_digit(16), Some(11));
+    assert_eq!('A'.to_digit(36), Some(10));
     assert_eq!('z'.to_digit(36), Some(35));
     assert_eq!('Z'.to_digit(36), Some(35));
-    assert_eq!(' '.to_digit(10), None);
+    assert_eq!('['.to_digit(36), None);
+    assert_eq!('`'.to_digit(36), None);
+    assert_eq!('{'.to_digit(36), None);
     assert_eq!('$'.to_digit(36), None);
+    assert_eq!('@'.to_digit(16), None);
+    assert_eq!('G'.to_digit(16), None);
+    assert_eq!('g'.to_digit(16), None);
+    assert_eq!(' '.to_digit(10), None);
+    assert_eq!('/'.to_digit(10), None);
+    assert_eq!(':'.to_digit(10), None);
+    assert_eq!(':'.to_digit(11), None);
 }
 
 #[test]
diff --git a/library/core/tests/hash/mod.rs b/library/core/tests/hash/mod.rs
index 1566d357490..72ccdd4848a 100644
--- a/library/core/tests/hash/mod.rs
+++ b/library/core/tests/hash/mod.rs
@@ -1,7 +1,7 @@
 mod sip;
 
 use std::default::Default;
-use std::hash::{Hash, Hasher};
+use std::hash::{BuildHasher, Hash, Hasher};
 use std::rc::Rc;
 
 struct MyHasher {
@@ -139,3 +139,10 @@ fn test_indirect_hasher() {
     }
     assert_eq!(hasher.hash, 5);
 }
+
+#[test]
+fn test_build_hasher_object_safe() {
+    use std::collections::hash_map::{DefaultHasher, RandomState};
+
+    let _: &dyn BuildHasher<Hasher = DefaultHasher> = &RandomState::new();
+}
diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs
index 4bbae6947bf..aaac39c2979 100644
--- a/library/core/tests/iter/adapters/flatten.rs
+++ b/library/core/tests/iter/adapters/flatten.rs
@@ -1,4 +1,5 @@
 use super::*;
+use core::array;
 use core::iter::*;
 
 #[test]
@@ -109,3 +110,42 @@ fn test_double_ended_flatten() {
     assert_eq!(it.next(), None);
     assert_eq!(it.next_back(), None);
 }
+
+#[test]
+fn test_trusted_len_flatten() {
+    fn assert_trusted_len<T: TrustedLen>(_: &T) {}
+    let mut iter = array::IntoIter::new([[0; 3]; 4]).flatten();
+    assert_trusted_len(&iter);
+
+    assert_eq!(iter.size_hint(), (12, Some(12)));
+    iter.next();
+    assert_eq!(iter.size_hint(), (11, Some(11)));
+    iter.next_back();
+    assert_eq!(iter.size_hint(), (10, Some(10)));
+
+    let iter = array::IntoIter::new([[(); usize::MAX]; 1]).flatten();
+    assert_eq!(iter.size_hint(), (usize::MAX, Some(usize::MAX)));
+
+    let iter = array::IntoIter::new([[(); usize::MAX]; 2]).flatten();
+    assert_eq!(iter.size_hint(), (usize::MAX, None));
+
+    let mut a = [(); 10];
+    let mut b = [(); 10];
+
+    let iter = array::IntoIter::new([&mut a, &mut b]).flatten();
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (20, Some(20)));
+    core::mem::drop(iter);
+
+    let iter = array::IntoIter::new([&a, &b]).flatten();
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (20, Some(20)));
+
+    let iter = [(), (), ()].iter().flat_map(|_| [(); 1000]);
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (3000, Some(3000)));
+
+    let iter = [(), ()].iter().flat_map(|_| &a);
+    assert_trusted_len(&iter);
+    assert_eq!(iter.size_hint(), (20, Some(20)));
+}
diff --git a/library/core/tests/iter/adapters/mod.rs b/library/core/tests/iter/adapters/mod.rs
index 96a53be1eaa..567d9fe49ca 100644
--- a/library/core/tests/iter/adapters/mod.rs
+++ b/library/core/tests/iter/adapters/mod.rs
@@ -24,7 +24,7 @@ use core::cell::Cell;
 
 /// An iterator that panics whenever `next` or next_back` is called
 /// after `None` has already been returned. This does not violate
-/// `Iterator`'s contract. Used to test that iterator adaptors don't
+/// `Iterator`'s contract. Used to test that iterator adapters don't
 /// poll their inner iterators after exhausting them.
 pub struct NonFused<I> {
     iter: I,
diff --git a/library/core/tests/iter/adapters/zip.rs b/library/core/tests/iter/adapters/zip.rs
index 797bfd957f9..585cfbb90e4 100644
--- a/library/core/tests/iter/adapters/zip.rs
+++ b/library/core/tests/iter/adapters/zip.rs
@@ -233,6 +233,33 @@ fn test_zip_trusted_random_access_composition() {
 }
 
 #[test]
+#[cfg(panic = "unwind")]
+fn test_zip_trusted_random_access_next_back_drop() {
+    use std::panic::catch_unwind;
+    use std::panic::AssertUnwindSafe;
+
+    let mut counter = 0;
+
+    let it = [42].iter().map(|e| {
+        let c = counter;
+        counter += 1;
+        if c == 0 {
+            panic!("bomb");
+        }
+
+        e
+    });
+    let it2 = [(); 0].iter();
+    let mut zip = it.zip(it2);
+    catch_unwind(AssertUnwindSafe(|| {
+        zip.next_back();
+    }))
+    .unwrap_err();
+    assert!(zip.next().is_none());
+    assert_eq!(counter, 1);
+}
+
+#[test]
 fn test_double_ended_zip() {
     let xs = [1, 2, 3, 4, 5, 6];
     let ys = [1, 2, 3, 7];
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 16051b3bc36..13f483f19b7 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -1,10 +1,8 @@
 #![feature(alloc_layout_extra)]
 #![feature(array_chunks)]
 #![feature(array_methods)]
-#![feature(array_map)]
 #![feature(array_windows)]
 #![feature(bool_to_option)]
-#![feature(bound_cloned)]
 #![feature(box_syntax)]
 #![feature(cell_update)]
 #![feature(cfg_panic)]
@@ -15,7 +13,8 @@
 #![feature(const_ptr_read)]
 #![feature(const_ptr_write)]
 #![feature(const_ptr_offset)]
-#![feature(control_flow_enum)]
+#![feature(const_trait_impl)]
+#![feature(const_num_from_num)]
 #![feature(core_intrinsics)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
@@ -31,7 +30,6 @@
 #![feature(try_find)]
 #![feature(is_sorted)]
 #![feature(pattern)]
-#![feature(raw)]
 #![feature(sort_internals)]
 #![feature(slice_partition_at_index)]
 #![feature(maybe_uninit_uninit_array)]
@@ -39,6 +37,7 @@
 #![feature(maybe_uninit_extra)]
 #![feature(maybe_uninit_write_slice)]
 #![feature(min_specialization)]
+#![feature(numfmt)]
 #![feature(step_trait)]
 #![feature(str_internals)]
 #![feature(test)]
@@ -46,7 +45,7 @@
 #![feature(try_trait_v2)]
 #![feature(slice_internals)]
 #![feature(slice_partition_dedup)]
-#![feature(int_error_matching)]
+#![feature(int_log)]
 #![feature(iter_advance_by)]
 #![feature(iter_partition_in_place)]
 #![feature(iter_intersperse)]
@@ -69,6 +68,7 @@
 #![feature(slice_group_by)]
 #![feature(trusted_random_access)]
 #![feature(unsize)]
+#![feature(unzip_option)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 extern crate test;
diff --git a/library/core/tests/macros.rs b/library/core/tests/macros.rs
index 482f3c1c998..ff3632e3550 100644
--- a/library/core/tests/macros.rs
+++ b/library/core/tests/macros.rs
@@ -12,3 +12,9 @@ fn assert_escape() {
 fn assert_ne_trailing_comma() {
     assert_ne!(1, 2,);
 }
+
+#[rustfmt::skip]
+#[test]
+fn matches_leading_pipe() {
+    matches!(1, | 1 | 2 | 3);
+}
diff --git a/library/core/tests/manually_drop.rs b/library/core/tests/manually_drop.rs
index 77a338daf7d..9eac279733a 100644
--- a/library/core/tests/manually_drop.rs
+++ b/library/core/tests/manually_drop.rs
@@ -2,6 +2,7 @@ use core::mem::ManuallyDrop;
 
 #[test]
 fn smoke() {
+    #[derive(Clone)]
     struct TypeWithDrop;
     impl Drop for TypeWithDrop {
         fn drop(&mut self) {
@@ -16,4 +17,11 @@ fn smoke() {
     let x: Box<ManuallyDrop<[TypeWithDrop]>> =
         Box::new(ManuallyDrop::new([TypeWithDrop, TypeWithDrop]));
     drop(x);
+
+    // test clone and clone_from implementations
+    let mut x = ManuallyDrop::new(TypeWithDrop);
+    let y = x.clone();
+    x.clone_from(&y);
+    drop(x);
+    drop(y);
 }
diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs
index dfdbc9305d2..c780bb32ca9 100644
--- a/library/core/tests/mem.rs
+++ b/library/core/tests/mem.rs
@@ -97,28 +97,6 @@ fn test_transmute_copy() {
     assert_eq!(1, unsafe { transmute_copy(&1) });
 }
 
-// Remove this test when `std::raw` is removed.
-// The replacement pointer metadata APIs are tested in library/core/tests/ptr.rs
-#[allow(deprecated)]
-#[test]
-fn test_transmute() {
-    trait Foo {
-        fn dummy(&self) {}
-    }
-    impl Foo for isize {}
-
-    let a = box 100isize as Box<dyn Foo>;
-    unsafe {
-        let x: ::core::raw::TraitObject = transmute(a);
-        assert!(*(x.data as *const isize) == 100);
-        let _x: Box<dyn Foo> = transmute(x);
-    }
-
-    unsafe {
-        assert_eq!(transmute::<_, Vec<u8>>("L".to_string()), [76]);
-    }
-}
-
 #[test]
 #[allow(dead_code)]
 fn test_discriminant_send_sync() {
diff --git a/library/core/tests/num/const_from.rs b/library/core/tests/num/const_from.rs
new file mode 100644
index 00000000000..aca18ef39de
--- /dev/null
+++ b/library/core/tests/num/const_from.rs
@@ -0,0 +1,25 @@
+#[test]
+fn from() {
+    use core::convert::TryFrom;
+    use core::num::TryFromIntError;
+
+    // From
+    const FROM: i64 = i64::from(1i32);
+    assert_eq!(FROM, 1i64);
+
+    // From int to float
+    const FROM_F64: f64 = f64::from(42u8);
+    assert_eq!(FROM_F64, 42f64);
+
+    // Upper bounded
+    const U8_FROM_U16: Result<u8, TryFromIntError> = u8::try_from(1u16);
+    assert_eq!(U8_FROM_U16, Ok(1u8));
+
+    // Both bounded
+    const I8_FROM_I16: Result<i8, TryFromIntError> = i8::try_from(1i16);
+    assert_eq!(I8_FROM_I16, Ok(1i8));
+
+    // Lower bounded
+    const I16_FROM_U16: Result<i16, TryFromIntError> = i16::try_from(1u16);
+    assert_eq!(I16_FROM_U16, Ok(1i16));
+}
diff --git a/library/core/tests/num/dec2flt/float.rs b/library/core/tests/num/dec2flt/float.rs
new file mode 100644
index 00000000000..7a9587a18d0
--- /dev/null
+++ b/library/core/tests/num/dec2flt/float.rs
@@ -0,0 +1,33 @@
+use core::num::dec2flt::float::RawFloat;
+
+#[test]
+fn test_f32_integer_decode() {
+    assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
+    assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
+    assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
+    assert_eq!(0f32.integer_decode(), (0, -150, 1));
+    assert_eq!((-0f32).integer_decode(), (0, -150, -1));
+    assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1));
+    assert_eq!(f32::NEG_INFINITY.integer_decode(), (8388608, 105, -1));
+
+    // Ignore the "sign" (quiet / signalling flag) of NAN.
+    // It can vary between runtime operations and LLVM folding.
+    let (nan_m, nan_e, _nan_s) = f32::NAN.integer_decode();
+    assert_eq!((nan_m, nan_e), (12582912, 105));
+}
+
+#[test]
+fn test_f64_integer_decode() {
+    assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
+    assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
+    assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
+    assert_eq!(0f64.integer_decode(), (0, -1075, 1));
+    assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
+    assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1));
+    assert_eq!(f64::NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
+
+    // Ignore the "sign" (quiet / signalling flag) of NAN.
+    // It can vary between runtime operations and LLVM folding.
+    let (nan_m, nan_e, _nan_s) = f64::NAN.integer_decode();
+    assert_eq!((nan_m, nan_e), (6755399441055744, 972));
+}
diff --git a/library/core/tests/num/dec2flt/lemire.rs b/library/core/tests/num/dec2flt/lemire.rs
new file mode 100644
index 00000000000..f71bbb7c7a3
--- /dev/null
+++ b/library/core/tests/num/dec2flt/lemire.rs
@@ -0,0 +1,53 @@
+use core::num::dec2flt::lemire::compute_float;
+
+fn compute_float32(q: i64, w: u64) -> (i32, u64) {
+    let fp = compute_float::<f32>(q, w);
+    (fp.e, fp.f)
+}
+
+fn compute_float64(q: i64, w: u64) -> (i32, u64) {
+    let fp = compute_float::<f64>(q, w);
+    (fp.e, fp.f)
+}
+
+#[test]
+fn compute_float_f32_rounding() {
+    // These test near-halfway cases for single-precision floats.
+    assert_eq!(compute_float32(0, 16777216), (151, 0));
+    assert_eq!(compute_float32(0, 16777217), (151, 0));
+    assert_eq!(compute_float32(0, 16777218), (151, 1));
+    assert_eq!(compute_float32(0, 16777219), (151, 2));
+    assert_eq!(compute_float32(0, 16777220), (151, 2));
+
+    // These are examples of the above tests, with
+    // digits from the exponent shifted to the mantissa.
+    assert_eq!(compute_float32(-10, 167772160000000000), (151, 0));
+    assert_eq!(compute_float32(-10, 167772170000000000), (151, 0));
+    assert_eq!(compute_float32(-10, 167772180000000000), (151, 1));
+    // Let's check the lines to see if anything is different in table...
+    assert_eq!(compute_float32(-10, 167772190000000000), (151, 2));
+    assert_eq!(compute_float32(-10, 167772200000000000), (151, 2));
+}
+
+#[test]
+fn compute_float_f64_rounding() {
+    // These test near-halfway cases for double-precision floats.
+    assert_eq!(compute_float64(0, 9007199254740992), (1076, 0));
+    assert_eq!(compute_float64(0, 9007199254740993), (1076, 0));
+    assert_eq!(compute_float64(0, 9007199254740994), (1076, 1));
+    assert_eq!(compute_float64(0, 9007199254740995), (1076, 2));
+    assert_eq!(compute_float64(0, 9007199254740996), (1076, 2));
+    assert_eq!(compute_float64(0, 18014398509481984), (1077, 0));
+    assert_eq!(compute_float64(0, 18014398509481986), (1077, 0));
+    assert_eq!(compute_float64(0, 18014398509481988), (1077, 1));
+    assert_eq!(compute_float64(0, 18014398509481990), (1077, 2));
+    assert_eq!(compute_float64(0, 18014398509481992), (1077, 2));
+
+    // These are examples of the above tests, with
+    // digits from the exponent shifted to the mantissa.
+    assert_eq!(compute_float64(-3, 9007199254740992000), (1076, 0));
+    assert_eq!(compute_float64(-3, 9007199254740993000), (1076, 0));
+    assert_eq!(compute_float64(-3, 9007199254740994000), (1076, 1));
+    assert_eq!(compute_float64(-3, 9007199254740995000), (1076, 2));
+    assert_eq!(compute_float64(-3, 9007199254740996000), (1076, 2));
+}
diff --git a/library/core/tests/num/dec2flt/mod.rs b/library/core/tests/num/dec2flt/mod.rs
index 32f05d1def5..4990d4a083d 100644
--- a/library/core/tests/num/dec2flt/mod.rs
+++ b/library/core/tests/num/dec2flt/mod.rs
@@ -1,7 +1,8 @@
 #![allow(overflowing_literals)]
 
+mod float;
+mod lemire;
 mod parse;
-mod rawfp;
 
 // Take a float literal, turn it into a string in various ways (that are all trusted
 // to be correct) and see if those strings are parsed back to the value of the literal.
@@ -28,12 +29,6 @@ fn ordinary() {
     test_literal!(0.1);
     test_literal!(12345.);
     test_literal!(0.9999999);
-
-    if cfg!(miri) {
-        // Miri is too slow
-        return;
-    }
-
     test_literal!(2.2250738585072014e-308);
 }
 
@@ -54,7 +49,6 @@ fn large() {
 }
 
 #[test]
-#[cfg_attr(miri, ignore)] // Miri is too slow
 fn subnormals() {
     test_literal!(5e-324);
     test_literal!(91e-324);
@@ -66,7 +60,6 @@ fn subnormals() {
 }
 
 #[test]
-#[cfg_attr(miri, ignore)] // Miri is too slow
 fn infinity() {
     test_literal!(1e400);
     test_literal!(1e309);
@@ -78,12 +71,6 @@ fn infinity() {
 fn zero() {
     test_literal!(0.0);
     test_literal!(1e-325);
-
-    if cfg!(miri) {
-        // Miri is too slow
-        return;
-    }
-
     test_literal!(1e-326);
     test_literal!(1e-500);
 }
diff --git a/library/core/tests/num/dec2flt/parse.rs b/library/core/tests/num/dec2flt/parse.rs
index bb7e51d3002..473feacc91f 100644
--- a/library/core/tests/num/dec2flt/parse.rs
+++ b/library/core/tests/num/dec2flt/parse.rs
@@ -1,17 +1,23 @@
-use core::num::dec2flt::parse::ParseResult::{Invalid, Valid};
-use core::num::dec2flt::parse::{parse_decimal, Decimal};
+use core::num::dec2flt::number::Number;
+use core::num::dec2flt::parse::parse_number;
+use core::num::dec2flt::{dec2flt, pfe_invalid};
+
+fn new_number(e: i64, m: u64) -> Number {
+    Number { exponent: e, mantissa: m, negative: false, many_digits: false }
+}
 
 #[test]
 fn missing_pieces() {
     let permutations = &[".e", "1e", "e4", "e", ".12e", "321.e", "32.12e+", "12.32e-"];
     for &s in permutations {
-        assert_eq!(parse_decimal(s), Invalid);
+        assert_eq!(dec2flt::<f64>(s), Err(pfe_invalid()));
     }
 }
 
 #[test]
 fn invalid_chars() {
     let invalid = "r,?<j";
+    let error = Err(pfe_invalid());
     let valid_strings = &["123", "666.", ".1", "5e1", "7e-3", "0.0e+1"];
     for c in invalid.chars() {
         for s in valid_strings {
@@ -19,23 +25,153 @@ fn invalid_chars() {
                 let mut input = String::new();
                 input.push_str(s);
                 input.insert(i, c);
-                assert!(parse_decimal(&input) == Invalid, "did not reject invalid {:?}", input);
+                assert!(dec2flt::<f64>(&input) == error, "did not reject invalid {:?}", input);
             }
         }
     }
 }
 
+fn parse_positive(s: &[u8]) -> Option<Number> {
+    parse_number(s, false)
+}
+
 #[test]
 fn valid() {
-    assert_eq!(parse_decimal("123.456e789"), Valid(Decimal::new(b"123", b"456", 789)));
-    assert_eq!(parse_decimal("123.456e+789"), Valid(Decimal::new(b"123", b"456", 789)));
-    assert_eq!(parse_decimal("123.456e-789"), Valid(Decimal::new(b"123", b"456", -789)));
-    assert_eq!(parse_decimal(".050"), Valid(Decimal::new(b"", b"050", 0)));
-    assert_eq!(parse_decimal("999"), Valid(Decimal::new(b"999", b"", 0)));
-    assert_eq!(parse_decimal("1.e300"), Valid(Decimal::new(b"1", b"", 300)));
-    assert_eq!(parse_decimal(".1e300"), Valid(Decimal::new(b"", b"1", 300)));
-    assert_eq!(parse_decimal("101e-33"), Valid(Decimal::new(b"101", b"", -33)));
+    assert_eq!(parse_positive(b"123.456e789"), Some(new_number(786, 123456)));
+    assert_eq!(parse_positive(b"123.456e+789"), Some(new_number(786, 123456)));
+    assert_eq!(parse_positive(b"123.456e-789"), Some(new_number(-792, 123456)));
+    assert_eq!(parse_positive(b".050"), Some(new_number(-3, 50)));
+    assert_eq!(parse_positive(b"999"), Some(new_number(0, 999)));
+    assert_eq!(parse_positive(b"1.e300"), Some(new_number(300, 1)));
+    assert_eq!(parse_positive(b".1e300"), Some(new_number(299, 1)));
+    assert_eq!(parse_positive(b"101e-33"), Some(new_number(-33, 101)));
     let zeros = "0".repeat(25);
     let s = format!("1.5e{}", zeros);
-    assert_eq!(parse_decimal(&s), Valid(Decimal::new(b"1", b"5", 0)));
+    assert_eq!(parse_positive(s.as_bytes()), Some(new_number(-1, 15)));
+}
+
+macro_rules! assert_float_result_bits_eq {
+    ($bits:literal, $ty:ty, $str:literal) => {{
+        let p = dec2flt::<$ty>($str);
+        assert_eq!(p.map(|x| x.to_bits()), Ok($bits));
+    }};
+}
+
+#[test]
+fn issue31109() {
+    // Regression test for #31109.
+    // Ensure the test produces a valid float with the expected bit pattern.
+    assert_float_result_bits_eq!(
+        0x3fd5555555555555,
+        f64,
+        "0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"
+    );
+}
+
+#[test]
+fn issue31407() {
+    // Regression test for #31407.
+    // Ensure the test produces a valid float with the expected bit pattern.
+    assert_float_result_bits_eq!(
+        0x1752a64e34ba0d3,
+        f64,
+        "1234567890123456789012345678901234567890e-340"
+    );
+    assert_float_result_bits_eq!(
+        0xfffffffffffff,
+        f64,
+        "2.225073858507201136057409796709131975934819546351645648023426109724822222021076945516529523908135087914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012981122451451889849057222307285255133155755015914397476397983411801999323962548289017107081850690630666655994938275772572015763062690663332647565300009245888316433037779791869612049497390377829704905051080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621572289880258182545180325707018860872113128079512233426288368622321503775666622503982534335974568884423900265498198385487948292206894721689831099698365846814022854243330660339850886445804001034933970427567186443383770486037861622771738545623065874679014086723327636718749999999999999999999999999999999999999e-308"
+    );
+    assert_float_result_bits_eq!(
+        0x10000000000000,
+        f64,
+        "2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901298112245145188984905722230728525513315575501591439747639798341180199932396254828901710708185069063066665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462157228988025818254518032570701886087211312807951223342628836862232150377566662250398253433597456888442390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042756718644338377048603786162277173854562306587467901408672332763671875e-308"
+    );
+    assert_float_result_bits_eq!(
+        0x10000000000000,
+        f64,
+        "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000222507385850720138309023271733240406421921598046233183055332741688720443481391819585428315901251102056406733973103581100515243416155346010885601238537771882113077799353200233047961014744258363607192156504694250373420837525080665061665815894872049117996859163964850063590877011830487479978088775374994945158045160505091539985658247081864511353793580499211598108576605199243335211435239014879569960959128889160299264151106346631339366347758651302937176204732563178148566435087212282863764204484681140761391147706280168985324411002416144742161856716615054015428508471675290190316132277889672970737312333408698898317506783884692609277397797285865965494109136909540613646756870239867831529068098461721092462539672851562500000000000000001"
+    );
+    assert_float_result_bits_eq!(
+        0x7fefffffffffffff,
+        f64,
+        "179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791.9999999999999999999999999999999999999999999999999999999999999999999999"
+    );
+    assert_float_result_bits_eq!(0x0, f64, "2.47032822920623272e-324");
+    assert_float_result_bits_eq!(
+        0x8000000,
+        f64,
+        "6.631236871469758276785396630275967243399099947355303144249971758736286630139265439618068200788048744105960420552601852889715006376325666595539603330361800519107591783233358492337208057849499360899425128640718856616503093444922854759159988160304439909868291973931426625698663157749836252274523485312442358651207051292453083278116143932569727918709786004497872322193856150225415211997283078496319412124640111777216148110752815101775295719811974338451936095907419622417538473679495148632480391435931767981122396703443803335529756003353209830071832230689201383015598792184172909927924176339315507402234836120730914783168400715462440053817592702766213559042115986763819482654128770595766806872783349146967171293949598850675682115696218943412532098591327667236328125E-316"
+    );
+    assert_float_result_bits_eq!(
+        0x10000,
+        f64,
+        "3.237883913302901289588352412501532174863037669423108059901297049552301970670676565786835742587799557860615776559838283435514391084153169252689190564396459577394618038928365305143463955100356696665629202017331344031730044369360205258345803431471660032699580731300954848363975548690010751530018881758184174569652173110473696022749934638425380623369774736560008997404060967498028389191878963968575439222206416981462690113342524002724385941651051293552601421155333430225237291523843322331326138431477823591142408800030775170625915670728657003151953664260769822494937951845801530895238439819708403389937873241463484205608000027270531106827387907791444918534771598750162812548862768493201518991668028251730299953143924168545708663913273994694463908672332763671875E-319"
+    );
+    assert_float_result_bits_eq!(
+        0x800000000100,
+        f64,
+        "6.953355807847677105972805215521891690222119817145950754416205607980030131549636688806115726399441880065386399864028691275539539414652831584795668560082999889551357784961446896042113198284213107935110217162654939802416034676213829409720583759540476786936413816541621287843248433202369209916612249676005573022703244799714622116542188837770376022371172079559125853382801396219552418839469770514904192657627060319372847562301074140442660237844114174497210955449896389180395827191602886654488182452409583981389442783377001505462015745017848754574668342161759496661766020028752888783387074850773192997102997936619876226688096314989645766000479009083731736585750335262099860150896718774401964796827166283225641992040747894382698751809812609536720628966577351093292236328125E-310"
+    );
+    assert_float_result_bits_eq!(
+        0x10800,
+        f64,
+        "3.339068557571188581835713701280943911923401916998521771655656997328440314559615318168849149074662609099998113009465566426808170378434065722991659642619467706034884424989741080790766778456332168200464651593995817371782125010668346652995912233993254584461125868481633343674905074271064409763090708017856584019776878812425312008812326260363035474811532236853359905334625575404216060622858633280744301892470300555678734689978476870369853549413277156622170245846166991655321535529623870646888786637528995592800436177901746286272273374471701452991433047257863864601424252024791567368195056077320885329384322332391564645264143400798619665040608077549162173963649264049738362290606875883456826586710961041737908872035803481241600376705491726170293986797332763671875E-319"
+    );
+    assert_float_result_bits_eq!(
+        0x0,
+        f64,
+        "2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328124999e-324"
+    );
+    assert_float_result_bits_eq!(
+        0x0,
+        f64,
+        "2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125e-324"
+    );
+    assert_float_result_bits_eq!(
+        0x1,
+        f64,
+        "2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125001e-324"
+    );
+    assert_float_result_bits_eq!(
+        0x1,
+        f64,
+        "7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984374999e-324"
+    );
+    assert_float_result_bits_eq!(
+        0x2,
+        f64,
+        "7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375e-324"
+    );
+    assert_float_result_bits_eq!(
+        0x2,
+        f64,
+        "7.4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375001e-324"
+    );
+    assert_float_result_bits_eq!(
+        0x6c9a143590c14,
+        f64,
+        "94393431193180696942841837085033647913224148539854e-358"
+    );
+    assert_float_result_bits_eq!(
+        0x7802665fd9600,
+        f64,
+        "104308485241983990666713401708072175773165034278685682646111762292409330928739751702404658197872319129036519947435319418387839758990478549477777586673075945844895981012024387992135617064532141489278815239849108105951619997829153633535314849999674266169258928940692239684771590065027025835804863585454872499320500023126142553932654370362024104462255244034053203998964360882487378334860197725139151265590832887433736189468858614521708567646743455601905935595381852723723645799866672558576993978025033590728687206296379801363024094048327273913079612469982585674824156000783167963081616214710691759864332339239688734656548790656486646106983450809073750535624894296242072010195710276073042036425579852459556183541199012652571123898996574563824424330960027873516082763671875e-1075"
+    );
+}
+
+#[test]
+fn many_digits() {
+    // Check large numbers of digits to ensure we have cases where significant
+    // digits (above Decimal::MAX_DIGITS) occurs.
+    assert_float_result_bits_eq!(
+        0x7ffffe,
+        f32,
+        "1.175494140627517859246175898662808184331245864732796240031385942718174675986064769972472277004271745681762695312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-38"
+    );
+    assert_float_result_bits_eq!(
+        0x7ffffe,
+        f32,
+        "1.175494140627517859246175898662808184331245864732796240031385942718174675986064769972472277004271745681762695312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-38"
+    );
 }
diff --git a/library/core/tests/num/dec2flt/rawfp.rs b/library/core/tests/num/dec2flt/rawfp.rs
deleted file mode 100644
index 34a37209d99..00000000000
--- a/library/core/tests/num/dec2flt/rawfp.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-use core::num::dec2flt::rawfp::RawFloat;
-use core::num::dec2flt::rawfp::{fp_to_float, next_float, prev_float, round_normal};
-use core::num::diy_float::Fp;
-
-fn integer_decode(f: f64) -> (u64, i16, i8) {
-    RawFloat::integer_decode(f)
-}
-
-#[test]
-fn fp_to_float_half_to_even() {
-    fn is_normalized(sig: u64) -> bool {
-        // intentionally written without {min,max}_sig() as a sanity check
-        sig >> 52 == 1 && sig >> 53 == 0
-    }
-
-    fn conv(sig: u64) -> u64 {
-        // The significands are perfectly in range, so the exponent should not matter
-        let (m1, e1, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 0 }));
-        assert_eq!(e1, 0 + 64 - 53);
-        let (m2, e2, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 55 }));
-        assert_eq!(e2, 55 + 64 - 53);
-        assert_eq!(m2, m1);
-        let (m3, e3, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: -78 }));
-        assert_eq!(e3, -78 + 64 - 53);
-        assert_eq!(m3, m2);
-        m3
-    }
-
-    let odd = 0x1F_EDCB_A012_345F;
-    let even = odd - 1;
-    assert!(is_normalized(odd));
-    assert!(is_normalized(even));
-    assert_eq!(conv(odd << 11), odd);
-    assert_eq!(conv(even << 11), even);
-    assert_eq!(conv(odd << 11 | 1 << 10), odd + 1);
-    assert_eq!(conv(even << 11 | 1 << 10), even);
-    assert_eq!(conv(even << 11 | 1 << 10 | 1), even + 1);
-    assert_eq!(conv(odd << 11 | 1 << 9), odd);
-    assert_eq!(conv(even << 11 | 1 << 9), even);
-    assert_eq!(conv(odd << 11 | 0x7FF), odd + 1);
-    assert_eq!(conv(even << 11 | 0x7FF), even + 1);
-    assert_eq!(conv(odd << 11 | 0x3FF), odd);
-    assert_eq!(conv(even << 11 | 0x3FF), even);
-}
-
-#[test]
-fn integers_to_f64() {
-    assert_eq!(fp_to_float::<f64>(Fp { f: 1, e: 0 }), 1.0);
-    assert_eq!(fp_to_float::<f64>(Fp { f: 42, e: 7 }), (42 << 7) as f64);
-    assert_eq!(fp_to_float::<f64>(Fp { f: 1 << 20, e: 30 }), (1u64 << 50) as f64);
-    assert_eq!(fp_to_float::<f64>(Fp { f: 4, e: -3 }), 0.5);
-}
-
-const SOME_FLOATS: [f64; 9] = [
-    0.1f64,
-    33.568,
-    42.1e-5,
-    777.0e9,
-    1.1111,
-    0.347997,
-    9843579834.35892,
-    12456.0e-150,
-    54389573.0e-150,
-];
-
-#[test]
-fn human_f64_roundtrip() {
-    for &x in &SOME_FLOATS {
-        let (f, e, _) = integer_decode(x);
-        let fp = Fp { f: f, e: e };
-        assert_eq!(fp_to_float::<f64>(fp), x);
-    }
-}
-
-#[test]
-fn rounding_overflow() {
-    let x = Fp { f: 0xFF_FF_FF_FF_FF_FF_FF_00u64, e: 42 };
-    let rounded = round_normal::<f64>(x);
-    let adjusted_k = x.e + 64 - 53;
-    assert_eq!(rounded.sig, 1 << 52);
-    assert_eq!(rounded.k, adjusted_k + 1);
-}
-
-#[test]
-fn prev_float_monotonic() {
-    let mut x = 1.0;
-    for _ in 0..100 {
-        let x1 = prev_float(x);
-        assert!(x1 < x);
-        assert!(x - x1 < 1e-15);
-        x = x1;
-    }
-}
-
-const MIN_SUBNORMAL: f64 = 5e-324;
-
-#[test]
-fn next_float_zero() {
-    let tiny = next_float(0.0);
-    assert_eq!(tiny, MIN_SUBNORMAL);
-    assert!(tiny != 0.0);
-}
-
-#[test]
-fn next_float_subnormal() {
-    let second = next_float(MIN_SUBNORMAL);
-    // For subnormals, MIN_SUBNORMAL is the ULP
-    assert!(second != MIN_SUBNORMAL);
-    assert!(second > 0.0);
-    assert_eq!(second - MIN_SUBNORMAL, MIN_SUBNORMAL);
-}
-
-#[test]
-fn next_float_inf() {
-    assert_eq!(next_float(f64::MAX), f64::INFINITY);
-    assert_eq!(next_float(f64::INFINITY), f64::INFINITY);
-}
-
-#[test]
-fn next_prev_identity() {
-    for &x in &SOME_FLOATS {
-        assert_eq!(prev_float(next_float(x)), x);
-        assert_eq!(prev_float(prev_float(next_float(next_float(x)))), x);
-        assert_eq!(next_float(prev_float(x)), x);
-        assert_eq!(next_float(next_float(prev_float(prev_float(x)))), x);
-    }
-}
-
-#[test]
-fn next_float_monotonic() {
-    let mut x = 0.49999999999999;
-    assert!(x < 0.5);
-    for _ in 0..200 {
-        let x1 = next_float(x);
-        assert!(x1 > x);
-        assert!(x1 - x < 1e-15, "next_float_monotonic: delta = {:?}", x1 - x);
-        x = x1;
-    }
-    assert!(x > 0.5);
-}
-
-#[test]
-fn test_f32_integer_decode() {
-    assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
-    assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
-    assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
-    assert_eq!(0f32.integer_decode(), (0, -150, 1));
-    assert_eq!((-0f32).integer_decode(), (0, -150, -1));
-    assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1));
-    assert_eq!(f32::NEG_INFINITY.integer_decode(), (8388608, 105, -1));
-
-    // Ignore the "sign" (quiet / signalling flag) of NAN.
-    // It can vary between runtime operations and LLVM folding.
-    let (nan_m, nan_e, _nan_s) = f32::NAN.integer_decode();
-    assert_eq!((nan_m, nan_e), (12582912, 105));
-}
-
-#[test]
-fn test_f64_integer_decode() {
-    assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
-    assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
-    assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
-    assert_eq!(0f64.integer_decode(), (0, -1075, 1));
-    assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
-    assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1));
-    assert_eq!(f64::NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
-
-    // Ignore the "sign" (quiet / signalling flag) of NAN.
-    // It can vary between runtime operations and LLVM folding.
-    let (nan_m, nan_e, _nan_s) = f64::NAN.integer_decode();
-    assert_eq!((nan_m, nan_e), (6755399441055744, 972));
-}
diff --git a/library/core/tests/num/flt2dec/mod.rs b/library/core/tests/num/flt2dec/mod.rs
index 960a7ca5ff5..4874e8ec09f 100644
--- a/library/core/tests/num/flt2dec/mod.rs
+++ b/library/core/tests/num/flt2dec/mod.rs
@@ -2,10 +2,11 @@ use std::mem::MaybeUninit;
 use std::{fmt, str};
 
 use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
-use core::num::flt2dec::{round_up, Formatted, Part, Sign, MAX_SIG_DIGITS};
+use core::num::flt2dec::{round_up, Sign, MAX_SIG_DIGITS};
 use core::num::flt2dec::{
     to_exact_exp_str, to_exact_fixed_str, to_shortest_exp_str, to_shortest_str,
 };
+use core::num::fmt::{Formatted, Part};
 
 pub use test::Bencher;
 
diff --git a/library/core/tests/num/int_log.rs b/library/core/tests/num/int_log.rs
new file mode 100644
index 00000000000..51122c11ce1
--- /dev/null
+++ b/library/core/tests/num/int_log.rs
@@ -0,0 +1,153 @@
+//! This tests the `Integer::{log,log2,log10}` methods. These tests are in a
+//! separate file because there's both a large number of them, and not all tests
+//! can be run on Android. This is because in Android `log2` uses an imprecise
+//! approximation:https://github.com/rust-lang/rust/blob/4825e12fc9c79954aa0fe18f5521efa6c19c7539/src/libstd/sys/unix/android.rs#L27-L53
+
+#[test]
+fn checked_log() {
+    assert_eq!(999u32.checked_log(10), Some(2));
+    assert_eq!(1000u32.checked_log(10), Some(3));
+    assert_eq!(555u32.checked_log(13), Some(2));
+    assert_eq!(63u32.checked_log(4), Some(2));
+    assert_eq!(64u32.checked_log(4), Some(3));
+    assert_eq!(10460353203u64.checked_log(3), Some(21));
+    assert_eq!(10460353202u64.checked_log(3), Some(20));
+    assert_eq!(147808829414345923316083210206383297601u128.checked_log(3), Some(80));
+    assert_eq!(147808829414345923316083210206383297600u128.checked_log(3), Some(79));
+    assert_eq!(22528399544939174411840147874772641u128.checked_log(19683), Some(8));
+    assert_eq!(22528399544939174411840147874772631i128.checked_log(19683), Some(7));
+
+    assert_eq!(0u8.checked_log(4), None);
+    assert_eq!(0u16.checked_log(4), None);
+    assert_eq!(0i8.checked_log(4), None);
+    assert_eq!(0i16.checked_log(4), None);
+
+    for i in i16::MIN..=0 {
+        assert_eq!(i.checked_log(4), None);
+    }
+    for i in 1..=i16::MAX {
+        assert_eq!(i.checked_log(13), Some((i as f32).log(13.0) as i16));
+    }
+    for i in 1..=u16::MAX {
+        assert_eq!(i.checked_log(13), Some((i as f32).log(13.0) as u16));
+    }
+}
+
+#[test]
+fn checked_log2() {
+    assert_eq!(5u32.checked_log2(), Some(2));
+    assert_eq!(0u64.checked_log2(), None);
+    assert_eq!(128i32.checked_log2(), Some(7));
+    assert_eq!((-55i16).checked_log2(), None);
+
+    assert_eq!(0u8.checked_log2(), None);
+    assert_eq!(0u16.checked_log2(), None);
+    assert_eq!(0i8.checked_log2(), None);
+    assert_eq!(0i16.checked_log2(), None);
+
+    for i in 1..=u8::MAX {
+        assert_eq!(i.checked_log2(), Some((i as f32).log2() as u8));
+    }
+    for i in 1..=u16::MAX {
+        // Guard against Android's imprecise f32::log2 implementation.
+        if i != 8192 && i != 32768 {
+            assert_eq!(i.checked_log2(), Some((i as f32).log2() as u16));
+        }
+    }
+    for i in i8::MIN..=0 {
+        assert_eq!(i.checked_log2(), None);
+    }
+    for i in 1..=i8::MAX {
+        assert_eq!(i.checked_log2(), Some((i as f32).log2() as i8));
+    }
+    for i in i16::MIN..=0 {
+        assert_eq!(i.checked_log2(), None);
+    }
+    for i in 1..=i16::MAX {
+        // Guard against Android's imprecise f32::log2 implementation.
+        if i != 8192 {
+            assert_eq!(i.checked_log2(), Some((i as f32).log2() as i16));
+        }
+    }
+}
+
+// Validate cases that fail on Android's imprecise float log2 implementation.
+#[test]
+#[cfg(not(target_os = "android"))]
+fn checked_log2_not_android() {
+    assert_eq!(8192u16.checked_log2(), Some((8192f32).log2() as u16));
+    assert_eq!(32768u16.checked_log2(), Some((32768f32).log2() as u16));
+    assert_eq!(8192i16.checked_log2(), Some((8192f32).log2() as i16));
+}
+
+#[test]
+fn checked_log10() {
+    assert_eq!(0u8.checked_log10(), None);
+    assert_eq!(0u16.checked_log10(), None);
+    assert_eq!(0i8.checked_log10(), None);
+    assert_eq!(0i16.checked_log10(), None);
+
+    for i in i16::MIN..=0 {
+        assert_eq!(i.checked_log10(), None);
+    }
+    for i in 1..=i16::MAX {
+        assert_eq!(i.checked_log10(), Some((i as f32).log10() as i16));
+    }
+    for i in 1..=u16::MAX {
+        assert_eq!(i.checked_log10(), Some((i as f32).log10() as u16));
+    }
+}
+
+macro_rules! log10_loop {
+    ($T:ty, $log10_max:expr) => {
+        assert_eq!(<$T>::MAX.log10(), $log10_max);
+        for i in 0..=$log10_max {
+            let p = (10 as $T).pow(i as u32);
+            if p >= 10 {
+                assert_eq!((p - 9).log10(), i - 1);
+                assert_eq!((p - 1).log10(), i - 1);
+            }
+            assert_eq!(p.log10(), i);
+            assert_eq!((p + 1).log10(), i);
+            if p >= 10 {
+                assert_eq!((p + 9).log10(), i);
+            }
+
+            // also check `x.log(10)`
+            if p >= 10 {
+                assert_eq!((p - 9).log(10), i - 1);
+                assert_eq!((p - 1).log(10), i - 1);
+            }
+            assert_eq!(p.log(10), i);
+            assert_eq!((p + 1).log(10), i);
+            if p >= 10 {
+                assert_eq!((p + 9).log(10), i);
+            }
+        }
+    };
+}
+
+#[test]
+fn log10_u8() {
+    log10_loop! { u8, 2 }
+}
+
+#[test]
+fn log10_u16() {
+    log10_loop! { u16, 4 }
+}
+
+#[test]
+fn log10_u32() {
+    log10_loop! { u32, 9 }
+}
+
+#[test]
+fn log10_u64() {
+    log10_loop! { u64, 19 }
+}
+
+#[test]
+fn log10_u128() {
+    log10_loop! { u128, 38 }
+}
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index bbb67667dfc..37b5e9127d5 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -27,8 +27,11 @@ mod u64;
 mod u8;
 
 mod bignum;
+
+mod const_from;
 mod dec2flt;
 mod flt2dec;
+mod int_log;
 mod ops;
 mod wrapping;
 
diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs
index 88ea15a3b33..cd8fdebe36a 100644
--- a/library/core/tests/option.rs
+++ b/library/core/tests/option.rs
@@ -399,7 +399,7 @@ fn test_unwrap_drop() {
 }
 
 #[test]
-pub fn option_ext() {
+fn option_ext() {
     let thing = "{{ f }}";
     let f = thing.find("{{");
 
@@ -407,3 +407,35 @@ pub fn option_ext() {
         println!("None!");
     }
 }
+
+#[test]
+fn zip_options() {
+    let x = Some(10);
+    let y = Some("foo");
+    let z: Option<usize> = None;
+
+    assert_eq!(x.zip(y), Some((10, "foo")));
+    assert_eq!(x.zip(z), None);
+    assert_eq!(z.zip(x), None);
+}
+
+#[test]
+fn unzip_options() {
+    let x = Some((10, "foo"));
+    let y = None::<(bool, i32)>;
+
+    assert_eq!(x.unzip(), (Some(10), Some("foo")));
+    assert_eq!(y.unzip(), (None, None));
+}
+
+#[test]
+fn zip_unzip_roundtrip() {
+    let x = Some(10);
+    let y = Some("foo");
+
+    let z = x.zip(y);
+    assert_eq!(z, Some((10, "foo")));
+
+    let a = z.unzip();
+    assert_eq!(a, (x, y));
+}
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index f4e5e7751b8..612f083a5c1 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -391,7 +391,6 @@ fn result_opt_conversions() {
 }
 
 #[test]
-#[cfg(not(bootstrap))] // Needs the V2 trait
 fn result_try_trait_v2_branch() {
     use core::num::NonZeroU32;
     use core::ops::{ControlFlow::*, Try};
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 3a98cd9d2ee..43e2af3eb18 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -135,6 +135,48 @@ fn test_partition_point() {
 }
 
 #[test]
+fn test_iterator_advance_by() {
+    let v = &[0, 1, 2, 3, 4];
+
+    for i in 0..=v.len() {
+        let mut iter = v.iter();
+        iter.advance_by(i).unwrap();
+        assert_eq!(iter.as_slice(), &v[i..]);
+    }
+
+    let mut iter = v.iter();
+    assert_eq!(iter.advance_by(v.len() + 1), Err(v.len()));
+    assert_eq!(iter.as_slice(), &[]);
+
+    let mut iter = v.iter();
+    iter.advance_by(3).unwrap();
+    assert_eq!(iter.as_slice(), &v[3..]);
+    iter.advance_by(2).unwrap();
+    assert_eq!(iter.as_slice(), &[]);
+}
+
+#[test]
+fn test_iterator_advance_back_by() {
+    let v = &[0, 1, 2, 3, 4];
+
+    for i in 0..=v.len() {
+        let mut iter = v.iter();
+        iter.advance_back_by(i).unwrap();
+        assert_eq!(iter.as_slice(), &v[..v.len() - i]);
+    }
+
+    let mut iter = v.iter();
+    assert_eq!(iter.advance_back_by(v.len() + 1), Err(v.len()));
+    assert_eq!(iter.as_slice(), &[]);
+
+    let mut iter = v.iter();
+    iter.advance_back_by(3).unwrap();
+    assert_eq!(iter.as_slice(), &v[..v.len() - 3]);
+    iter.advance_back_by(2).unwrap();
+    assert_eq!(iter.as_slice(), &[]);
+}
+
+#[test]
 fn test_iterator_nth() {
     let v: &[_] = &[0, 1, 2, 3, 4];
     for i in 0..v.len() {
@@ -697,6 +739,10 @@ fn test_array_windows_count() {
     let v3: &[i32] = &[];
     let c3 = v3.array_windows::<2>();
     assert_eq!(c3.count(), 0);
+
+    let v4: &[()] = &[(); usize::MAX];
+    let c4 = v4.array_windows::<1>();
+    assert_eq!(c4.count(), usize::MAX);
 }
 
 #[test]
@@ -1008,6 +1054,10 @@ fn test_windows_count() {
     let v3: &[i32] = &[];
     let c3 = v3.windows(2);
     assert_eq!(c3.count(), 0);
+
+    let v4 = &[(); usize::MAX];
+    let c4 = v4.windows(1);
+    assert_eq!(c4.count(), usize::MAX);
 }
 
 #[test]
diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml
index bdab664cd64..6dec0e67497 100644
--- a/library/panic_abort/Cargo.toml
+++ b/library/panic_abort/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "panic_abort"
 version = "0.0.0"
 license = "MIT OR Apache-2.0"
diff --git a/library/panic_abort/src/android.rs b/library/panic_abort/src/android.rs
index 34d77502eab..18bb932f10e 100644
--- a/library/panic_abort/src/android.rs
+++ b/library/panic_abort/src/android.rs
@@ -7,7 +7,7 @@ const ANDROID_SET_ABORT_MESSAGE: &[u8] = b"android_set_abort_message\0";
 type SetAbortMessageType = unsafe extern "C" fn(*const libc::c_char) -> ();
 
 // Forward the abort message to libc's android_set_abort_message. We try our best to populate the
-// message but as this function may already be called as part of a failed allocation, it may not be
+// message but as this function may already be called as part of a failed allocation, it might not be
 // possible to do so.
 //
 // Some methods of core are on purpose avoided (such as try_reserve) as these rely on the correct
diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index d95ea6530c2..4580f9a7758 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -15,6 +15,7 @@
 #![feature(staged_api)]
 #![feature(rustc_attrs)]
 #![feature(asm)]
+#![feature(c_unwind)]
 
 #[cfg(target_os = "android")]
 mod android;
@@ -30,7 +31,7 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen
 
 // "Leak" the payload and shim to the relevant abort on the platform in question.
 #[rustc_std_internal_symbol]
-pub unsafe extern "C" fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 {
+pub unsafe extern "C-unwind" fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 {
     // Android has the ability to attach a message as part of the abort.
     #[cfg(target_os = "android")]
     android::android_set_abort_message(_payload);
diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml
index 533f059a85e..67405463aa6 100644
--- a/library/panic_unwind/Cargo.toml
+++ b/library/panic_unwind/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "panic_unwind"
 version = "0.0.0"
 license = "MIT OR Apache-2.0"
diff --git a/library/panic_unwind/src/dwarf/eh.rs b/library/panic_unwind/src/dwarf/eh.rs
index 6dbf7c11b4c..7394feab82f 100644
--- a/library/panic_unwind/src/dwarf/eh.rs
+++ b/library/panic_unwind/src/dwarf/eh.rs
@@ -1,9 +1,9 @@
 //! Parsing of GCC-style Language-Specific Data Area (LSDA)
 //! For details see:
-//!  * <http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html>
-//!  * <http://mentorembedded.github.io/cxx-abi/exceptions.pdf>
-//!  * <http://www.airs.com/blog/archives/460>
-//!  * <http://www.airs.com/blog/archives/464>
+//!  * <https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html>
+//!  * <https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf>
+//!  * <https://www.airs.com/blog/archives/460>
+//!  * <https://www.airs.com/blog/archives/464>
 //!
 //! A reference implementation may be found in the GCC source tree
 //! (`<root>/libgcc/unwind-c.c` as of this writing).
diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs
index 14f49bbf483..9d6ede73e3d 100644
--- a/library/panic_unwind/src/gcc.rs
+++ b/library/panic_unwind/src/gcc.rs
@@ -5,8 +5,8 @@
 //! documents linked from it.
 //! These are also good reads:
 //!  * <https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html>
-//!  * <http://monoinfinito.wordpress.com/series/exception-handling-in-c/>
-//!  * <http://www.airs.com/blog/index.php?s=exception+frames>
+//!  * <https://monoinfinito.wordpress.com/series/exception-handling-in-c/>
+//!  * <https://www.airs.com/blog/index.php?s=exception+frames>
 //!
 //! ## A brief summary
 //!
@@ -94,7 +94,7 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
 // and TargetLowering::getExceptionSelectorRegister() for each architecture,
 // then mapped to DWARF register numbers via register definition tables
 // (typically <arch>RegisterInfo.td, search for "DwarfRegNum").
-// See also http://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register.
+// See also https://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register.
 
 #[cfg(target_arch = "x86")]
 const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX
@@ -130,7 +130,7 @@ const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11
 cfg_if::cfg_if! {
     if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "netbsd")))] {
         // ARM EHABI personality routine.
-        // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
+        // https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
         //
         // iOS uses the default routine instead since it uses SjLj unwinding.
         #[lang = "eh_personality"]
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index d32a3f1f832..ac7d8c18e3e 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -20,12 +20,11 @@
 #![feature(panic_unwind)]
 #![feature(staged_api)]
 #![feature(std_internals)]
-#![feature(unwind_attributes)]
 #![feature(abi_thiscall)]
 #![feature(rustc_attrs)]
-#![feature(raw)]
 #![panic_runtime]
 #![feature(panic_runtime)]
+#![feature(c_unwind)]
 // `real_imp` is unused with Miri, so silence warnings.
 #![cfg_attr(miri, allow(dead_code))]
 
@@ -46,7 +45,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(any(
         all(target_family = "windows", target_env = "gnu"),
         target_os = "psp",
-        target_family = "unix",
+        all(target_family = "unix", not(target_os = "espidf")),
         all(target_vendor = "fortanix", target_env = "sgx"),
     ))] {
         // Rust runtime's startup objects depend on these symbols, so make them public.
@@ -59,6 +58,7 @@ cfg_if::cfg_if! {
         // - arch=wasm32
         // - os=none ("bare metal" targets)
         // - os=uefi
+        // - os=espidf
         // - nvptx64-nvidia-cuda
         // - arch=avr
         #[path = "dummy.rs"]
@@ -99,8 +99,7 @@ pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any
 // Entry point for raising an exception, just delegates to the platform-specific
 // implementation.
 #[rustc_std_internal_symbol]
-#[unwind(allowed)]
-pub unsafe extern "C" fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32 {
+pub unsafe extern "C-unwind" fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32 {
     let payload = Box::from_raw((*payload).take_box());
 
     imp::panic(payload)
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 58028d40576..9f1eb411ff6 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -42,7 +42,7 @@
 //!   of the `try` intrinsic.
 //!
 //! [win64]: https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64
-//! [llvm]: http://llvm.org/docs/ExceptionHandling.html#background-on-windows-exceptions
+//! [llvm]: https://llvm.org/docs/ExceptionHandling.html#background-on-windows-exceptions
 
 #![allow(nonstandard_style)]
 
@@ -100,7 +100,7 @@ struct Exception {
 // In any case, these structures are all constructed in a similar manner, and
 // it's just somewhat verbose for us.
 //
-// [1]: http://www.geoffchappell.com/studies/msvc/language/predefined/
+// [1]: https://www.geoffchappell.com/studies/msvc/language/predefined/
 
 #[cfg(target_arch = "x86")]
 #[macro_use]
@@ -233,15 +233,14 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
 // support capturing exceptions with std::exception_ptr, which we can't support
 // because Box<dyn Any> isn't clonable.
 macro_rules! define_cleanup {
-    ($abi:tt) => {
+    ($abi:tt $abi2:tt) => {
         unsafe extern $abi fn exception_cleanup(e: *mut Exception) {
             if let Exception { data: Some(b) } = e.read() {
                 drop(b);
                 super::__rust_drop_panic();
             }
         }
-        #[unwind(allowed)]
-        unsafe extern $abi fn exception_copy(_dest: *mut Exception,
+        unsafe extern $abi2 fn exception_copy(_dest: *mut Exception,
                                              _src: *mut Exception)
                                              -> *mut Exception {
             panic!("Rust panics cannot be copied");
@@ -250,9 +249,9 @@ macro_rules! define_cleanup {
 }
 cfg_if::cfg_if! {
    if #[cfg(target_arch = "x86")] {
-       define_cleanup!("thiscall");
+       define_cleanup!("thiscall" "thiscall-unwind");
    } else {
-       define_cleanup!("C");
+       define_cleanup!("C" "C-unwind");
    }
 }
 
@@ -307,8 +306,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
         ptr!(exception_copy) as u32,
     );
 
-    extern "system" {
-        #[unwind(allowed)]
+    extern "system-unwind" {
         fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8) -> !;
     }
 
diff --git a/library/proc_macro/Cargo.toml b/library/proc_macro/Cargo.toml
index 9cc9ef4ec19..faf460e32bd 100644
--- a/library/proc_macro/Cargo.toml
+++ b/library/proc_macro/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "proc_macro"
 version = "0.0.0"
 edition = "2018"
diff --git a/library/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs
index 717201aef10..d82669d3e23 100644
--- a/library/proc_macro/src/bridge/buffer.rs
+++ b/library/proc_macro/src/bridge/buffer.rs
@@ -6,35 +6,6 @@ use std::ops::{Deref, DerefMut};
 use std::slice;
 
 #[repr(C)]
-struct Slice<'a, T> {
-    data: &'a [T; 0],
-    len: usize,
-}
-
-unsafe impl<'a, T: Sync> Sync for Slice<'a, T> {}
-unsafe impl<'a, T: Sync> Send for Slice<'a, T> {}
-
-impl<T> Copy for Slice<'a, T> {}
-impl<T> Clone for Slice<'a, T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-impl<T> From<&'a [T]> for Slice<'a, T> {
-    fn from(xs: &'a [T]) -> Self {
-        Slice { data: unsafe { &*(xs.as_ptr() as *const [T; 0]) }, len: xs.len() }
-    }
-}
-
-impl<T> Deref for Slice<'a, T> {
-    type Target = [T];
-    fn deref(&self) -> &[T] {
-        unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) }
-    }
-}
-
-#[repr(C)]
 pub struct Buffer<T: Copy> {
     data: *mut T,
     len: usize,
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index c6bec5a6fbd..8ae7b6de1a6 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -386,7 +386,7 @@ fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
             //
             // Note that panics should be impossible beyond this point, but
             // this is defensively trying to avoid any accidental panicking
-            // reaching the `extern "C"` (which should `abort` but may not
+            // reaching the `extern "C"` (which should `abort` but might not
             // at the moment, so this is also potentially preventing UB).
             b.clear();
             Ok::<_, ()>(output).encode(&mut b, &mut ());
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index a2953b68564..7001e827ad8 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -55,6 +55,7 @@ macro_rules! with_api {
             FreeFunctions {
                 fn drop($self: $S::FreeFunctions);
                 fn track_env_var(var: &str, value: Option<&str>);
+                fn track_path(path: &str);
             },
             TokenStream {
                 fn drop($self: $S::TokenStream);
@@ -108,6 +109,7 @@ macro_rules! with_api {
                 fn drop($self: $S::Literal);
                 fn clone($self: &$S::Literal) -> $S::Literal;
                 fn from_str(s: &str) -> Result<$S::Literal, ()>;
+                fn to_string($self: &$S::Literal) -> String;
                 fn debug_kind($self: &$S::Literal) -> String;
                 fn symbol($self: &$S::Literal) -> String;
                 fn suffix($self: &$S::Literal) -> Option<String>;
diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs
index 588e6ded0f4..42432563faf 100644
--- a/library/proc_macro/src/bridge/rpc.rs
+++ b/library/proc_macro/src/bridge/rpc.rs
@@ -246,7 +246,7 @@ impl<S> DecodeMut<'_, '_, S> for String {
     }
 }
 
-/// Simplied version of panic payloads, ignoring
+/// Simplified version of panic payloads, ignoring
 /// types other than `&'static str` and `String`.
 pub enum PanicMessage {
     StaticStr(&'static str),
diff --git a/library/proc_macro/src/diagnostic.rs b/library/proc_macro/src/diagnostic.rs
index 7495468a05b..6e46dc0367d 100644
--- a/library/proc_macro/src/diagnostic.rs
+++ b/library/proc_macro/src/diagnostic.rs
@@ -56,10 +56,9 @@ pub struct Diagnostic {
 
 macro_rules! diagnostic_child_methods {
     ($spanned:ident, $regular:ident, $level:expr) => {
-        /// Adds a new child diagnostic message to `self` with the level
-        /// identified by this method's name with the given `spans` and
-        /// `message`.
         #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
+        #[doc = concat!("Adds a new child diagnostics message to `self` with the [`",
+                        stringify!($level), "`] level, and the given `spans` and `message`.")]
         pub fn $spanned<S, T>(mut self, spans: S, message: T) -> Diagnostic
         where
             S: MultiSpan,
@@ -69,9 +68,9 @@ macro_rules! diagnostic_child_methods {
             self
         }
 
-        /// Adds a new child diagnostic message to `self` with the level
-        /// identified by this method's name with the given `message`.
         #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
+        #[doc = concat!("Adds a new child diagnostic message to `self` with the [`",
+                        stringify!($level), "`] level, and the given `message`.")]
         pub fn $regular<T: Into<String>>(mut self, message: T) -> Diagnostic {
             self.children.push(Diagnostic::new($level, message));
             self
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 3990826ce42..f25e257bf31 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -43,7 +43,7 @@ mod diagnostic;
 pub use diagnostic::{Diagnostic, Level, MultiSpan};
 
 use std::cmp::Ordering;
-use std::ops::{Bound, RangeBounds};
+use std::ops::RangeBounds;
 use std::path::PathBuf;
 use std::str::FromStr;
 use std::{error, fmt, iter, mem};
@@ -84,14 +84,13 @@ impl !Sync for TokenStream {}
 
 /// Error returned from `TokenStream::from_str`.
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
+#[non_exhaustive]
 #[derive(Debug)]
-pub struct LexError {
-    _inner: (),
-}
+pub struct LexError;
 
 impl LexError {
     fn new() -> Self {
-        LexError { _inner: () }
+        LexError
     }
 }
 
@@ -349,13 +348,13 @@ impl Span {
     /// Gets the starting line/column in the source file for this span.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn start(&self) -> LineColumn {
-        self.0.start()
+        self.0.start().add_1_to_column()
     }
 
     /// Gets the ending line/column in the source file for this span.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn end(&self) -> LineColumn {
-        self.0.end()
+        self.0.end().add_1_to_column()
     }
 
     /// Creates a new span encompassing `self` and `other`.
@@ -433,12 +432,18 @@ pub struct LineColumn {
     /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub line: usize,
-    /// The 0-indexed column (in UTF-8 characters) in the source file on which
-    /// the span starts or ends (inclusive).
+    /// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
+    /// file on which the span starts or ends (inclusive).
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub column: usize,
 }
 
+impl LineColumn {
+    fn add_1_to_column(self) -> Self {
+        LineColumn { line: self.line, column: self.column + 1 }
+    }
+}
+
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 impl !Send for LineColumn {}
 #[unstable(feature = "proc_macro_span", issue = "54725")]
@@ -468,10 +473,10 @@ impl SourceFile {
     ///
     /// ### Note
     /// If the code span associated with this `SourceFile` was generated by an external macro, this
-    /// macro, this may not be an actual path on the filesystem. Use [`is_real`] to check.
+    /// macro, this might not be an actual path on the filesystem. Use [`is_real`] to check.
     ///
     /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
-    /// the command line, the path as given may not actually be valid.
+    /// the command line, the path as given might not actually be valid.
     ///
     /// [`is_real`]: Self::is_real
     #[unstable(feature = "proc_macro_span", issue = "54725")]
@@ -658,7 +663,7 @@ pub enum Delimiter {
     /// An implicit delimiter, that may, for example, appear around tokens coming from a
     /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
     /// `$var * 3` where `$var` is `1 + 2`.
-    /// Implicit delimiters may not survive roundtrip of a token stream through a string.
+    /// Implicit delimiters might not survive roundtrip of a token stream through a string.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     None,
 }
@@ -707,7 +712,7 @@ impl Group {
     /// pub fn span_open(&self) -> Span {
     ///                 ^
     /// ```
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
     pub fn span_open(&self) -> Span {
         Span(self.0.span_open())
     }
@@ -718,7 +723,7 @@ impl Group {
     /// pub fn span_close(&self) -> Span {
     ///                        ^
     /// ```
-    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    #[stable(feature = "proc_macro_group_span", since = "1.55.0")]
     pub fn span_close(&self) -> Span {
         Span(self.0.span_close())
     }
@@ -765,7 +770,7 @@ impl fmt::Debug for Group {
     }
 }
 
-/// An `Punct` is an single punctuation character like `+`, `-` or `#`.
+/// A `Punct` is a single punctuation character such as `+`, `-` or `#`.
 ///
 /// Multi-character operators like `+=` are represented as two instances of `Punct` with different
 /// forms of `Spacing` returned.
@@ -778,16 +783,19 @@ impl !Send for Punct {}
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Sync for Punct {}
 
-/// Whether an `Punct` is followed immediately by another `Punct` or
-/// followed by another token or whitespace.
+/// Describes whether a `Punct` is followed immediately by another `Punct` ([`Spacing::Joint`]) or
+/// by a different token or whitespace ([`Spacing::Alone`]).
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 pub enum Spacing {
-    /// e.g., `+` is `Alone` in `+ =`, `+ident` or `+()`.
+    /// A `Punct` is not immediately followed by another `Punct`.
+    /// E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     Alone,
-    /// e.g., `+` is `Joint` in `+=` or `'#`.
-    /// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`.
+    /// A `Punct` is immediately followed by another `Punct`.
+    /// E.g. `+` is `Joint` in `+=` and `++`.
+    ///
+    /// Additionally, single quote `'` can join with identifiers to form lifetimes: `'ident`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     Joint,
 }
@@ -971,7 +979,7 @@ macro_rules! suffixed_int_literals {
         /// This function will create an integer like `1u32` where the integer
         /// value specified is the first part of the token and the integral is
         /// also suffixed at the end.
-        /// Literals created from negative numbers may not survive round-trips through
+        /// Literals created from negative numbers might not survive round-trips through
         /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
         ///
         /// Literals created through this method have the `Span::call_site()`
@@ -993,7 +1001,7 @@ macro_rules! unsuffixed_int_literals {
         /// specified on this token, meaning that invocations like
         /// `Literal::i8_unsuffixed(1)` are equivalent to
         /// `Literal::u32_unsuffixed(1)`.
-        /// Literals created from negative numbers may not survive rountrips through
+        /// Literals created from negative numbers might not survive rountrips through
         /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
         ///
         /// Literals created through this method have the `Span::call_site()`
@@ -1042,7 +1050,7 @@ impl Literal {
     /// This constructor is similar to those like `Literal::i8_unsuffixed` where
     /// the float's value is emitted directly into the token but no suffix is
     /// used, so it may be inferred to be a `f64` later in the compiler.
-    /// Literals created from negative numbers may not survive rountrips through
+    /// Literals created from negative numbers might not survive rountrips through
     /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
     ///
     /// # Panics
@@ -1063,7 +1071,7 @@ impl Literal {
     /// specified is the preceding part of the token and `f32` is the suffix of
     /// the token. This token will always be inferred to be an `f32` in the
     /// compiler.
-    /// Literals created from negative numbers may not survive rountrips through
+    /// Literals created from negative numbers might not survive rountrips through
     /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
     ///
     /// # Panics
@@ -1083,7 +1091,7 @@ impl Literal {
     /// This constructor is similar to those like `Literal::i8_unsuffixed` where
     /// the float's value is emitted directly into the token but no suffix is
     /// used, so it may be inferred to be a `f64` later in the compiler.
-    /// Literals created from negative numbers may not survive rountrips through
+    /// Literals created from negative numbers might not survive rountrips through
     /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
     ///
     /// # Panics
@@ -1104,7 +1112,7 @@ impl Literal {
     /// specified is the preceding part of the token and `f64` is the suffix of
     /// the token. This token will always be inferred to be an `f64` in the
     /// compiler.
-    /// Literals created from negative numbers may not survive rountrips through
+    /// Literals created from negative numbers might not survive rountrips through
     /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
     ///
     /// # Panics
@@ -1162,16 +1170,7 @@ impl Literal {
     // was 'c' or whether it was '\u{63}'.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
-        // HACK(eddyb) something akin to `Option::cloned`, but for `Bound<&T>`.
-        fn cloned_bound<T: Clone>(bound: Bound<&T>) -> Bound<T> {
-            match bound {
-                Bound::Included(x) => Bound::Included(x.clone()),
-                Bound::Excluded(x) => Bound::Excluded(x.clone()),
-                Bound::Unbounded => Bound::Unbounded,
-            }
-        }
-
-        self.0.subspan(cloned_bound(range.start_bound()), cloned_bound(range.end_bound())).map(Span)
+        self.0.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
     }
 }
 
@@ -1202,7 +1201,7 @@ impl FromStr for Literal {
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl ToString for Literal {
     fn to_string(&self) -> String {
-        TokenStream::from(TokenTree::from(self.clone())).to_string()
+        self.0.to_string()
     }
 }
 
@@ -1241,3 +1240,17 @@ pub mod tracked_env {
         value
     }
 }
+
+/// Tracked access to additional files.
+#[unstable(feature = "track_path", issue = "73921")]
+pub mod tracked_path {
+
+    /// Track a file explicitly.
+    ///
+    /// Commonly used for tracking asset preprocessing.
+    #[unstable(feature = "track_path", issue = "73921")]
+    pub fn path<P: AsRef<str>>(path: P) {
+        let path: &str = path.as_ref();
+        crate::bridge::client::FreeFunctions::track_path(path);
+    }
+}
diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml
index 7b7ca8029b4..0f7f0067652 100644
--- a/library/profiler_builtins/Cargo.toml
+++ b/library/profiler_builtins/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "profiler_builtins"
 version = "0.0.0"
 edition = "2018"
@@ -14,4 +13,4 @@ core = { path = "../core" }
 compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] }
 
 [build-dependencies]
-cc = "1.0.68"
+cc = "1.0.69"
diff --git a/library/rustc-std-workspace-alloc/Cargo.toml b/library/rustc-std-workspace-alloc/Cargo.toml
index 810197afd31..1ea421834a7 100644
--- a/library/rustc-std-workspace-alloc/Cargo.toml
+++ b/library/rustc-std-workspace-alloc/Cargo.toml
@@ -1,7 +1,6 @@
 [package]
 name = "rustc-std-workspace-alloc"
 version = "1.99.0"
-authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = 'MIT OR Apache-2.0'
 description = """
 Hack for the compiler's own build system
diff --git a/library/rustc-std-workspace-core/Cargo.toml b/library/rustc-std-workspace-core/Cargo.toml
index a386ec2b43a..01e8b92e149 100644
--- a/library/rustc-std-workspace-core/Cargo.toml
+++ b/library/rustc-std-workspace-core/Cargo.toml
@@ -1,7 +1,6 @@
 [package]
 name = "rustc-std-workspace-core"
 version = "1.99.0"
-authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = 'MIT OR Apache-2.0'
 description = """
 Hack for the compiler's own build system
diff --git a/library/rustc-std-workspace-std/Cargo.toml b/library/rustc-std-workspace-std/Cargo.toml
index ed6765556cc..811bc78d210 100644
--- a/library/rustc-std-workspace-std/Cargo.toml
+++ b/library/rustc-std-workspace-std/Cargo.toml
@@ -1,7 +1,6 @@
 [package]
 name = "rustc-std-workspace-std"
 version = "1.99.0"
-authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = 'MIT OR Apache-2.0'
 description = """
 Hack for the compiler's own build system
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 415d874c7fa..7e260aaa428 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "std"
 version = "0.0.0"
 license = "MIT OR Apache-2.0"
@@ -16,7 +15,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core" }
-libc = { version = "0.2.93", default-features = false, features = ['rustc-dep-of-std'] }
+libc = { version = "0.2.99", default-features = false, features = ['rustc-dep-of-std'] }
 compiler_builtins = { version = "0.1.44" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
@@ -43,7 +42,7 @@ dlmalloc = { version = "0.2.1", features = ['rustc-dep-of-std'] }
 fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_os = "hermit"))'.dependencies]
-hermit-abi = { version = "0.1.17", features = ['rustc-dep-of-std'] }
+hermit-abi = { version = "0.1.19", features = ['rustc-dep-of-std'] }
 
 [target.wasm32-wasi.dependencies]
 wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features = false }
diff --git a/library/std/build.rs b/library/std/build.rs
index a14ac63c7a8..726157c1f1a 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -26,6 +26,7 @@ fn main() {
         || target.contains("vxworks")
         || target.contains("wasm32")
         || target.contains("asmjs")
+        || target.contains("espidf")
     {
         // These platforms don't have any special requirements.
     } else {
diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs
index 0aae4674b29..9ace3e1b600 100644
--- a/library/std/src/backtrace.rs
+++ b/library/std/src/backtrace.rs
@@ -35,13 +35,13 @@
 //! `BacktraceStatus` enum as a result of `Backtrace::status`.
 //!
 //! Like above with accuracy platform support is done on a best effort basis.
-//! Sometimes libraries may not be available at runtime or something may go
+//! Sometimes libraries might not be available at runtime or something may go
 //! wrong which would cause a backtrace to not be captured. Please feel free to
 //! report issues with platforms where a backtrace cannot be captured though!
 //!
 //! ## Environment Variables
 //!
-//! The `Backtrace::capture` function may not actually capture a backtrace by
+//! The `Backtrace::capture` function might not actually capture a backtrace by
 //! default. Its behavior is governed by two environment variables:
 //!
 //! * `RUST_LIB_BACKTRACE` - if this is set to `0` then `Backtrace::capture`
@@ -61,7 +61,7 @@
 //! Note that the `Backtrace::force_capture` function can be used to ignore
 //! these environment variables. Also note that the state of environment
 //! variables is cached once the first backtrace is created, so altering
-//! `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` at runtime may not actually change
+//! `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` at runtime might not actually change
 //! how backtraces are captured.
 
 #![unstable(feature = "backtrace", issue = "53487")]
@@ -399,12 +399,11 @@ impl fmt::Display for Backtrace {
         let mut f = backtrace_rs::BacktraceFmt::new(fmt, style, &mut print_path);
         f.add_context()?;
         for frame in frames {
-            let mut f = f.frame();
             if frame.symbols.is_empty() {
-                f.print_raw(frame.frame.ip(), None, None, None)?;
+                f.frame().print_raw(frame.frame.ip(), None, None, None)?;
             } else {
                 for symbol in frame.symbols.iter() {
-                    f.print_raw_with_column(
+                    f.frame().print_raw_with_column(
                         frame.frame.ip(),
                         symbol.name.as_ref().map(|b| backtrace_rs::SymbolName::new(b)),
                         symbol.filename.as_ref().map(|b| match b {
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index a1f52a9c2e8..7e8da13239c 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 #[cfg(test)]
 mod tests;
 
@@ -10,6 +8,7 @@ use hashbrown::hash_map as base;
 use crate::borrow::Borrow;
 use crate::cell::Cell;
 use crate::collections::TryReserveError;
+use crate::collections::TryReserveErrorKind;
 use crate::fmt::{self, Debug};
 #[allow(deprecated)]
 use crate::hash::{BuildHasher, Hash, Hasher, SipHasher13};
@@ -124,8 +123,21 @@ use crate::sys;
 /// }
 /// ```
 ///
-/// `HashMap` also implements an [`Entry API`](#method.entry), which allows
-/// for more complex methods of getting, setting, updating and removing keys and
+/// A `HashMap` with a known list of items can be initialized from an array:
+///
+/// ```
+/// use std::collections::HashMap;
+///
+/// let solar_distance = HashMap::from([
+///     ("Mercury", 0.4),
+///     ("Venus", 0.7),
+///     ("Earth", 1.0),
+///     ("Mars", 1.5),
+/// ]);
+/// ```
+///
+/// `HashMap` implements an [`Entry API`](#method.entry), which allows
+/// for complex methods of getting, setting, updating and removing keys and
 /// their values:
 ///
 /// ```
@@ -179,27 +191,17 @@ use crate::sys;
 /// }
 ///
 /// // Use a HashMap to store the vikings' health points.
-/// let mut vikings = HashMap::new();
-///
-/// vikings.insert(Viking::new("Einar", "Norway"), 25);
-/// vikings.insert(Viking::new("Olaf", "Denmark"), 24);
-/// vikings.insert(Viking::new("Harald", "Iceland"), 12);
+/// let vikings = HashMap::from([
+///     (Viking::new("Einar", "Norway"), 25),
+///     (Viking::new("Olaf", "Denmark"), 24),
+///     (Viking::new("Harald", "Iceland"), 12),
+/// ]);
 ///
 /// // Use derived implementation to print the status of the vikings.
 /// for (viking, health) in &vikings {
 ///     println!("{:?} has {} hp", viking, health);
 /// }
 /// ```
-///
-/// A `HashMap` with fixed list of elements can be initialized from an array:
-///
-/// ```
-/// use std::collections::HashMap;
-///
-/// let timber_resources: HashMap<&str, i32> = [("Norway", 100), ("Denmark", 50), ("Iceland", 10)]
-///     .iter().cloned().collect();
-/// // use the values stored in map
-/// ```
 
 #[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_type")]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -454,7 +456,6 @@ impl<K, V, S> HashMap<K, V, S> {
     /// a.insert(1, "a");
     /// assert_eq!(a.len(), 1);
     /// ```
-    #[doc(alias = "length")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize {
         self.base.len()
@@ -666,7 +667,6 @@ where
     /// # Examples
     ///
     /// ```
-    /// #![feature(shrink_to)]
     /// use std::collections::HashMap;
     ///
     /// let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
@@ -679,7 +679,7 @@ where
     /// assert!(map.capacity() >= 2);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.base.shrink_to(min_capacity);
     }
@@ -893,7 +893,6 @@ where
     /// assert_eq!(map.remove(&1), Some("a"));
     /// assert_eq!(map.remove(&1), None);
     /// ```
-    #[doc(alias = "delete")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
@@ -936,6 +935,7 @@ where
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
+    /// The elements are visited in unsorted (and unspecified) order.
     ///
     /// # Examples
     ///
@@ -1149,6 +1149,37 @@ where
     }
 }
 
+#[stable(feature = "std_collections_from_array", since = "1.56.0")]
+// Note: as what is currently the most convenient built-in way to construct
+// a HashMap, a simple usage of this function must not *require* the user
+// to provide a type annotation in order to infer the third type parameter
+// (the hasher parameter, conventionally "S").
+// To that end, this impl is defined using RandomState as the concrete
+// type of S, rather than being generic over `S: BuildHasher + Default`.
+// It is expected that users who want to specify a hasher will manually use
+// `with_capacity_and_hasher`.
+// If type parameter defaults worked on impls, and if type parameter
+// defaults could be mixed with const generics, then perhaps
+// this could be generalized.
+// See also the equivalent impl on HashSet.
+impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, RandomState>
+where
+    K: Eq + Hash,
+{
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let map1 = HashMap::from([(1, 2), (3, 4)]);
+    /// let map2: HashMap<_, _> = [(1, 2), (3, 4)].into();
+    /// assert_eq!(map1, map2);
+    /// ```
+    fn from(arr: [(K, V); N]) -> Self {
+        crate::array::IntoIter::new(arr).collect()
+    }
+}
+
 /// An iterator over the entries of a `HashMap`.
 ///
 /// This `struct` is created by the [`iter`] method on [`HashMap`]. See its
@@ -1831,6 +1862,7 @@ impl<K, V, S> Debug for RawEntryBuilder<'_, K, V, S> {
 ///
 /// [`entry`]: HashMap::entry
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "HashMapEntry")]
 pub enum Entry<'a, K: 'a, V: 'a> {
     /// An occupied entry.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -2787,15 +2819,7 @@ where
 
     #[inline]
     fn extend_reserve(&mut self, additional: usize) {
-        // self.base.extend_reserve(additional);
-        // FIXME: hashbrown should implement this method.
-        // But until then, use the same reservation logic:
-
-        // Reserve the entire hint lower bound if the map is empty.
-        // Otherwise reserve half the hint (rounded up), so the map
-        // will only resize twice in the worst case.
-        let reserve = if self.is_empty() { additional } else { (additional + 1) / 2 };
-        self.base.reserve(reserve);
+        self.base.extend_reserve(additional);
     }
 }
 
@@ -2966,9 +2990,11 @@ fn map_entry<'a, K: 'a, V: 'a>(raw: base::RustcEntry<'a, K, V>) -> Entry<'a, K,
 #[inline]
 pub(super) fn map_try_reserve_error(err: hashbrown::TryReserveError) -> TryReserveError {
     match err {
-        hashbrown::TryReserveError::CapacityOverflow => TryReserveError::CapacityOverflow,
+        hashbrown::TryReserveError::CapacityOverflow => {
+            TryReserveErrorKind::CapacityOverflow.into()
+        }
         hashbrown::TryReserveError::AllocError { layout } => {
-            TryReserveError::AllocError { layout, non_exhaustive: () }
+            TryReserveErrorKind::AllocError { layout, non_exhaustive: () }.into()
         }
     }
 }
diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs
index 819be142227..d9b20aee2d2 100644
--- a/library/std/src/collections/hash/map/tests.rs
+++ b/library/std/src/collections/hash/map/tests.rs
@@ -1,9 +1,10 @@
 use super::Entry::{Occupied, Vacant};
 use super::HashMap;
 use super::RandomState;
+use crate::assert_matches::assert_matches;
 use crate::cell::RefCell;
 use rand::{thread_rng, Rng};
-use realstd::collections::TryReserveError::*;
+use realstd::collections::TryReserveErrorKind::*;
 
 // https://github.com/rust-lang/rust/issues/62301
 fn _assert_hashmap_is_unwind_safe() {
@@ -821,15 +822,17 @@ fn test_try_reserve() {
 
     const MAX_USIZE: usize = usize::MAX;
 
-    if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) {
-    } else {
-        panic!("usize::MAX should trigger an overflow!");
-    }
-
-    if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) {
-    } else {
-        panic!("usize::MAX / 8 should trigger an OOM!")
-    }
+    assert_matches!(
+        empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+        Err(CapacityOverflow),
+        "usize::MAX should trigger an overflow!"
+    );
+
+    assert_matches!(
+        empty_bytes.try_reserve(MAX_USIZE / 8).map_err(|e| e.kind()),
+        Err(AllocError { .. }),
+        "usize::MAX / 8 should trigger an OOM!"
+    );
 }
 
 #[test]
@@ -1085,3 +1088,15 @@ mod test_drain_filter {
         assert_eq!(map.len(), 2);
     }
 }
+
+#[test]
+fn from_array() {
+    let map = HashMap::from([(1, 2), (3, 4)]);
+    let unordered_duplicates = HashMap::from([(3, 4), (1, 2), (1, 2)]);
+    assert_eq!(map, unordered_duplicates);
+
+    // This next line must infer the hasher type parameter.
+    // If you make a change that causes this line to no longer infer,
+    // that's a problem!
+    let _must_not_require_type_annotation = HashMap::from([(1, 2)]);
+}
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index 5220c8ad709..3b61acd122e 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -95,14 +95,12 @@ use super::map::{map_try_reserve_error, RandomState};
 /// }
 /// ```
 ///
-/// A `HashSet` with fixed list of elements can be initialized from an array:
+/// A `HashSet` with a known list of items can be initialized from an array:
 ///
 /// ```
 /// use std::collections::HashSet;
 ///
-/// let viking_names: HashSet<&'static str> =
-///     [ "Einar", "Olaf", "Harald" ].iter().cloned().collect();
-/// // use the values stored in the set
+/// let viking_names = HashSet::from(["Einar", "Olaf", "Harald"]);
 /// ```
 ///
 /// [hash set]: crate::collections#use-the-set-variant-of-any-of-these-maps-when
@@ -202,7 +200,6 @@ impl<T, S> HashSet<T, S> {
     /// v.insert(1);
     /// assert_eq!(v.len(), 1);
     /// ```
-    #[doc(alias = "length")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize {
@@ -467,7 +464,6 @@ where
     /// # Examples
     ///
     /// ```
-    /// #![feature(shrink_to)]
     /// use std::collections::HashSet;
     ///
     /// let mut set = HashSet::with_capacity(100);
@@ -480,7 +476,7 @@ where
     /// assert!(set.capacity() >= 2);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.base.shrink_to(min_capacity)
     }
@@ -875,7 +871,6 @@ where
     /// assert_eq!(set.remove(&2), true);
     /// assert_eq!(set.remove(&2), false);
     /// ```
-    #[doc(alias = "delete")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
@@ -914,6 +909,7 @@ where
     /// Retains only the elements specified by the predicate.
     ///
     /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+    /// The elements are visited in unsorted (and unspecified) order.
     ///
     /// # Examples
     ///
@@ -998,6 +994,37 @@ where
     }
 }
 
+#[stable(feature = "std_collections_from_array", since = "1.56.0")]
+// Note: as what is currently the most convenient built-in way to construct
+// a HashSet, a simple usage of this function must not *require* the user
+// to provide a type annotation in order to infer the third type parameter
+// (the hasher parameter, conventionally "S").
+// To that end, this impl is defined using RandomState as the concrete
+// type of S, rather than being generic over `S: BuildHasher + Default`.
+// It is expected that users who want to specify a hasher will manually use
+// `with_capacity_and_hasher`.
+// If type parameter defaults worked on impls, and if type parameter
+// defaults could be mixed with const generics, then perhaps
+// this could be generalized.
+// See also the equivalent impl on HashMap.
+impl<T, const N: usize> From<[T; N]> for HashSet<T, RandomState>
+where
+    T: Eq + Hash,
+{
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let set1 = HashSet::from([1, 2, 3, 4]);
+    /// let set2: HashSet<_> = [1, 2, 3, 4].into();
+    /// assert_eq!(set1, set2);
+    /// ```
+    fn from(arr: [T; N]) -> Self {
+        crate::array::IntoIter::new(arr).collect()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, S> Extend<T> for HashSet<T, S>
 where
diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs
index 40f8467fd93..6a625e6243c 100644
--- a/library/std/src/collections/hash/set/tests.rs
+++ b/library/std/src/collections/hash/set/tests.rs
@@ -484,3 +484,15 @@ fn test_drain_filter_pred_panic_leak() {
     assert_eq!(DROPS.load(Ordering::SeqCst), 3);
     assert_eq!(set.len(), 0);
 }
+
+#[test]
+fn from_array() {
+    let set = HashSet::from([1, 2, 3, 4]);
+    let unordered_duplicates = HashSet::from([4, 1, 4, 3, 2]);
+    assert_eq!(set, unordered_duplicates);
+
+    // This next line must infer the hasher type parameter.
+    // If you make a change that causes this line to no longer infer,
+    // that's a problem!
+    let _must_not_require_type_annotation = HashSet::from([1, 2]);
+}
diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs
index 8cda601edd1..130bb5cb2b3 100644
--- a/library/std/src/collections/mod.rs
+++ b/library/std/src/collections/mod.rs
@@ -422,6 +422,12 @@ pub use self::hash_set::HashSet;
 
 #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
 pub use alloc_crate::collections::TryReserveError;
+#[unstable(
+    feature = "try_reserve_kind",
+    reason = "Uncertain how much info should be exposed",
+    issue = "48043"
+)]
+pub use alloc_crate::collections::TryReserveErrorKind;
 
 mod hash;
 
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 4403280efc1..a7465200955 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -185,15 +185,13 @@ impl fmt::Debug for VarsOs {
 ///
 /// # Errors
 ///
-/// Errors if the environment variable is not present.
-/// Errors if the environment variable is not valid Unicode. If this is not desired, consider using
-/// [`var_os`].
+/// This function will return an error if the environment variable isn't set.
 ///
-/// # Panics
+/// This function may return an error if the environment variable's name contains
+/// the equal sign character (`=`) or the NUL character.
 ///
-/// This function may panic if `key` is empty, contains an ASCII equals sign
-/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
-/// character.
+/// This function will return an error if the environment variable's value is
+/// not valid Unicode. If this is not desired, consider using [`var_os`].
 ///
 /// # Examples
 ///
@@ -219,18 +217,22 @@ fn _var(key: &OsStr) -> Result<String, VarError> {
 }
 
 /// Fetches the environment variable `key` from the current process, returning
-/// [`None`] if the variable isn't set.
-///
-/// # Panics
-///
-/// This function may panic if `key` is empty, contains an ASCII equals sign
-/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
-/// character.
+/// [`None`] if the variable isn't set or there's another error.
 ///
 /// Note that the method will not check if the environment variable
 /// is valid Unicode. If you want to have an error on invalid UTF-8,
 /// use the [`var`] function instead.
 ///
+/// # Errors
+///
+/// This function returns an error if the environment variable isn't set.
+///
+/// This function may return an error if the environment variable's name contains
+/// the equal sign character (`=`) or the NUL character.
+///
+/// This function may return an error if the environment variable's value contains
+/// the NUL character.
+///
 /// # Examples
 ///
 /// ```
@@ -249,7 +251,6 @@ pub fn var_os<K: AsRef<OsStr>>(key: K) -> Option<OsString> {
 
 fn _var_os(key: &OsStr) -> Option<OsString> {
     os_imp::getenv(key)
-        .unwrap_or_else(|e| panic!("failed to get environment variable `{:?}`: {}", key, e))
 }
 
 /// The error type for operations interacting with environment variables.
@@ -294,7 +295,7 @@ impl Error for VarError {
     }
 }
 
-/// Sets the environment variable `k` to the value `v` for the currently running
+/// Sets the environment variable `key` to the value `value` for the currently running
 /// process.
 ///
 /// Note that while concurrent access to environment variables is safe in Rust,
@@ -305,14 +306,13 @@ impl Error for VarError {
 ///
 /// Discussion of this unsafety on Unix may be found in:
 ///
-///  - [Austin Group Bugzilla](http://austingroupbugs.net/view.php?id=188)
+///  - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
 ///  - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
 ///
 /// # Panics
 ///
-/// This function may panic if `key` is empty, contains an ASCII equals sign
-/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
-/// character.
+/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
+/// or the NUL character `'\0'`, or when `value` contains the NUL character.
 ///
 /// # Examples
 ///
@@ -344,7 +344,7 @@ fn _set_var(key: &OsStr, value: &OsStr) {
 ///
 /// Discussion of this unsafety on Unix may be found in:
 ///
-///  - [Austin Group Bugzilla](http://austingroupbugs.net/view.php?id=188)
+///  - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
 ///  - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
 ///
 /// # Panics
@@ -683,7 +683,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 /// for more.
 ///
 /// The first element is traditionally the path of the executable, but it can be
-/// set to arbitrary text, and may not even exist. This means this property
+/// set to arbitrary text, and might not even exist. This means this property
 /// should not be relied upon for security purposes.
 ///
 /// [`env::args()`]: args
@@ -699,7 +699,7 @@ pub struct Args {
 /// for more.
 ///
 /// The first element is traditionally the path of the executable, but it can be
-/// set to arbitrary text, and may not even exist. This means this property
+/// set to arbitrary text, and might not even exist. This means this property
 /// should not be relied upon for security purposes.
 ///
 /// [`env::args_os()`]: args_os
@@ -712,7 +712,7 @@ pub struct ArgsOs {
 /// via the command line).
 ///
 /// The first element is traditionally the path of the executable, but it can be
-/// set to arbitrary text, and may not even exist. This means this property should
+/// set to arbitrary text, and might not even exist. This means this property should
 /// not be relied upon for security purposes.
 ///
 /// On Unix systems the shell usually expands unquoted arguments with glob patterns
@@ -749,7 +749,7 @@ pub fn args() -> Args {
 /// via the command line).
 ///
 /// The first element is traditionally the path of the executable, but it can be
-/// set to arbitrary text, and may not even exist. This means this property should
+/// set to arbitrary text, and might not even exist. This means this property should
 /// not be relied upon for security purposes.
 ///
 /// On Unix systems the shell usually expands unquoted arguments with glob patterns
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index 14c2f961d32..ec9f0122950 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -597,6 +597,9 @@ impl Error for char::ParseCharError {
 #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
 impl Error for alloc::collections::TryReserveError {}
 
+#[unstable(feature = "duration_checked_float", issue = "83400")]
+impl Error for core::time::FromSecsError {}
+
 // Copied from `any.rs`.
 impl dyn Error + 'static {
     /// Returns `true` if the boxed type is the same as `T`
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index c16d27fa1f5..0b392897f9d 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -324,18 +324,20 @@ impl f32 {
 
     /// Returns the square root of a number.
     ///
-    /// Returns NaN if `self` is a negative number.
+    /// Returns NaN if `self` is a negative number other than `-0.0`.
     ///
     /// # Examples
     ///
     /// ```
     /// let positive = 4.0_f32;
     /// let negative = -4.0_f32;
+    /// let negative_zero = -0.0_f32;
     ///
     /// let abs_difference = (positive.sqrt() - 2.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// assert!(negative.sqrt().is_nan());
+    /// assert!(negative_zero.sqrt() == negative_zero);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -407,7 +409,7 @@ impl f32 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
     ///
-    /// The result may not be correctly rounded owing to implementation details;
+    /// The result might not be correctly rounded owing to implementation details;
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
     ///
@@ -876,4 +878,40 @@ impl f32 {
     pub fn atanh(self) -> f32 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
+
+    /// Linear interpolation between `start` and `end`.
+    ///
+    /// This enables linear interpolation between `start` and `end`, where start is represented by
+    /// `self == 0.0` and `end` is represented by `self == 1.0`. This is the basis of all
+    /// "transition", "easing", or "step" functions; if you change `self` from 0.0 to 1.0
+    /// at a given rate, the result will change from `start` to `end` at a similar rate.
+    ///
+    /// Values below 0.0 or above 1.0 are allowed, allowing you to extrapolate values outside the
+    /// range from `start` to `end`. This also is useful for transition functions which might
+    /// move slightly past the end or start for a desired effect. Mathematically, the values
+    /// returned are equivalent to `start + self * (end - start)`, although we make a few specific
+    /// guarantees that are useful specifically to linear interpolation.
+    ///
+    /// These guarantees are:
+    ///
+    /// * If `start` and `end` are [finite], the value at 0.0 is always `start` and the
+    ///   value at 1.0 is always `end`. (exactness)
+    /// * If `start` and `end` are [finite], the values will always move in the direction from
+    ///   `start` to `end` (monotonicity)
+    /// * If `self` is [finite] and `start == end`, the value at any point will always be
+    ///   `start == end`. (consistency)
+    ///
+    /// [finite]: #method.is_finite
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_interpolation", issue = "86269")]
+    pub fn lerp(self, start: f32, end: f32) -> f32 {
+        // consistent
+        if start == end {
+            start
+
+        // exact/monotonic
+        } else {
+            self.mul_add(end, (-self).mul_add(start, start))
+        }
+    }
 }
diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs
index 0d4b865f339..fe66a73afd6 100644
--- a/library/std/src/f32/tests.rs
+++ b/library/std/src/f32/tests.rs
@@ -757,3 +757,66 @@ fn test_total_cmp() {
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f32::INFINITY));
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
 }
+
+#[test]
+fn test_lerp_exact() {
+    // simple values
+    assert_eq!(f32::lerp(0.0, 2.0, 4.0), 2.0);
+    assert_eq!(f32::lerp(1.0, 2.0, 4.0), 4.0);
+
+    // boundary values
+    assert_eq!(f32::lerp(0.0, f32::MIN, f32::MAX), f32::MIN);
+    assert_eq!(f32::lerp(1.0, f32::MIN, f32::MAX), f32::MAX);
+}
+
+#[test]
+fn test_lerp_consistent() {
+    assert_eq!(f32::lerp(f32::MAX, f32::MIN, f32::MIN), f32::MIN);
+    assert_eq!(f32::lerp(f32::MIN, f32::MAX, f32::MAX), f32::MAX);
+
+    // as long as t is finite, a/b can be infinite
+    assert_eq!(f32::lerp(f32::MAX, f32::NEG_INFINITY, f32::NEG_INFINITY), f32::NEG_INFINITY);
+    assert_eq!(f32::lerp(f32::MIN, f32::INFINITY, f32::INFINITY), f32::INFINITY);
+}
+
+#[test]
+fn test_lerp_nan_infinite() {
+    // non-finite t is not NaN if a/b different
+    assert!(!f32::lerp(f32::INFINITY, f32::MIN, f32::MAX).is_nan());
+    assert!(!f32::lerp(f32::NEG_INFINITY, f32::MIN, f32::MAX).is_nan());
+}
+
+#[test]
+fn test_lerp_values() {
+    // just a few basic values
+    assert_eq!(f32::lerp(0.25, 1.0, 2.0), 1.25);
+    assert_eq!(f32::lerp(0.50, 1.0, 2.0), 1.50);
+    assert_eq!(f32::lerp(0.75, 1.0, 2.0), 1.75);
+}
+
+#[test]
+fn test_lerp_monotonic() {
+    // near 0
+    let below_zero = f32::lerp(-f32::EPSILON, f32::MIN, f32::MAX);
+    let zero = f32::lerp(0.0, f32::MIN, f32::MAX);
+    let above_zero = f32::lerp(f32::EPSILON, f32::MIN, f32::MAX);
+    assert!(below_zero <= zero);
+    assert!(zero <= above_zero);
+    assert!(below_zero <= above_zero);
+
+    // near 0.5
+    let below_half = f32::lerp(0.5 - f32::EPSILON, f32::MIN, f32::MAX);
+    let half = f32::lerp(0.5, f32::MIN, f32::MAX);
+    let above_half = f32::lerp(0.5 + f32::EPSILON, f32::MIN, f32::MAX);
+    assert!(below_half <= half);
+    assert!(half <= above_half);
+    assert!(below_half <= above_half);
+
+    // near 1
+    let below_one = f32::lerp(1.0 - f32::EPSILON, f32::MIN, f32::MAX);
+    let one = f32::lerp(1.0, f32::MIN, f32::MAX);
+    let above_one = f32::lerp(1.0 + f32::EPSILON, f32::MIN, f32::MAX);
+    assert!(below_one <= one);
+    assert!(one <= above_one);
+    assert!(below_one <= above_one);
+}
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 4c95df5ffe0..602cceb5d1a 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -324,18 +324,20 @@ impl f64 {
 
     /// Returns the square root of a number.
     ///
-    /// Returns NaN if `self` is a negative number.
+    /// Returns NaN if `self` is a negative number other than `-0.0`.
     ///
     /// # Examples
     ///
     /// ```
     /// let positive = 4.0_f64;
     /// let negative = -4.0_f64;
+    /// let negative_zero = -0.0_f64;
     ///
     /// let abs_difference = (positive.sqrt() - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// assert!(negative.sqrt().is_nan());
+    /// assert!(negative_zero.sqrt() == negative_zero);
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -407,7 +409,7 @@ impl f64 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
     ///
-    /// The result may not be correctly rounded owing to implementation details;
+    /// The result might not be correctly rounded owing to implementation details;
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
     ///
@@ -879,6 +881,42 @@ impl f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
 
+    /// Linear interpolation between `start` and `end`.
+    ///
+    /// This enables linear interpolation between `start` and `end`, where start is represented by
+    /// `self == 0.0` and `end` is represented by `self == 1.0`. This is the basis of all
+    /// "transition", "easing", or "step" functions; if you change `self` from 0.0 to 1.0
+    /// at a given rate, the result will change from `start` to `end` at a similar rate.
+    ///
+    /// Values below 0.0 or above 1.0 are allowed, allowing you to extrapolate values outside the
+    /// range from `start` to `end`. This also is useful for transition functions which might
+    /// move slightly past the end or start for a desired effect. Mathematically, the values
+    /// returned are equivalent to `start + self * (end - start)`, although we make a few specific
+    /// guarantees that are useful specifically to linear interpolation.
+    ///
+    /// These guarantees are:
+    ///
+    /// * If `start` and `end` are [finite], the value at 0.0 is always `start` and the
+    ///   value at 1.0 is always `end`. (exactness)
+    /// * If `start` and `end` are [finite], the values will always move in the direction from
+    ///   `start` to `end` (monotonicity)
+    /// * If `self` is [finite] and `start == end`, the value at any point will always be
+    ///   `start == end`. (consistency)
+    ///
+    /// [finite]: #method.is_finite
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_interpolation", issue = "86269")]
+    pub fn lerp(self, start: f64, end: f64) -> f64 {
+        // consistent
+        if start == end {
+            start
+
+        // exact/monotonic
+        } else {
+            self.mul_add(end, (-self).mul_add(start, start))
+        }
+    }
+
     // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
     // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
     // of expected NaN).
diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs
index 5c163cfe90e..04cb0109261 100644
--- a/library/std/src/f64/tests.rs
+++ b/library/std/src/f64/tests.rs
@@ -753,3 +753,58 @@ fn test_total_cmp() {
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f64::INFINITY));
     assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan()));
 }
+
+#[test]
+fn test_lerp_exact() {
+    // simple values
+    assert_eq!(f64::lerp(0.0, 2.0, 4.0), 2.0);
+    assert_eq!(f64::lerp(1.0, 2.0, 4.0), 4.0);
+
+    // boundary values
+    assert_eq!(f64::lerp(0.0, f64::MIN, f64::MAX), f64::MIN);
+    assert_eq!(f64::lerp(1.0, f64::MIN, f64::MAX), f64::MAX);
+}
+
+#[test]
+fn test_lerp_consistent() {
+    assert_eq!(f64::lerp(f64::MAX, f64::MIN, f64::MIN), f64::MIN);
+    assert_eq!(f64::lerp(f64::MIN, f64::MAX, f64::MAX), f64::MAX);
+
+    // as long as t is finite, a/b can be infinite
+    assert_eq!(f64::lerp(f64::MAX, f64::NEG_INFINITY, f64::NEG_INFINITY), f64::NEG_INFINITY);
+    assert_eq!(f64::lerp(f64::MIN, f64::INFINITY, f64::INFINITY), f64::INFINITY);
+}
+
+#[test]
+fn test_lerp_nan_infinite() {
+    // non-finite t is not NaN if a/b different
+    assert!(!f64::lerp(f64::INFINITY, f64::MIN, f64::MAX).is_nan());
+    assert!(!f64::lerp(f64::NEG_INFINITY, f64::MIN, f64::MAX).is_nan());
+}
+
+#[test]
+fn test_lerp_values() {
+    // just a few basic values
+    assert_eq!(f64::lerp(0.25, 1.0, 2.0), 1.25);
+    assert_eq!(f64::lerp(0.50, 1.0, 2.0), 1.50);
+    assert_eq!(f64::lerp(0.75, 1.0, 2.0), 1.75);
+}
+
+#[test]
+fn test_lerp_monotonic() {
+    // near 0
+    let below_zero = f64::lerp(-f64::EPSILON, f64::MIN, f64::MAX);
+    let zero = f64::lerp(0.0, f64::MIN, f64::MAX);
+    let above_zero = f64::lerp(f64::EPSILON, f64::MIN, f64::MAX);
+    assert!(below_zero <= zero);
+    assert!(zero <= above_zero);
+    assert!(below_zero <= above_zero);
+
+    // near 1
+    let below_one = f64::lerp(1.0 - f64::EPSILON, f64::MIN, f64::MAX);
+    let one = f64::lerp(1.0, f64::MIN, f64::MAX);
+    let above_one = f64::lerp(1.0 + f64::EPSILON, f64::MIN, f64::MAX);
+    assert!(below_one <= one);
+    assert!(one <= above_one);
+    assert!(below_one <= above_one);
+}
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index 0184495eecf..0b7dc256db8 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -124,8 +124,8 @@
 //! method is an [`OsString`] which can be round-tripped to a Windows
 //! string losslessly.
 //!
-//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
-//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
+//! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
+//! [Unicode code point]: https://www.unicode.org/glossary/#code_point
 //! [`env::set_var()`]: crate::env::set_var
 //! [`env::var_os()`]: crate::env::var_os
 //! [unix.OsStringExt]: crate::os::unix::ffi::OsStringExt
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index ca391ffb3d5..8f4cd6c691c 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -271,7 +271,9 @@ impl OsString {
     ///
     /// Note that the allocator may give the collection more space than it
     /// requests. Therefore, capacity can not be relied upon to be precisely
-    /// minimal. Prefer reserve if future insertions are expected.
+    /// minimal. Prefer [`reserve`] if future insertions are expected.
+    ///
+    /// [`reserve`]: OsString::reserve
     ///
     /// # Examples
     ///
@@ -319,7 +321,6 @@ impl OsString {
     /// # Examples
     ///
     /// ```
-    /// #![feature(shrink_to)]
     /// use std::ffi::OsString;
     ///
     /// let mut s = OsString::from("foo");
@@ -333,7 +334,7 @@ impl OsString {
     /// assert!(s.capacity() >= 3);
     /// ```
     #[inline]
-    #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.inner.shrink_to(min_capacity)
     }
@@ -694,7 +695,6 @@ impl OsStr {
     /// let os_str = OsStr::new("foo");
     /// assert_eq!(os_str.len(), 3);
     /// ```
-    #[doc(alias = "length")]
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
     #[inline]
     pub fn len(&self) -> usize {
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index a1636e2f604..2c04481c04e 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -88,6 +88,7 @@ use crate::time::SystemTime;
 /// [`BufReader<R>`]: io::BufReader
 /// [`sync_all`]: File::sync_all
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "File")]
 pub struct File {
     inner: fs_imp::File,
 }
@@ -183,12 +184,14 @@ pub struct Permissions(fs_imp::FilePermissions);
 /// It is returned by [`Metadata::file_type`] method.
 #[stable(feature = "file_type", since = "1.1.0")]
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "FileType")]
 pub struct FileType(fs_imp::FileType);
 
 /// A builder used to create directories in various manners.
 ///
 /// This builder also supports platform-specific options.
 #[stable(feature = "dir_builder", since = "1.6.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "DirBuilder")]
 #[derive(Debug)]
 pub struct DirBuilder {
     inner: fs_imp::DirBuilder,
@@ -416,7 +419,7 @@ impl File {
         self.inner.fsync()
     }
 
-    /// This function is similar to [`sync_all`], except that it may not
+    /// This function is similar to [`sync_all`], except that it might not
     /// synchronize file metadata to the filesystem.
     ///
     /// This is intended for use cases that must synchronize content, but don't
@@ -880,8 +883,7 @@ impl OpenOptions {
     /// This function will return an error under a number of different
     /// circumstances. Some of these error conditions are listed here, together
     /// with their [`io::ErrorKind`]. The mapping to [`io::ErrorKind`]s is not
-    /// part of the compatibility contract of the function, especially the
-    /// [`Other`] kind might change to more specific kinds in the future.
+    /// part of the compatibility contract of the function.
     ///
     /// * [`NotFound`]: The specified file does not exist and neither `create`
     ///   or `create_new` is set.
@@ -895,9 +897,11 @@ impl OpenOptions {
     ///   exists.
     /// * [`InvalidInput`]: Invalid combinations of open options (truncate
     ///   without write access, no access mode set, etc.).
-    /// * [`Other`]: One of the directory components of the specified file path
+    ///
+    /// The following errors don't match any existing [`io::ErrorKind`] at the moment:
+    /// * One of the directory components of the specified file path
     ///   was not, in fact, a directory.
-    /// * [`Other`]: Filesystem-level errors: full disk, write permission
+    /// * Filesystem-level errors: full disk, write permission
     ///   requested on a read-only file system, exceeded disk quota, too many
     ///   open files, too long filename, too many symbolic links in the
     ///   specified path (Unix-like systems only), etc.
@@ -913,7 +917,6 @@ impl OpenOptions {
     /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists
     /// [`InvalidInput`]: io::ErrorKind::InvalidInput
     /// [`NotFound`]: io::ErrorKind::NotFound
-    /// [`Other`]: io::ErrorKind::Other
     /// [`PermissionDenied`]: io::ErrorKind::PermissionDenied
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
@@ -1007,6 +1010,32 @@ impl Metadata {
         self.file_type().is_file()
     }
 
+    /// Returns `true` if this metadata is for a symbolic link.
+    ///
+    /// # Examples
+    ///
+    #[cfg_attr(unix, doc = "```no_run")]
+    #[cfg_attr(not(unix), doc = "```ignore")]
+    /// #![feature(is_symlink)]
+    /// use std::fs;
+    /// use std::path::Path;
+    /// use std::os::unix::fs::symlink;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let link_path = Path::new("link");
+    ///     symlink("/origin_does_not_exists/", link_path)?;
+    ///
+    ///     let metadata = fs::symlink_metadata(link_path)?;
+    ///
+    ///     assert!(metadata.is_symlink());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "is_symlink", issue = "85748")]
+    pub fn is_symlink(&self) -> bool {
+        self.file_type().is_symlink()
+    }
+
     /// Returns the size of the file, in bytes, this metadata is for.
     ///
     /// # Examples
@@ -1052,7 +1081,7 @@ impl Metadata {
     ///
     /// # Errors
     ///
-    /// This field may not be available on all platforms, and will return an
+    /// This field might not be available on all platforms, and will return an
     /// `Err` on platforms where it is not available.
     ///
     /// # Examples
@@ -1087,7 +1116,7 @@ impl Metadata {
     ///
     /// # Errors
     ///
-    /// This field may not be available on all platforms, and will return an
+    /// This field might not be available on all platforms, and will return an
     /// `Err` on platforms where it is not available.
     ///
     /// # Examples
@@ -1119,7 +1148,7 @@ impl Metadata {
     ///
     /// # Errors
     ///
-    /// This field may not be available on all platforms, and will return an
+    /// This field might not be available on all platforms, and will return an
     /// `Err` on platforms or filesystems where it is not available.
     ///
     /// # Examples
@@ -1525,7 +1554,6 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 ///     Ok(())
 /// }
 /// ```
-#[doc(alias = "delete")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
     fs_imp::unlink(path.as_ref())
@@ -1711,8 +1739,11 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
 ///
 /// # Platform-specific behavior
 ///
-/// This function currently corresponds to the `linkat` function with no flags
-/// on Unix and the `CreateHardLink` function on Windows.
+/// This function currently corresponds the `CreateHardLink` function on Windows.
+/// On most Unix systems, it corresponds to the `linkat` function with no flags.
+/// On Android, VxWorks, and Redox, it instead corresponds to the `link` function.
+/// On MacOS, it uses the `linkat` function if it is available, but on very old
+/// systems where `linkat` is not available, `link` is selected at runtime instead.
 /// Note that, this [may change in the future][changes].
 ///
 /// [changes]: io#platform-specific-behavior
@@ -1881,6 +1912,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 ///     Ok(())
 /// }
 /// ```
+#[doc(alias = "mkdir")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
     DirBuilder::new().create(path.as_ref())
@@ -1960,7 +1992,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///     Ok(())
 /// }
 /// ```
-#[doc(alias = "delete")]
+#[doc(alias = "rmdir")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
     fs_imp::rmdir(path.as_ref())
@@ -1998,7 +2030,6 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///     Ok(())
 /// }
 /// ```
-#[doc(alias = "delete")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
     fs_imp::remove_dir_all(path.as_ref())
@@ -2008,6 +2039,8 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// The iterator will yield instances of [`io::Result`]`<`[`DirEntry`]`>`.
 /// New errors may be encountered after an iterator is initially constructed.
+/// Entries for the current and parent directories (typically `.` and `..`) are
+/// skipped.
 ///
 /// # Platform-specific behavior
 ///
@@ -2190,7 +2223,7 @@ impl DirBuilder {
             Some(p) => self.create_dir_all(p)?,
             None => {
                 return Err(io::Error::new_const(
-                    io::ErrorKind::Other,
+                    io::ErrorKind::Uncategorized,
                     &"failed to create whole tree",
                 ));
             }
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index ce8d3a56f7a..13dbae3b7b5 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -19,6 +19,10 @@ use crate::os::unix::fs::symlink as symlink_junction;
 use crate::os::windows::fs::{symlink_dir, symlink_file};
 #[cfg(windows)]
 use crate::sys::fs::symlink_junction;
+#[cfg(target_os = "macos")]
+use crate::sys::weak::weak;
+#[cfg(target_os = "macos")]
+use libc::{c_char, c_int};
 
 macro_rules! check {
     ($e:expr) => {
@@ -79,6 +83,17 @@ pub fn got_symlink_permission(tmpdir: &TempDir) -> bool {
     }
 }
 
+#[cfg(target_os = "macos")]
+fn able_to_not_follow_symlinks_while_hard_linking() -> bool {
+    weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int);
+    linkat.get().is_some()
+}
+
+#[cfg(not(target_os = "macos"))]
+fn able_to_not_follow_symlinks_while_hard_linking() -> bool {
+    return true;
+}
+
 #[test]
 fn file_test_io_smoke_test() {
     let message = "it's alright. have a good time";
@@ -809,7 +824,7 @@ fn symlink_noexist() {
     };
 
     // Use a relative path for testing. Symlinks get normalized by Windows,
-    // so we may not get the same path back for absolute paths
+    // so we might not get the same path back for absolute paths
     check!(symlink_file(&"foo", &tmpdir.join("bar")));
     assert_eq!(check!(fs::read_link(&tmpdir.join("bar"))).to_str().unwrap(), "foo");
 }
@@ -1329,7 +1344,8 @@ fn metadata_access_times() {
         match (a.created(), b.created()) {
             (Ok(t1), Ok(t2)) => assert!(t1 <= t2),
             (Err(e1), Err(e2))
-                if e1.kind() == ErrorKind::Other && e2.kind() == ErrorKind::Other
+                if e1.kind() == ErrorKind::Uncategorized
+                    && e2.kind() == ErrorKind::Uncategorized
                     || e1.kind() == ErrorKind::Unsupported
                         && e2.kind() == ErrorKind::Unsupported => {}
             (a, b) => {
@@ -1346,6 +1362,9 @@ fn symlink_hard_link() {
     if !got_symlink_permission(&tmpdir) {
         return;
     };
+    if !able_to_not_follow_symlinks_while_hard_linking() {
+        return;
+    }
 
     // Create "file", a file.
     check!(fs::File::create(tmpdir.join("file")));
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index d8021d3e99a..32d194d9616 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -438,7 +438,13 @@ impl<R: Seek> Seek for BufReader<R> {
 }
 
 impl<T> SizeHint for BufReader<T> {
+    #[inline]
     fn lower_bound(&self) -> usize {
-        self.buffer().len()
+        SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
+    }
+
+    #[inline]
+    fn upper_bound(&self) -> Option<usize> {
+        SizeHint::upper_bound(self.get_ref()).and_then(|up| self.buffer().len().checked_add(up))
     }
 }
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index ef2769d431f..9da5fbff9cf 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -68,7 +68,7 @@ use crate::ptr;
 /// [`flush`]: BufWriter::flush
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufWriter<W: Write> {
-    inner: Option<W>,
+    inner: W,
     // The buffer. Avoid using this like a normal `Vec` in common code paths.
     // That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
     // methods that require bounds checking or the like. This makes an enormous
@@ -112,7 +112,7 @@ impl<W: Write> BufWriter<W> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
-        BufWriter { inner: Some(inner), buf: Vec::with_capacity(capacity), panicked: false }
+        BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
     }
 
     /// Send data in our local buffer into the inner writer, looping as
@@ -161,10 +161,9 @@ impl<W: Write> BufWriter<W> {
         }
 
         let mut guard = BufGuard::new(&mut self.buf);
-        let inner = self.inner.as_mut().unwrap();
         while !guard.done() {
             self.panicked = true;
-            let r = inner.write(guard.remaining());
+            let r = self.inner.write(guard.remaining());
             self.panicked = false;
 
             match r {
@@ -212,7 +211,7 @@ impl<W: Write> BufWriter<W> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &W {
-        self.inner.as_ref().unwrap()
+        &self.inner
     }
 
     /// Gets a mutable reference to the underlying writer.
@@ -232,7 +231,7 @@ impl<W: Write> BufWriter<W> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut W {
-        self.inner.as_mut().unwrap()
+        &mut self.inner
     }
 
     /// Returns a reference to the internally buffered data.
@@ -308,7 +307,7 @@ impl<W: Write> BufWriter<W> {
     pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
         match self.flush_buf() {
             Err(e) => Err(IntoInnerError::new(self, e)),
-            Ok(()) => Ok(self.inner.take().unwrap()),
+            Ok(()) => Ok(self.into_parts().0),
         }
     }
 
@@ -319,27 +318,32 @@ impl<W: Write> BufWriter<W> {
     /// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
     /// contents can still be recovered).
     ///
-    /// `into_raw_parts` makes no attempt to flush data and cannot fail.
+    /// `into_parts` makes no attempt to flush data and cannot fail.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(bufwriter_into_raw_parts)]
+    /// #![feature(bufwriter_into_parts)]
     /// use std::io::{BufWriter, Write};
     ///
     /// let mut buffer = [0u8; 10];
     /// let mut stream = BufWriter::new(buffer.as_mut());
     /// write!(stream, "too much data").unwrap();
     /// stream.flush().expect_err("it doesn't fit");
-    /// let (recovered_writer, buffered_data) = stream.into_raw_parts();
+    /// let (recovered_writer, buffered_data) = stream.into_parts();
     /// assert_eq!(recovered_writer.len(), 0);
     /// assert_eq!(&buffered_data.unwrap(), b"ata");
     /// ```
-    #[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
-    pub fn into_raw_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
+    #[unstable(feature = "bufwriter_into_parts", issue = "80690")]
+    pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
         let buf = mem::take(&mut self.buf);
         let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
-        (self.inner.take().unwrap(), buf)
+
+        // SAFETY: forget(self) prevents double dropping inner
+        let inner = unsafe { ptr::read(&mut self.inner) };
+        mem::forget(self);
+
+        (inner, buf)
     }
 
     // Ensure this function does not get inlined into `write`, so that it
@@ -440,14 +444,14 @@ impl<W: Write> BufWriter<W> {
     }
 }
 
-#[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
-/// Error returned for the buffered data from `BufWriter::into_raw_parts`, when the underlying
+#[unstable(feature = "bufwriter_into_parts", issue = "80690")]
+/// Error returned for the buffered data from `BufWriter::into_parts`, when the underlying
 /// writer has previously panicked.  Contains the (possibly partly written) buffered data.
 ///
 /// # Example
 ///
 /// ```
-/// #![feature(bufwriter_into_raw_parts)]
+/// #![feature(bufwriter_into_parts)]
 /// use std::io::{self, BufWriter, Write};
 /// use std::panic::{catch_unwind, AssertUnwindSafe};
 ///
@@ -463,7 +467,7 @@ impl<W: Write> BufWriter<W> {
 ///     stream.flush().unwrap()
 /// }));
 /// assert!(result.is_err());
-/// let (recovered_writer, buffered_data) = stream.into_raw_parts();
+/// let (recovered_writer, buffered_data) = stream.into_parts();
 /// assert!(matches!(recovered_writer, PanickingWriter));
 /// assert_eq!(buffered_data.unwrap_err().into_inner(), b"some data");
 /// ```
@@ -474,7 +478,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.
-    #[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
+    #[unstable(feature = "bufwriter_into_parts", issue = "80690")]
     pub fn into_inner(self) -> Vec<u8> {
         self.buf
     }
@@ -483,7 +487,7 @@ impl WriterPanicked {
         "BufWriter inner writer panicked, what data remains unwritten is not known";
 }
 
-#[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
+#[unstable(feature = "bufwriter_into_parts", issue = "80690")]
 impl error::Error for WriterPanicked {
     #[allow(deprecated, deprecated_in_future)]
     fn description(&self) -> &str {
@@ -491,14 +495,14 @@ impl error::Error for WriterPanicked {
     }
 }
 
-#[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
+#[unstable(feature = "bufwriter_into_parts", issue = "80690")]
 impl fmt::Display for WriterPanicked {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", Self::DESCRIPTION)
     }
 }
 
-#[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
+#[unstable(feature = "bufwriter_into_parts", issue = "80690")]
 impl fmt::Debug for WriterPanicked {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("WriterPanicked")
@@ -643,7 +647,7 @@ where
 {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt.debug_struct("BufWriter")
-            .field("writer", &self.inner.as_ref().unwrap())
+            .field("writer", &self.inner)
             .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
             .finish()
     }
@@ -663,7 +667,7 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Drop for BufWriter<W> {
     fn drop(&mut self) {
-        if self.inner.is_some() && !self.panicked {
+        if !self.panicked {
             // dtors should not panic, so we ignore a failed flush
             let _r = self.flush_buf();
         }
diff --git a/library/std/src/io/buffered/mod.rs b/library/std/src/io/buffered/mod.rs
index 65497817f81..8cfffc2fd35 100644
--- a/library/std/src/io/buffered/mod.rs
+++ b/library/std/src/io/buffered/mod.rs
@@ -14,6 +14,8 @@ use crate::io::Error;
 
 pub use bufreader::BufReader;
 pub use bufwriter::BufWriter;
+#[unstable(feature = "bufwriter_into_parts", issue = "80690")]
+pub use bufwriter::WriterPanicked;
 pub use linewriter::LineWriter;
 use linewritershim::LineWriterShim;
 
@@ -133,7 +135,6 @@ impl<W> IntoInnerError<W> {
     ///
     /// # Example
     /// ```
-    /// #![feature(io_into_inner_error_parts)]
     /// use std::io::{BufWriter, ErrorKind, Write};
     ///
     /// let mut not_enough_space = [0u8; 10];
@@ -143,7 +144,7 @@ impl<W> IntoInnerError<W> {
     /// let err = into_inner_err.into_error();
     /// assert_eq!(err.kind(), ErrorKind::WriteZero);
     /// ```
-    #[unstable(feature = "io_into_inner_error_parts", issue = "79704")]
+    #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
     pub fn into_error(self) -> Error {
         self.1
     }
@@ -156,7 +157,6 @@ impl<W> IntoInnerError<W> {
     ///
     /// # Example
     /// ```
-    /// #![feature(io_into_inner_error_parts)]
     /// use std::io::{BufWriter, ErrorKind, Write};
     ///
     /// let mut not_enough_space = [0u8; 10];
@@ -167,7 +167,7 @@ impl<W> IntoInnerError<W> {
     /// assert_eq!(err.kind(), ErrorKind::WriteZero);
     /// assert_eq!(recovered_writer.buffer(), b"t be actually written");
     /// ```
-    #[unstable(feature = "io_into_inner_error_parts", issue = "79704")]
+    #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
     pub fn into_parts(self) -> (Error, W) {
         (self.1, self.0)
     }
diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs
index 9527254c947..ae0cea985d7 100644
--- a/library/std/src/io/cursor.rs
+++ b/library/std/src/io/cursor.rs
@@ -205,6 +205,62 @@ impl<T> Cursor<T> {
     }
 }
 
+impl<T> Cursor<T>
+where
+    T: AsRef<[u8]>,
+{
+    /// Returns the remaining slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(cursor_remaining)]
+    /// use std::io::Cursor;
+    ///
+    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
+    ///
+    /// assert_eq!(buff.remaining_slice(), &[1, 2, 3, 4, 5]);
+    ///
+    /// buff.set_position(2);
+    /// assert_eq!(buff.remaining_slice(), &[3, 4, 5]);
+    ///
+    /// buff.set_position(4);
+    /// assert_eq!(buff.remaining_slice(), &[5]);
+    ///
+    /// buff.set_position(6);
+    /// assert_eq!(buff.remaining_slice(), &[]);
+    /// ```
+    #[unstable(feature = "cursor_remaining", issue = "86369")]
+    pub fn remaining_slice(&self) -> &[u8] {
+        let len = self.pos.min(self.inner.as_ref().len() as u64);
+        &self.inner.as_ref()[(len as usize)..]
+    }
+
+    /// Returns `true` if the remaining slice is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(cursor_remaining)]
+    /// use std::io::Cursor;
+    ///
+    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
+    ///
+    /// buff.set_position(2);
+    /// assert!(!buff.is_empty());
+    ///
+    /// buff.set_position(5);
+    /// assert!(buff.is_empty());
+    ///
+    /// buff.set_position(10);
+    /// assert!(buff.is_empty());
+    /// ```
+    #[unstable(feature = "cursor_remaining", issue = "86369")]
+    pub fn is_empty(&self) -> bool {
+        self.pos >= self.inner.as_ref().len() as u64
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Clone for Cursor<T>
 where
@@ -268,7 +324,7 @@ where
     T: AsRef<[u8]>,
 {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        let n = Read::read(&mut self.fill_buf()?, buf)?;
+        let n = Read::read(&mut self.remaining_slice(), buf)?;
         self.pos += n as u64;
         Ok(n)
     }
@@ -291,7 +347,7 @@ where
 
     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
         let n = buf.len();
-        Read::read_exact(&mut self.fill_buf()?, buf)?;
+        Read::read_exact(&mut self.remaining_slice(), buf)?;
         self.pos += n as u64;
         Ok(())
     }
@@ -308,8 +364,7 @@ where
     T: AsRef<[u8]>,
 {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
-        let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
-        Ok(&self.inner.as_ref()[(amt as usize)..])
+        Ok(self.remaining_slice())
     }
     fn consume(&mut self, amt: usize) {
         self.pos += amt as u64;
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 56e6f08268c..829ef3d98bb 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -105,6 +105,12 @@ pub enum ErrorKind {
     /// The connection was reset by the remote server.
     #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionReset,
+    /// The remote host is not reachable.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    HostUnreachable,
+    /// The network containing the remote host is not reachable.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    NetworkUnreachable,
     /// The connection was aborted (terminated) by the remote server.
     #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionAborted,
@@ -119,6 +125,9 @@ pub enum ErrorKind {
     /// local.
     #[stable(feature = "rust1", since = "1.0.0")]
     AddrNotAvailable,
+    /// The system's networking is down.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    NetworkDown,
     /// The operation failed because a pipe was closed.
     #[stable(feature = "rust1", since = "1.0.0")]
     BrokenPipe,
@@ -129,6 +138,38 @@ pub enum ErrorKind {
     /// requested to not occur.
     #[stable(feature = "rust1", since = "1.0.0")]
     WouldBlock,
+    /// A filesystem object is, unexpectedly, not a directory.
+    ///
+    /// For example, a filesystem path was specified where one of the intermediate directory
+    /// components was, in fact, a plain file.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    NotADirectory,
+    /// The filesystem object is, unexpectedly, a directory.
+    ///
+    /// A directory was specified when a non-directory was expected.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    IsADirectory,
+    /// A non-empty directory was specified where an empty directory was expected.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    DirectoryNotEmpty,
+    /// The filesystem or storage medium is read-only, but a write operation was attempted.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    ReadOnlyFilesystem,
+    /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
+    ///
+    /// There was a loop (or excessively long chain) resolving a filesystem object
+    /// or file IO object.
+    ///
+    /// On Unix this is usually the result of a symbolic link loop; or, of exceeding the
+    /// system-specific limit on the depth of symlink traversal.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    FilesystemLoop,
+    /// Stale network file handle.
+    ///
+    /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
+    /// by problems with the network or server.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    StaleNetworkFileHandle,
     /// A parameter was incorrect.
     #[stable(feature = "rust1", since = "1.0.0")]
     InvalidInput,
@@ -158,17 +199,78 @@ pub enum ErrorKind {
     /// [`Ok(0)`]: Ok
     #[stable(feature = "rust1", since = "1.0.0")]
     WriteZero,
+    /// The underlying storage (typically, a filesystem) is full.
+    ///
+    /// This does not include out of quota errors.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    StorageFull,
+    /// Seek on unseekable file.
+    ///
+    /// Seeking was attempted on an open file handle which is not suitable for seeking - for
+    /// example, on Unix, a named pipe opened with `File::open`.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    NotSeekable,
+    /// Filesystem quota was exceeded.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    FilesystemQuotaExceeded,
+    /// File larger than allowed or supported.
+    ///
+    /// This might arise from a hard limit of the underlying filesystem or file access API, or from
+    /// an administratively imposed resource limitation.  Simple disk full, and out of quota, have
+    /// their own errors.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    FileTooLarge,
+    /// Resource is busy.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    ResourceBusy,
+    /// Executable file is busy.
+    ///
+    /// An attempt was made to write to a file which is also in use as a running program.  (Not all
+    /// operating systems detect this situation.)
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    ExecutableFileBusy,
+    /// Deadlock (avoided).
+    ///
+    /// A file locking operation would result in deadlock.  This situation is typically detected, if
+    /// at all, on a best-effort basis.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    Deadlock,
+    /// Cross-device or cross-filesystem (hard) link or rename.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    CrossesDevices,
+    /// Too many (hard) links to the same filesystem object.
+    ///
+    /// The filesystem does not support making so many hardlinks to the same file.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    TooManyLinks,
+    /// Filename too long.
+    ///
+    /// The limit might be from the underlying filesystem or API, or an administratively imposed
+    /// resource limit.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    FilenameTooLong,
+    /// Program argument list too long.
+    ///
+    /// When trying to run an external program, a system or process limit on the size of the
+    /// arguments would have been exceeded.
+    #[unstable(feature = "io_error_more", issue = "86442")]
+    ArgumentListTooLong,
     /// This operation was interrupted.
     ///
     /// Interrupted operations can typically be retried.
     #[stable(feature = "rust1", since = "1.0.0")]
     Interrupted,
-    /// Any I/O error not part of this list.
+
+    /// A custom error that does not fall under any other I/O error kind.
     ///
-    /// Errors that are `Other` now may move to a different or a new
-    /// [`ErrorKind`] variant in the future. It is not recommended to match
-    /// an error against `Other` and to expect any additional characteristics,
-    /// e.g., a specific [`Error::raw_os_error`] return value.
+    /// This can be used to construct your own [`Error`]s that do not match any
+    /// [`ErrorKind`].
+    ///
+    /// This [`ErrorKind`] is not used by the standard library.
+    ///
+    /// Errors from the standard library that do not fall under any of the I/O
+    /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
+    /// New [`ErrorKind`]s might be added in the future for some of those.
     #[stable(feature = "rust1", since = "1.0.0")]
     Other,
 
@@ -191,31 +293,62 @@ pub enum ErrorKind {
     /// to allocate enough memory.
     #[stable(feature = "out_of_memory_error", since = "1.54.0")]
     OutOfMemory,
+
+    /// Any I/O error from the standard library that's not part of this list.
+    ///
+    /// Errors that are `Uncategorized` now may move to a different or a new
+    /// [`ErrorKind`] variant in the future. It is not recommended to match
+    /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
+    #[unstable(feature = "io_error_uncategorized", issue = "none")]
+    #[doc(hidden)]
+    Uncategorized,
 }
 
 impl ErrorKind {
     pub(crate) fn as_str(&self) -> &'static str {
+        use ErrorKind::*;
         match *self {
-            ErrorKind::NotFound => "entity not found",
-            ErrorKind::PermissionDenied => "permission denied",
-            ErrorKind::ConnectionRefused => "connection refused",
-            ErrorKind::ConnectionReset => "connection reset",
-            ErrorKind::ConnectionAborted => "connection aborted",
-            ErrorKind::NotConnected => "not connected",
-            ErrorKind::AddrInUse => "address in use",
-            ErrorKind::AddrNotAvailable => "address not available",
-            ErrorKind::BrokenPipe => "broken pipe",
-            ErrorKind::AlreadyExists => "entity already exists",
-            ErrorKind::WouldBlock => "operation would block",
-            ErrorKind::InvalidInput => "invalid input parameter",
-            ErrorKind::InvalidData => "invalid data",
-            ErrorKind::TimedOut => "timed out",
-            ErrorKind::WriteZero => "write zero",
-            ErrorKind::Interrupted => "operation interrupted",
-            ErrorKind::Other => "other os error",
-            ErrorKind::UnexpectedEof => "unexpected end of file",
-            ErrorKind::Unsupported => "unsupported",
-            ErrorKind::OutOfMemory => "out of memory",
+            AddrInUse => "address in use",
+            AddrNotAvailable => "address not available",
+            AlreadyExists => "entity already exists",
+            ArgumentListTooLong => "argument list too long",
+            BrokenPipe => "broken pipe",
+            ResourceBusy => "resource busy",
+            ConnectionAborted => "connection aborted",
+            ConnectionRefused => "connection refused",
+            ConnectionReset => "connection reset",
+            CrossesDevices => "cross-device link or rename",
+            Deadlock => "deadlock",
+            DirectoryNotEmpty => "directory not empty",
+            ExecutableFileBusy => "executable file busy",
+            FilenameTooLong => "filename too long",
+            FilesystemQuotaExceeded => "filesystem quota exceeded",
+            FileTooLarge => "file too large",
+            HostUnreachable => "host unreachable",
+            Interrupted => "operation interrupted",
+            InvalidData => "invalid data",
+            InvalidInput => "invalid input parameter",
+            IsADirectory => "is a directory",
+            NetworkDown => "network down",
+            NetworkUnreachable => "network unreachable",
+            NotADirectory => "not a directory",
+            StorageFull => "no storage space",
+            NotConnected => "not connected",
+            NotFound => "entity not found",
+            Other => "other error",
+            OutOfMemory => "out of memory",
+            PermissionDenied => "permission denied",
+            ReadOnlyFilesystem => "read-only filesystem or storage medium",
+            StaleNetworkFileHandle => "stale network file handle",
+            FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
+            NotSeekable => "seek on unseekable file",
+            TimedOut => "timed out",
+            TooManyLinks => "too many links",
+            Uncategorized => "uncategorized error",
+            UnexpectedEof => "unexpected end of file",
+            Unsupported => "unsupported",
+            WouldBlock => "operation would block",
+            WriteZero => "write zero",
         }
     }
 }
@@ -538,7 +671,7 @@ impl Error {
     /// }
     ///
     /// fn main() {
-    ///     // Will print "Other".
+    ///     // Will print "Uncategorized".
     ///     print_error(Error::last_os_error());
     ///     // Will print "AddrInUse".
     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 6891bd8a664..7a2a49ba7d7 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -87,6 +87,11 @@ impl<S: Seek + ?Sized> Seek for &mut S {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (**self).seek(pos)
     }
+
+    #[inline]
+    fn stream_position(&mut self) -> io::Result<u64> {
+        (**self).stream_position()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B: BufRead + ?Sized> BufRead for &mut B {
@@ -186,6 +191,11 @@ impl<S: Seek + ?Sized> Seek for Box<S> {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         (**self).seek(pos)
     }
+
+    #[inline]
+    fn stream_position(&mut self) -> io::Result<u64> {
+        (**self).stream_position()
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B: BufRead + ?Sized> BufRead for Box<B> {
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 4c154dbe01a..fa073d080c6 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -252,7 +252,9 @@
 mod tests;
 
 use crate::cmp;
+use crate::convert::TryInto;
 use crate::fmt;
+use crate::mem::replace;
 use crate::ops::{Deref, DerefMut};
 use crate::ptr;
 use crate::slice;
@@ -262,6 +264,8 @@ use crate::sys_common::memchr;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::buffered::IntoInnerError;
+#[unstable(feature = "bufwriter_into_parts", issue = "80690")]
+pub use self::buffered::WriterPanicked;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::buffered::{BufReader, BufWriter, LineWriter};
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -275,6 +279,8 @@ pub use self::error::{Error, ErrorKind, Result};
 pub use self::stdio::set_output_capture;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
+#[unstable(feature = "stdio_locked", issue = "86845")]
+pub use self::stdio::{stderr_locked, stdin_locked, stdout_locked};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{StderrLock, StdinLock, StdoutLock};
 #[unstable(feature = "print_internals", issue = "none")]
@@ -510,6 +516,7 @@ pub(crate) fn default_read_exact<R: Read + ?Sized>(this: &mut R, mut buf: &mut [
 /// [`File`]: crate::fs::File
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(notable_trait)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "IoRead")]
 pub trait Read {
     /// Pull some bytes from this source into the specified buffer, returning
     /// how many bytes were read.
@@ -548,7 +555,7 @@ pub trait Read {
     /// contents of `buf` being true. It is recommended that *implementations*
     /// only write data to `buf` instead of reading its contents.
     ///
-    /// Correspondingly, however, *callers* of this method may not assume any guarantees
+    /// Correspondingly, however, *callers* of this method must not assume any guarantees
     /// about how the implementation uses `buf`. The trait is safe to implement,
     /// so it is possible that the code that's supposed to write to the buffer might also read
     /// from it. It is your responsibility to make sure that `buf` is initialized
@@ -803,9 +810,9 @@ pub trait Read {
         default_read_exact(self, buf)
     }
 
-    /// Creates a "by reference" adaptor for this instance of `Read`.
+    /// Creates a "by reference" adapter for this instance of `Read`.
     ///
-    /// The returned adaptor also implements `Read` and will simply borrow this
+    /// The returned adapter also implements `Read` and will simply borrow this
     /// current reader.
     ///
     /// # Examples
@@ -882,7 +889,7 @@ pub trait Read {
         Bytes { inner: self }
     }
 
-    /// Creates an adaptor which will chain this stream with another.
+    /// Creates an adapter which will chain this stream with another.
     ///
     /// The returned `Read` instance will first read all bytes from this object
     /// until EOF is encountered. Afterwards the output is equivalent to the
@@ -920,7 +927,7 @@ pub trait Read {
         Chain { first: self, second: next, done_first: false }
     }
 
-    /// Creates an adaptor which will read at most `limit` bytes from it.
+    /// Creates an adapter which will read at most `limit` bytes from it.
     ///
     /// This function returns a new instance of `Read` which will read at most
     /// `limit` bytes, after which it will always return EOF ([`Ok(0)`]). Any
@@ -1044,6 +1051,32 @@ impl<'a> IoSliceMut<'a> {
 
     /// Advance the internal cursor of the slice.
     ///
+    /// Also see [`IoSliceMut::advance_slices`] to advance the cursors of
+    /// multiple buffers.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(io_slice_advance)]
+    ///
+    /// use std::io::IoSliceMut;
+    /// use std::ops::Deref;
+    ///
+    /// let mut data = [1; 8];
+    /// let mut buf = IoSliceMut::new(&mut data);
+    ///
+    /// // Mark 3 bytes as read.
+    /// buf.advance(3);
+    /// assert_eq!(buf.deref(), [1; 5].as_ref());
+    /// ```
+    #[unstable(feature = "io_slice_advance", issue = "62726")]
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        self.0.advance(n)
+    }
+
+    /// Advance the internal cursor of the slices.
+    ///
     /// # Notes
     ///
     /// Elements in the slice may be modified if the cursor is not advanced to
@@ -1070,13 +1103,13 @@ impl<'a> IoSliceMut<'a> {
     /// ][..];
     ///
     /// // Mark 10 bytes as read.
-    /// bufs = IoSliceMut::advance(bufs, 10);
+    /// IoSliceMut::advance_slices(&mut bufs, 10);
     /// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
     /// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
     /// ```
     #[unstable(feature = "io_slice_advance", issue = "62726")]
     #[inline]
-    pub fn advance<'b>(bufs: &'b mut [IoSliceMut<'a>], n: usize) -> &'b mut [IoSliceMut<'a>] {
+    pub fn advance_slices(bufs: &mut &mut [IoSliceMut<'a>], n: usize) {
         // Number of buffers to remove.
         let mut remove = 0;
         // Total length of all the to be removed buffers.
@@ -1090,11 +1123,10 @@ impl<'a> IoSliceMut<'a> {
             }
         }
 
-        let bufs = &mut bufs[remove..];
+        *bufs = &mut replace(bufs, &mut [])[remove..];
         if !bufs.is_empty() {
-            bufs[0].0.advance(n - accumulated_len)
+            bufs[0].advance(n - accumulated_len)
         }
-        bufs
     }
 }
 
@@ -1153,6 +1185,32 @@ impl<'a> IoSlice<'a> {
 
     /// Advance the internal cursor of the slice.
     ///
+    /// Also see [`IoSlice::advance_slices`] to advance the cursors of multiple
+    /// buffers.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(io_slice_advance)]
+    ///
+    /// use std::io::IoSlice;
+    /// use std::ops::Deref;
+    ///
+    /// let mut data = [1; 8];
+    /// let mut buf = IoSlice::new(&mut data);
+    ///
+    /// // Mark 3 bytes as read.
+    /// buf.advance(3);
+    /// assert_eq!(buf.deref(), [1; 5].as_ref());
+    /// ```
+    #[unstable(feature = "io_slice_advance", issue = "62726")]
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        self.0.advance(n)
+    }
+
+    /// Advance the internal cursor of the slices.
+    ///
     /// # Notes
     ///
     /// Elements in the slice may be modified if the cursor is not advanced to
@@ -1179,12 +1237,12 @@ impl<'a> IoSlice<'a> {
     /// ][..];
     ///
     /// // Mark 10 bytes as written.
-    /// bufs = IoSlice::advance(bufs, 10);
+    /// IoSlice::advance_slices(&mut bufs, 10);
     /// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
     /// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
     #[unstable(feature = "io_slice_advance", issue = "62726")]
     #[inline]
-    pub fn advance<'b>(bufs: &'b mut [IoSlice<'a>], n: usize) -> &'b mut [IoSlice<'a>] {
+    pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize) {
         // Number of buffers to remove.
         let mut remove = 0;
         // Total length of all the to be removed buffers.
@@ -1198,11 +1256,10 @@ impl<'a> IoSlice<'a> {
             }
         }
 
-        let bufs = &mut bufs[remove..];
+        *bufs = &mut replace(bufs, &mut [])[remove..];
         if !bufs.is_empty() {
-            bufs[0].0.advance(n - accumulated_len)
+            bufs[0].advance(n - accumulated_len)
         }
-        bufs
     }
 }
 
@@ -1269,7 +1326,7 @@ impl Initializer {
 /// * The [`write`] method will attempt to write some data into the object,
 ///   returning how many bytes were successfully written.
 ///
-/// * The [`flush`] method is useful for adaptors and explicit buffers
+/// * The [`flush`] method is useful for adapters and explicit buffers
 ///   themselves for ensuring that all buffered data has been pushed out to the
 ///   'true sink'.
 ///
@@ -1307,11 +1364,12 @@ impl Initializer {
 /// [`write_all`]: Write::write_all
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(notable_trait)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "IoWrite")]
 pub trait Write {
     /// Write a buffer into this writer, returning how many bytes were written.
     ///
     /// This function will attempt to write the entire contents of `buf`, but
-    /// the entire write may not succeed, or the write may also generate an
+    /// the entire write might not succeed, or the write may also generate an
     /// error. A call to `write` represents *at most one* attempt to write to
     /// any wrapped object.
     ///
@@ -1364,6 +1422,27 @@ pub trait Write {
     /// The default implementation calls [`write`] with either the first nonempty
     /// buffer provided, or an empty one if none exists.
     ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io::IoSlice;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let mut data1 = [1; 8];
+    ///     let mut data2 = [15; 8];
+    ///     let io_slice1 = IoSlice::new(&mut data1);
+    ///     let io_slice2 = IoSlice::new(&mut data2);
+    ///
+    ///     let mut buffer = File::create("foo.txt")?;
+    ///
+    ///     // Writes some prefix of the byte string, not necessarily all of it.
+    ///     buffer.write_vectored(&[io_slice1, io_slice2])?;
+    ///     Ok(())
+    /// }
+    /// ```
+    ///
     /// [`write`]: Write::write
     #[stable(feature = "iovec", since = "1.36.0")]
     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
@@ -1511,7 +1590,7 @@ pub trait Write {
     fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
         // Guarantee that bufs is empty if it contains no data,
         // to avoid calling write_vectored if there is no data to be written.
-        bufs = IoSlice::advance(bufs, 0);
+        IoSlice::advance_slices(&mut bufs, 0);
         while !bufs.is_empty() {
             match self.write_vectored(bufs) {
                 Ok(0) => {
@@ -1520,7 +1599,7 @@ pub trait Write {
                         &"failed to write whole buffer",
                     ));
                 }
-                Ok(n) => bufs = IoSlice::advance(bufs, n),
+                Ok(n) => IoSlice::advance_slices(&mut bufs, n),
                 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
                 Err(e) => return Err(e),
             }
@@ -1567,12 +1646,12 @@ pub trait Write {
     fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
         // Create a shim which translates a Write to a fmt::Write and saves
         // off I/O errors. instead of discarding them
-        struct Adaptor<'a, T: ?Sized + 'a> {
+        struct Adapter<'a, T: ?Sized + 'a> {
             inner: &'a mut T,
             error: Result<()>,
         }
 
-        impl<T: Write + ?Sized> fmt::Write for Adaptor<'_, T> {
+        impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
             fn write_str(&mut self, s: &str) -> fmt::Result {
                 match self.inner.write_all(s.as_bytes()) {
                     Ok(()) => Ok(()),
@@ -1584,7 +1663,7 @@ pub trait Write {
             }
         }
 
-        let mut output = Adaptor { inner: self, error: Ok(()) };
+        let mut output = Adapter { inner: self, error: Ok(()) };
         match fmt::write(&mut output, fmt) {
             Ok(()) => Ok(()),
             Err(..) => {
@@ -1592,15 +1671,15 @@ pub trait Write {
                 if output.error.is_err() {
                     output.error
                 } else {
-                    Err(Error::new_const(ErrorKind::Other, &"formatter error"))
+                    Err(Error::new_const(ErrorKind::Uncategorized, &"formatter error"))
                 }
             }
         }
     }
 
-    /// Creates a "by reference" adaptor for this instance of `Write`.
+    /// Creates a "by reference" adapter for this instance of `Write`.
     ///
-    /// The returned adaptor also implements `Write` and will simply borrow this
+    /// The returned adapter also implements `Write` and will simply borrow this
     /// current writer.
     ///
     /// # Examples
@@ -1684,7 +1763,6 @@ pub trait Seek {
     /// # Example
     ///
     /// ```no_run
-    /// #![feature(seek_rewind)]
     /// use std::io::{Read, Seek, Write};
     /// use std::fs::OpenOptions;
     ///
@@ -1702,7 +1780,7 @@ pub trait Seek {
     /// f.read_to_string(&mut buf).unwrap();
     /// assert_eq!(&buf, hello);
     /// ```
-    #[unstable(feature = "seek_rewind", issue = "85149")]
+    #[stable(feature = "seek_rewind", since = "1.55.0")]
     fn rewind(&mut self) -> Result<()> {
         self.seek(SeekFrom::Start(0))?;
         Ok(())
@@ -1953,6 +2031,37 @@ pub trait BufRead: Read {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn consume(&mut self, amt: usize);
 
+    /// Check if the underlying `Read` has any data left to be read.
+    ///
+    /// This function may fill the buffer to check for data,
+    /// so this functions returns `Result<bool>`, not `bool`.
+    ///
+    /// Default implementation calls `fill_buf` and checks that
+    /// returned slice is empty (which means that there is no data left,
+    /// since EOF is reached).
+    ///
+    /// Examples
+    ///
+    /// ```
+    /// #![feature(buf_read_has_data_left)]
+    /// use std::io;
+    /// use std::io::prelude::*;
+    ///
+    /// let stdin = io::stdin();
+    /// let mut stdin = stdin.lock();
+    ///
+    /// while stdin.has_data_left().unwrap() {
+    ///     let mut line = String::new();
+    ///     stdin.read_line(&mut line).unwrap();
+    ///     // work with line
+    ///     println!("{:?}", line);
+    /// }
+    /// ```
+    #[unstable(feature = "buf_read_has_data_left", reason = "recently added", issue = "86423")]
+    fn has_data_left(&mut self) -> Result<bool> {
+        self.fill_buf().map(|b| !b.is_empty())
+    }
+
     /// Read all bytes into `buf` until the delimiter `byte` or EOF is reached.
     ///
     /// This function will read bytes from the underlying stream until the
@@ -2154,7 +2263,7 @@ pub trait BufRead: Read {
     }
 }
 
-/// Adaptor to chain together two readers.
+/// Adapter to chain together two readers.
 ///
 /// This struct is generally created by calling [`chain`] on a reader.
 /// Please see the documentation of [`chain`] for more details.
@@ -2291,19 +2400,21 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
 }
 
 impl<T, U> SizeHint for Chain<T, U> {
+    #[inline]
     fn lower_bound(&self) -> usize {
         SizeHint::lower_bound(&self.first) + SizeHint::lower_bound(&self.second)
     }
 
+    #[inline]
     fn upper_bound(&self) -> Option<usize> {
         match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
-            (Some(first), Some(second)) => Some(first + second),
+            (Some(first), Some(second)) => first.checked_add(second),
             _ => None,
         }
     }
 }
 
-/// Reader adaptor which limits the bytes read from an underlying reader.
+/// Reader adapter which limits the bytes read from an underlying reader.
 ///
 /// This struct is generally created by calling [`take`] on a reader.
 /// Please see the documentation of [`take`] for more details.
@@ -2502,6 +2613,21 @@ impl<T: BufRead> BufRead for Take<T> {
     }
 }
 
+impl<T> SizeHint for Take<T> {
+    #[inline]
+    fn lower_bound(&self) -> usize {
+        cmp::min(SizeHint::lower_bound(&self.inner) as u64, self.limit) as usize
+    }
+
+    #[inline]
+    fn upper_bound(&self) -> Option<usize> {
+        match SizeHint::upper_bound(&self.inner) {
+            Some(upper_bound) => Some(cmp::min(upper_bound as u64, self.limit) as usize),
+            None => self.limit.try_into().ok(),
+        }
+    }
+}
+
 /// An iterator over `u8` values of a reader.
 ///
 /// This struct is generally created by calling [`bytes`] on a reader.
@@ -2546,15 +2672,53 @@ trait SizeHint {
 }
 
 impl<T> SizeHint for T {
+    #[inline]
     default fn lower_bound(&self) -> usize {
         0
     }
 
+    #[inline]
     default fn upper_bound(&self) -> Option<usize> {
         None
     }
 }
 
+impl<T> SizeHint for &mut T {
+    #[inline]
+    fn lower_bound(&self) -> usize {
+        SizeHint::lower_bound(*self)
+    }
+
+    #[inline]
+    fn upper_bound(&self) -> Option<usize> {
+        SizeHint::upper_bound(*self)
+    }
+}
+
+impl<T> SizeHint for Box<T> {
+    #[inline]
+    fn lower_bound(&self) -> usize {
+        SizeHint::lower_bound(&**self)
+    }
+
+    #[inline]
+    fn upper_bound(&self) -> Option<usize> {
+        SizeHint::upper_bound(&**self)
+    }
+}
+
+impl SizeHint for &[u8] {
+    #[inline]
+    fn lower_bound(&self) -> usize {
+        self.len()
+    }
+
+    #[inline]
+    fn upper_bound(&self) -> Option<usize> {
+        Some(self.len())
+    }
+}
+
 /// An iterator over the contents of an instance of `BufRead` split on a
 /// particular byte.
 ///
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 2b0d2b7e0be..14a63303711 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -7,7 +7,7 @@ use crate::io::prelude::*;
 
 use crate::cell::{Cell, RefCell};
 use crate::fmt;
-use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter};
+use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter, Lines, Split};
 use crate::lazy::SyncOnceCell;
 use crate::pin::Pin;
 use crate::sync::atomic::{AtomicBool, Ordering};
@@ -216,12 +216,12 @@ fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
 /// # Examples
 ///
 /// ```no_run
-/// use std::io::{self, Read};
+/// use std::io;
 ///
 /// fn main() -> io::Result<()> {
 ///     let mut buffer = String::new();
 ///     let mut stdin = io::stdin(); // We get `Stdin` here.
-///     stdin.read_to_string(&mut buffer)?;
+///     stdin.read_line(&mut buffer)?;
 ///     Ok(())
 /// }
 /// ```
@@ -244,14 +244,14 @@ pub struct Stdin {
 /// # Examples
 ///
 /// ```no_run
-/// use std::io::{self, Read};
+/// use std::io::{self, BufRead};
 ///
 /// fn main() -> io::Result<()> {
 ///     let mut buffer = String::new();
 ///     let stdin = io::stdin(); // We get `Stdin` here.
 ///     {
 ///         let mut handle = stdin.lock(); // We get `StdinLock` here.
-///         handle.read_to_string(&mut buffer)?;
+///         handle.read_line(&mut buffer)?;
 ///     } // `StdinLock` is dropped here.
 ///     Ok(())
 /// }
@@ -277,11 +277,11 @@ pub struct StdinLock<'a> {
 /// Using implicit synchronization:
 ///
 /// ```no_run
-/// use std::io::{self, Read};
+/// use std::io;
 ///
 /// fn main() -> io::Result<()> {
 ///     let mut buffer = String::new();
-///     io::stdin().read_to_string(&mut buffer)?;
+///     io::stdin().read_line(&mut buffer)?;
 ///     Ok(())
 /// }
 /// ```
@@ -289,14 +289,14 @@ pub struct StdinLock<'a> {
 /// Using explicit synchronization:
 ///
 /// ```no_run
-/// use std::io::{self, Read};
+/// use std::io::{self, BufRead};
 ///
 /// fn main() -> io::Result<()> {
 ///     let mut buffer = String::new();
 ///     let stdin = io::stdin();
 ///     let mut handle = stdin.lock();
 ///
-///     handle.read_to_string(&mut buffer)?;
+///     handle.read_line(&mut buffer)?;
 ///     Ok(())
 /// }
 /// ```
@@ -310,6 +310,48 @@ pub fn stdin() -> Stdin {
     }
 }
 
+/// Constructs a new locked handle to the standard input of the current
+/// process.
+///
+/// Each handle returned is a guard granting locked access to a shared
+/// global buffer whose access is synchronized via a mutex. If you need
+/// more explicit control over locking, for example, in a multi-threaded
+/// program, use the [`io::stdin`] function to obtain an unlocked handle,
+/// along with the [`Stdin::lock`] method.
+///
+/// The lock is released when the returned guard goes out of scope. The
+/// returned guard also implements the [`Read`] and [`BufRead`] traits for
+/// accessing the underlying data.
+///
+/// **Note**: The mutex locked by this handle is not reentrant. Even in a
+/// single-threaded program, calling other code that accesses [`Stdin`]
+/// could cause a deadlock or panic, if this locked handle is held across
+/// that call.
+///
+/// ### Note: Windows Portability Consideration
+/// When operating in a console, the Windows implementation of this stream does not support
+/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
+/// an error.
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(stdio_locked)]
+/// use std::io::{self, BufRead};
+///
+/// fn main() -> io::Result<()> {
+///     let mut buffer = String::new();
+///     let mut handle = io::stdin_locked();
+///
+///     handle.read_line(&mut buffer)?;
+///     Ok(())
+/// }
+/// ```
+#[unstable(feature = "stdio_locked", issue = "86845")]
+pub fn stdin_locked() -> StdinLock<'static> {
+    stdin().into_locked()
+}
+
 impl Stdin {
     /// Locks this handle to the standard input stream, returning a readable
     /// guard.
@@ -321,20 +363,20 @@ impl Stdin {
     /// # Examples
     ///
     /// ```no_run
-    /// use std::io::{self, Read};
+    /// use std::io::{self, BufRead};
     ///
     /// fn main() -> io::Result<()> {
     ///     let mut buffer = String::new();
     ///     let stdin = io::stdin();
     ///     let mut handle = stdin.lock();
     ///
-    ///     handle.read_to_string(&mut buffer)?;
+    ///     handle.read_line(&mut buffer)?;
     ///     Ok(())
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock<'_> {
-        StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
+        self.lock_any()
     }
 
     /// Locks this handle and reads a line of input, appending it to the specified buffer.
@@ -367,6 +409,86 @@ impl Stdin {
     pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
         self.lock().read_line(buf)
     }
+
+    // Locks this handle with any lifetime. This depends on the
+    // implementation detail that the underlying `Mutex` is static.
+    fn lock_any<'a>(&self) -> StdinLock<'a> {
+        StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
+    }
+
+    /// Consumes this handle to the standard input stream, locking the
+    /// shared global buffer associated with the stream and returning a
+    /// readable guard.
+    ///
+    /// The lock is released when the returned guard goes out of scope. The
+    /// returned guard also implements the [`Read`] and [`BufRead`] traits
+    /// for accessing the underlying data.
+    ///
+    /// It is often simpler to directly get a locked handle using the
+    /// [`stdin_locked`] function instead, unless nearby code also needs to
+    /// use an unlocked handle.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(stdio_locked)]
+    /// use std::io::{self, BufRead};
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut buffer = String::new();
+    ///     let mut handle = io::stdin().into_locked();
+    ///
+    ///     handle.read_line(&mut buffer)?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "stdio_locked", issue = "86845")]
+    pub fn into_locked(self) -> StdinLock<'static> {
+        self.lock_any()
+    }
+
+    /// Consumes this handle and returns an iterator over input lines.
+    ///
+    /// For detailed semantics of this method, see the documentation on
+    /// [`BufRead::lines`].
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(stdin_forwarders)]
+    /// use std::io;
+    ///
+    /// let lines = io::stdin().lines();
+    /// for line in lines {
+    ///     println!("got a line: {}", line.unwrap());
+    /// }
+    /// ```
+    #[unstable(feature = "stdin_forwarders", issue = "87096")]
+    pub fn lines(self) -> Lines<StdinLock<'static>> {
+        self.into_locked().lines()
+    }
+
+    /// Consumes this handle and returns an iterator over input bytes,
+    /// split at the specified byte value.
+    ///
+    /// For detailed semantics of this method, see the documentation on
+    /// [`BufRead::split`].
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(stdin_forwarders)]
+    /// use std::io;
+    ///
+    /// let splits = io::stdin().split(b'-');
+    /// for split in splits {
+    ///     println!("got a chunk: {}", String::from_utf8_lossy(&split.unwrap()));
+    /// }
+    /// ```
+    #[unstable(feature = "stdin_forwarders", issue = "87096")]
+    pub fn split(self, byte: u8) -> Split<StdinLock<'static>> {
+        self.into_locked().split(byte)
+    }
 }
 
 #[stable(feature = "std_debug", since = "1.16.0")]
@@ -558,6 +680,42 @@ pub fn stdout() -> Stdout {
     }
 }
 
+/// Constructs a new locked handle to the standard output of the current
+/// process.
+///
+/// Each handle returned is a guard granting locked access to a shared
+/// global buffer whose access is synchronized via a mutex. If you need
+/// more explicit control over locking, for example, in a multi-threaded
+/// program, use the [`io::stdout`] function to obtain an unlocked handle,
+/// along with the [`Stdout::lock`] method.
+///
+/// The lock is released when the returned guard goes out of scope. The
+/// returned guard also implements the [`Write`] trait for writing data.
+///
+/// ### Note: Windows Portability Consideration
+/// 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.
+///
+/// # Examples
+///
+/// ```no_run
+/// #![feature(stdio_locked)]
+/// use std::io::{self, Write};
+///
+/// fn main() -> io::Result<()> {
+///     let mut handle = io::stdout_locked();
+///
+///     handle.write_all(b"hello world")?;
+///
+///     Ok(())
+/// }
+/// ```
+#[unstable(feature = "stdio_locked", issue = "86845")]
+pub fn stdout_locked() -> StdoutLock<'static> {
+    stdout().into_locked()
+}
+
 pub fn cleanup() {
     if let Some(instance) = STDOUT.get() {
         // Flush the data and disable buffering during shutdown
@@ -595,8 +753,45 @@ impl Stdout {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdoutLock<'_> {
+        self.lock_any()
+    }
+
+    // Locks this handle with any lifetime. This depends on the
+    // implementation detail that the underlying `ReentrantMutex` is
+    // static.
+    fn lock_any<'a>(&self) -> StdoutLock<'a> {
         StdoutLock { inner: self.inner.lock() }
     }
+
+    /// Consumes this handle to the standard output stream, locking the
+    /// shared global buffer associated with the stream and returning a
+    /// writable guard.
+    ///
+    /// The lock is released when the returned lock goes out of scope. The
+    /// returned guard also implements the [`Write`] trait for writing data.
+    ///
+    /// It is often simpler to directly get a locked handle using the
+    /// [`io::stdout_locked`] function instead, unless nearby code also
+    /// needs to use an unlocked handle.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(stdio_locked)]
+    /// use std::io::{self, Write};
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut handle = io::stdout().into_locked();
+    ///
+    ///     handle.write_all(b"hello world")?;
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "stdio_locked", issue = "86845")]
+    pub fn into_locked(self) -> StdoutLock<'static> {
+        self.lock_any()
+    }
 }
 
 #[stable(feature = "std_debug", since = "1.16.0")]
@@ -769,6 +964,35 @@ pub fn stderr() -> Stderr {
     }
 }
 
+/// Constructs a new locked handle to the standard error of the current
+/// process.
+///
+/// This handle is not buffered.
+///
+/// ### Note: Windows Portability Consideration
+/// 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.
+///
+/// # Example
+///
+/// ```no_run
+/// #![feature(stdio_locked)]
+/// use std::io::{self, Write};
+///
+/// fn main() -> io::Result<()> {
+///     let mut handle = io::stderr_locked();
+///
+///     handle.write_all(b"hello world")?;
+///
+///     Ok(())
+/// }
+/// ```
+#[unstable(feature = "stdio_locked", issue = "86845")]
+pub fn stderr_locked() -> StderrLock<'static> {
+    stderr().into_locked()
+}
+
 impl Stderr {
     /// Locks this handle to the standard error stream, returning a writable
     /// guard.
@@ -792,8 +1016,42 @@ impl Stderr {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StderrLock<'_> {
+        self.lock_any()
+    }
+
+    // Locks this handle with any lifetime. This depends on the
+    // implementation detail that the underlying `ReentrantMutex` is
+    // static.
+    fn lock_any<'a>(&self) -> StderrLock<'a> {
         StderrLock { inner: self.inner.lock() }
     }
+
+    /// Locks and consumes this handle to the standard error stream,
+    /// returning a writable guard.
+    ///
+    /// The lock is released when the returned guard goes out of scope. The
+    /// returned guard also implements the [`Write`] trait for writing
+    /// data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(stdio_locked)]
+    /// use std::io::{self, Write};
+    ///
+    /// fn foo() -> io::Result<()> {
+    ///     let stderr = io::stderr();
+    ///     let mut handle = stderr.into_locked();
+    ///
+    ///     handle.write_all(b"hello world")?;
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "stdio_locked", issue = "86845")]
+    pub fn into_locked(self) -> StderrLock<'static> {
+        self.lock_any()
+    }
 }
 
 #[stable(feature = "std_debug", since = "1.16.0")]
diff --git a/library/std/src/io/stdio/tests.rs b/library/std/src/io/stdio/tests.rs
index 04af500268f..b1df6b7131c 100644
--- a/library/std/src/io/stdio/tests.rs
+++ b/library/std/src/io/stdio/tests.rs
@@ -1,5 +1,6 @@
 use super::*;
 use crate::panic::{RefUnwindSafe, UnwindSafe};
+use crate::sync::mpsc::sync_channel;
 use crate::thread;
 
 #[test]
@@ -45,3 +46,121 @@ fn panic_doesnt_poison() {
     let _a = stderr();
     let _a = _a.lock();
 }
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_lock_stderr() {
+    test_lock(stderr, stderr_locked);
+}
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_lock_stdin() {
+    test_lock(stdin, stdin_locked);
+}
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_lock_stdout() {
+    test_lock(stdout, stdout_locked);
+}
+
+// Helper trait to make lock testing function generic.
+trait Stdio<'a>: 'static
+where
+    Self::Lock: 'a,
+{
+    type Lock;
+    fn lock(&'a self) -> Self::Lock;
+}
+impl<'a> Stdio<'a> for Stderr {
+    type Lock = StderrLock<'a>;
+    fn lock(&'a self) -> StderrLock<'a> {
+        self.lock()
+    }
+}
+impl<'a> Stdio<'a> for Stdin {
+    type Lock = StdinLock<'a>;
+    fn lock(&'a self) -> StdinLock<'a> {
+        self.lock()
+    }
+}
+impl<'a> Stdio<'a> for Stdout {
+    type Lock = StdoutLock<'a>;
+    fn lock(&'a self) -> StdoutLock<'a> {
+        self.lock()
+    }
+}
+
+// Helper trait to make lock testing function generic.
+trait StdioOwnedLock: 'static {}
+impl StdioOwnedLock for StderrLock<'static> {}
+impl StdioOwnedLock for StdinLock<'static> {}
+impl StdioOwnedLock for StdoutLock<'static> {}
+
+// Tests locking on stdio handles by starting two threads and checking that
+// they block each other appropriately.
+fn test_lock<T, U>(get_handle: fn() -> T, get_locked: fn() -> U)
+where
+    T: for<'a> Stdio<'a>,
+    U: StdioOwnedLock,
+{
+    // State enum to track different phases of the test, primarily when
+    // each lock is acquired and released.
+    #[derive(Debug, PartialEq)]
+    enum State {
+        Start1,
+        Acquire1,
+        Start2,
+        Release1,
+        Acquire2,
+        Release2,
+    }
+    use State::*;
+    // Logging vector to be checked to make sure lock acquisitions and
+    // releases happened in the correct order.
+    let log = Arc::new(Mutex::new(Vec::new()));
+    let ((tx1, rx1), (tx2, rx2)) = (sync_channel(0), sync_channel(0));
+    let th1 = {
+        let (log, tx) = (Arc::clone(&log), tx1);
+        thread::spawn(move || {
+            log.lock().unwrap().push(Start1);
+            let handle = get_handle();
+            {
+                let locked = handle.lock();
+                log.lock().unwrap().push(Acquire1);
+                tx.send(Acquire1).unwrap(); // notify of acquisition
+                tx.send(Release1).unwrap(); // wait for release command
+                log.lock().unwrap().push(Release1);
+            }
+            tx.send(Acquire1).unwrap(); // wait for th2 acquire
+            {
+                let locked = handle.lock();
+                log.lock().unwrap().push(Acquire1);
+            }
+            log.lock().unwrap().push(Release1);
+        })
+    };
+    let th2 = {
+        let (log, tx) = (Arc::clone(&log), tx2);
+        thread::spawn(move || {
+            tx.send(Start2).unwrap(); // wait for start command
+            let locked = get_locked();
+            log.lock().unwrap().push(Acquire2);
+            tx.send(Acquire2).unwrap(); // notify of acquisition
+            tx.send(Release2).unwrap(); // wait for release command
+            log.lock().unwrap().push(Release2);
+        })
+    };
+    assert_eq!(rx1.recv().unwrap(), Acquire1); // wait for th1 acquire
+    log.lock().unwrap().push(Start2);
+    assert_eq!(rx2.recv().unwrap(), Start2); // block th2
+    assert_eq!(rx1.recv().unwrap(), Release1); // release th1
+    assert_eq!(rx2.recv().unwrap(), Acquire2); // wait for th2 acquire
+    assert_eq!(rx1.recv().unwrap(), Acquire1); // block th1
+    assert_eq!(rx2.recv().unwrap(), Release2); // release th2
+    th2.join().unwrap();
+    th1.join().unwrap();
+    assert_eq!(
+        *log.lock().unwrap(),
+        [Start1, Acquire1, Start2, Release1, Acquire2, Release2, Acquire1, Release1]
+    );
+}
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index 2b14e161503..1beb72a9a50 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -72,6 +72,16 @@ fn lines() {
 }
 
 #[test]
+fn buf_read_has_data_left() {
+    let mut buf = Cursor::new(&b"abcd"[..]);
+    assert!(buf.has_data_left().unwrap());
+    buf.read_exact(&mut [0; 2]).unwrap();
+    assert!(buf.has_data_left().unwrap());
+    buf.read_exact(&mut [0; 2]).unwrap();
+    assert!(!buf.has_data_left().unwrap());
+}
+
+#[test]
 fn read_to_end() {
     let mut c = Cursor::new(&b""[..]);
     let mut v = Vec::new();
@@ -225,6 +235,24 @@ fn empty_size_hint() {
 }
 
 #[test]
+fn slice_size_hint() {
+    let size_hint = (&[1, 2, 3]).bytes().size_hint();
+    assert_eq!(size_hint, (3, Some(3)));
+}
+
+#[test]
+fn take_size_hint() {
+    let size_hint = (&[1, 2, 3]).take(2).bytes().size_hint();
+    assert_eq!(size_hint, (2, Some(2)));
+
+    let size_hint = (&[1, 2, 3]).take(4).bytes().size_hint();
+    assert_eq!(size_hint, (3, Some(3)));
+
+    let size_hint = io::repeat(0).take(3).bytes().size_hint();
+    assert_eq!(size_hint, (3, Some(3)));
+}
+
+#[test]
 fn chain_empty_size_hint() {
     let chain = io::empty().chain(io::empty());
     let size_hint = chain.bytes().size_hint();
@@ -242,7 +270,7 @@ fn chain_size_hint() {
 
     let chain = buf_reader_1.chain(buf_reader_2);
     let size_hint = chain.bytes().size_hint();
-    assert_eq!(size_hint, (testdata.len(), None));
+    assert_eq!(size_hint, (testdata.len(), Some(testdata.len())));
 }
 
 #[test]
@@ -308,6 +336,10 @@ fn seek_position() -> io::Result<()> {
     assert_eq!(c.stream_position()?, 8);
     assert_eq!(c.stream_position()?, 8);
 
+    c.rewind()?;
+    assert_eq!(c.stream_position()?, 0);
+    assert_eq!(c.stream_position()?, 0);
+
     Ok(())
 }
 
@@ -353,7 +385,7 @@ fn test_read_to_end_capacity() -> io::Result<()> {
 }
 
 #[test]
-fn io_slice_mut_advance() {
+fn io_slice_mut_advance_slices() {
     let mut buf1 = [1; 8];
     let mut buf2 = [2; 16];
     let mut buf3 = [3; 8];
@@ -364,75 +396,75 @@ fn io_slice_mut_advance() {
     ][..];
 
     // Only in a single buffer..
-    bufs = IoSliceMut::advance(bufs, 1);
+    IoSliceMut::advance_slices(&mut bufs, 1);
     assert_eq!(bufs[0].deref(), [1; 7].as_ref());
     assert_eq!(bufs[1].deref(), [2; 16].as_ref());
     assert_eq!(bufs[2].deref(), [3; 8].as_ref());
 
     // Removing a buffer, leaving others as is.
-    bufs = IoSliceMut::advance(bufs, 7);
+    IoSliceMut::advance_slices(&mut bufs, 7);
     assert_eq!(bufs[0].deref(), [2; 16].as_ref());
     assert_eq!(bufs[1].deref(), [3; 8].as_ref());
 
     // Removing a buffer and removing from the next buffer.
-    bufs = IoSliceMut::advance(bufs, 18);
+    IoSliceMut::advance_slices(&mut bufs, 18);
     assert_eq!(bufs[0].deref(), [3; 6].as_ref());
 }
 
 #[test]
-fn io_slice_mut_advance_empty_slice() {
-    let empty_bufs = &mut [][..];
+fn io_slice_mut_advance_slices_empty_slice() {
+    let mut empty_bufs = &mut [][..];
     // Shouldn't panic.
-    IoSliceMut::advance(empty_bufs, 1);
+    IoSliceMut::advance_slices(&mut empty_bufs, 1);
 }
 
 #[test]
-fn io_slice_mut_advance_beyond_total_length() {
+fn io_slice_mut_advance_slices_beyond_total_length() {
     let mut buf1 = [1; 8];
     let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
 
     // Going beyond the total length should be ok.
-    bufs = IoSliceMut::advance(bufs, 9);
+    IoSliceMut::advance_slices(&mut bufs, 9);
     assert!(bufs.is_empty());
 }
 
 #[test]
-fn io_slice_advance() {
+fn io_slice_advance_slices() {
     let buf1 = [1; 8];
     let buf2 = [2; 16];
     let buf3 = [3; 8];
     let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..];
 
     // Only in a single buffer..
-    bufs = IoSlice::advance(bufs, 1);
+    IoSlice::advance_slices(&mut bufs, 1);
     assert_eq!(bufs[0].deref(), [1; 7].as_ref());
     assert_eq!(bufs[1].deref(), [2; 16].as_ref());
     assert_eq!(bufs[2].deref(), [3; 8].as_ref());
 
     // Removing a buffer, leaving others as is.
-    bufs = IoSlice::advance(bufs, 7);
+    IoSlice::advance_slices(&mut bufs, 7);
     assert_eq!(bufs[0].deref(), [2; 16].as_ref());
     assert_eq!(bufs[1].deref(), [3; 8].as_ref());
 
     // Removing a buffer and removing from the next buffer.
-    bufs = IoSlice::advance(bufs, 18);
+    IoSlice::advance_slices(&mut bufs, 18);
     assert_eq!(bufs[0].deref(), [3; 6].as_ref());
 }
 
 #[test]
-fn io_slice_advance_empty_slice() {
-    let empty_bufs = &mut [][..];
+fn io_slice_advance_slices_empty_slice() {
+    let mut empty_bufs = &mut [][..];
     // Shouldn't panic.
-    IoSlice::advance(empty_bufs, 1);
+    IoSlice::advance_slices(&mut empty_bufs, 1);
 }
 
 #[test]
-fn io_slice_advance_beyond_total_length() {
+fn io_slice_advance_slices_beyond_total_length() {
     let buf1 = [1; 8];
     let mut bufs = &mut [IoSlice::new(&buf1)][..];
 
     // Going beyond the total length should be ok.
-    bufs = IoSlice::advance(bufs, 9);
+    IoSlice::advance_slices(&mut bufs, 9);
     assert!(bufs.is_empty());
 }
 
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index 73f2f3eb3f5..a8812f197d8 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -13,9 +13,9 @@ use crate::io::{
 /// This struct is generally created by calling [`empty()`]. Please see
 /// the documentation of [`empty()`] for more details.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Empty {
-    _priv: (),
-}
+#[non_exhaustive]
+#[derive(Copy, Clone, Default)]
+pub struct Empty;
 
 /// Constructs a new handle to an empty reader.
 ///
@@ -35,7 +35,7 @@ pub struct Empty {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
 pub const fn empty() -> Empty {
-    Empty { _priv: () }
+    Empty
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -83,6 +83,7 @@ impl fmt::Debug for Empty {
 }
 
 impl SizeHint for Empty {
+    #[inline]
     fn upper_bound(&self) -> Option<usize> {
         Some(0)
     }
@@ -147,6 +148,18 @@ impl Read for Repeat {
     }
 }
 
+impl SizeHint for Repeat {
+    #[inline]
+    fn lower_bound(&self) -> usize {
+        usize::MAX
+    }
+
+    #[inline]
+    fn upper_bound(&self) -> Option<usize> {
+        None
+    }
+}
+
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for Repeat {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -159,9 +172,9 @@ impl fmt::Debug for Repeat {
 /// This struct is generally created by calling [`sink`]. Please
 /// see the documentation of [`sink()`] for more details.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Sink {
-    _priv: (),
-}
+#[non_exhaustive]
+#[derive(Copy, Clone, Default)]
+pub struct Sink;
 
 /// Creates an instance of a writer which will successfully consume all data.
 ///
@@ -182,7 +195,7 @@ pub struct Sink {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
 pub const fn sink() -> Sink {
-    Sink { _priv: () }
+    Sink
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index ba2b8b6955d..605bd33a4bf 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -971,7 +971,7 @@ mod match_keyword {}
 /// ```
 ///
 /// Like [`struct`]s and [`enum`]s, a module and its content are private by
-/// default, unaccessible to code outside of the module.
+/// default, inaccessible to code outside of the module.
 ///
 /// To learn more about allowing access, see the documentation for the [`pub`]
 /// keyword.
@@ -987,13 +987,13 @@ mod mod_keyword {}
 /// Capture a [closure]'s environment by value.
 ///
 /// `move` converts any variables captured by reference or mutable reference
-/// to owned by value variables.
+/// to variables captured by value.
 ///
 /// ```rust
-/// let capture = "hello";
-/// let closure = move || {
-///     println!("rust says {}", capture);
-/// };
+/// let data = vec![1, 2, 3];
+/// let closure = move || println!("captured {:?} by value", data);
+///
+/// // data is no longer available, it is owned by the closure
 /// ```
 ///
 /// Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though
@@ -1004,31 +1004,29 @@ mod mod_keyword {}
 /// ```rust
 /// fn create_fn() -> impl Fn() {
 ///     let text = "Fn".to_owned();
-///
 ///     move || println!("This is a: {}", text)
 /// }
 ///
 /// let fn_plain = create_fn();
-///
 /// fn_plain();
 /// ```
 ///
 /// `move` is often used when [threads] are involved.
 ///
 /// ```rust
-/// let x = 5;
+/// let data = vec![1, 2, 3];
 ///
 /// std::thread::spawn(move || {
-///     println!("captured {} by value", x)
+///     println!("captured {:?} by value", data)
 /// }).join().unwrap();
 ///
-/// // x is no longer available
+/// // data was moved to the spawned thread, so we cannot use it here
 /// ```
 ///
 /// `move` is also valid before an async block.
 ///
 /// ```rust
-/// let capture = "hello";
+/// let capture = "hello".to_owned();
 /// let block = async move {
 ///     println!("rust says {} from async block", capture);
 /// };
@@ -1094,8 +1092,7 @@ mod move_keyword {}
 /// Mutable raw pointers work much like mutable references, with the added
 /// possibility of not pointing to a valid object. The syntax is `*mut Type`.
 ///
-/// More information on mutable references and pointers can be found in```
-/// [Reference].
+/// More information on mutable references and pointers can be found in the [Reference].
 ///
 /// [Reference]: ../reference/types/pointer.html#mutable-references-mut
 mod mut_keyword {}
@@ -2259,6 +2256,9 @@ mod await_keyword {}
 /// At run-time, when a method needs to be called on the `dyn Trait`, the vtable is consulted to get
 /// the function pointer and then that function pointer is called.
 ///
+/// See the Reference for more information on [trait objects][ref-trait-obj]
+/// and [object safety][ref-obj-safety].
+///
 /// ## Trade-offs
 ///
 /// The above indirection is the additional runtime cost of calling a function on a `dyn Trait`.
@@ -2267,9 +2267,9 @@ mod await_keyword {}
 /// However, `dyn Trait` is likely to produce smaller code than `impl Trait` / generic parameters as
 /// the method won't be duplicated for each concrete type.
 ///
-/// Read more about `object safety` and [trait object]s.
-///
 /// [trait object]: ../book/ch17-02-trait-objects.html
+/// [ref-trait-obj]: ../reference/types/trait-object.html
+/// [ref-obj-safety]: ../reference/items/traits.html#object-safety
 /// [erased]: https://en.wikipedia.org/wiki/Type_erasure
 mod dyn_keyword {}
 
diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs
index ca86e569bc1..5afdb799f0c 100644
--- a/library/std/src/lazy.rs
+++ b/library/std/src/lazy.rs
@@ -86,7 +86,21 @@ impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
 impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
 
 #[unstable(feature = "once_cell", issue = "74465")]
-impl<T> Default for SyncOnceCell<T> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> const Default for SyncOnceCell<T> {
+    /// Creates a new empty cell.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncOnceCell;
+    ///
+    /// fn main() {
+    ///     assert_eq!(SyncOnceCell::<()>::new(), SyncOnceCell::default());
+    /// }
+    /// ```
     fn default() -> SyncOnceCell<T> {
         SyncOnceCell::new()
     }
@@ -118,6 +132,23 @@ impl<T: Clone> Clone for SyncOnceCell<T> {
 
 #[unstable(feature = "once_cell", issue = "74465")]
 impl<T> From<T> for SyncOnceCell<T> {
+    /// Create a new cell with its contents set to `value`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(once_cell)]
+    ///
+    /// use std::lazy::SyncOnceCell;
+    ///
+    /// # fn main() -> Result<(), i32> {
+    /// let a = SyncOnceCell::from(3);
+    /// let b = SyncOnceCell::new();
+    /// b.set(3)?;
+    /// assert_eq!(a, b);
+    /// Ok(())
+    /// # }
+    /// ```
     fn from(value: T) -> Self {
         let cell = Self::new();
         match cell.set(value) {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index c4f21587457..5e91a0cdbd6 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -225,15 +225,17 @@
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
-#![feature(async_stream)]
 #![feature(arbitrary_self_types)]
 #![feature(array_error_internals)]
 #![feature(asm)]
 #![feature(assert_matches)]
 #![feature(associated_type_bounds)]
+#![feature(async_stream)]
 #![feature(atomic_mut_ptr)]
+#![feature(auto_traits)]
 #![feature(bench_black_box)]
 #![feature(box_syntax)]
+#![feature(c_unwind)]
 #![feature(c_variadic)]
 #![feature(cfg_accessible)]
 #![feature(cfg_eval)]
@@ -244,14 +246,16 @@
 #![feature(concat_idents)]
 #![feature(const_cstr_unchecked)]
 #![feature(const_fn_floating_point_arithmetic)]
-#![feature(const_fn_transmute)]
 #![feature(const_fn_fn_ptr_basics)]
+#![cfg_attr(bootstrap, feature(const_fn_transmute))]
+#![feature(const_format_args)]
 #![feature(const_io_structs)]
 #![feature(const_ip)]
+#![feature(const_ipv4)]
 #![feature(const_ipv6)]
 #![feature(const_raw_ptr_deref)]
 #![feature(const_socketaddr)]
-#![feature(const_ipv4)]
+#![feature(const_trait_impl)]
 #![feature(container_error_extra)]
 #![feature(core_intrinsics)]
 #![feature(custom_test_frameworks)]
@@ -260,13 +264,15 @@
 #![feature(doc_keyword)]
 #![feature(doc_masked)]
 #![feature(doc_notable_trait)]
+#![cfg_attr(not(bootstrap), feature(doc_primitive))]
 #![feature(dropck_eyepatch)]
+#![feature(duration_checked_float)]
 #![feature(duration_constants)]
 #![feature(edition_panic)]
 #![feature(exact_size_is_empty)]
 #![feature(exhaustive_patterns)]
 #![feature(extend_one)]
-#![cfg_attr(bootstrap, feature(extended_key_value_attributes))]
+#![feature(float_interpolation)]
 #![feature(fn_traits)]
 #![feature(format_args_nl)]
 #![feature(gen_future)]
@@ -275,8 +281,8 @@
 #![feature(global_asm)]
 #![feature(hashmap_internals)]
 #![feature(int_error_internals)]
-#![feature(int_error_matching)]
 #![feature(integer_atomics)]
+#![feature(int_log)]
 #![feature(into_future)]
 #![feature(intra_doc_pointers)]
 #![feature(iter_zip)]
@@ -286,7 +292,6 @@
 #![feature(log_syntax)]
 #![feature(map_try_insert)]
 #![feature(maybe_uninit_extra)]
-#![feature(maybe_uninit_ref)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(min_specialization)]
@@ -297,19 +302,14 @@
 #![feature(nll)]
 #![feature(nonnull_slice_from_raw_parts)]
 #![feature(once_cell)]
-#![feature(auto_traits)]
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
 #![feature(panic_unwind)]
 #![feature(pin_static_ref)]
-#![feature(prelude_2021)]
 #![feature(prelude_import)]
 #![feature(ptr_internals)]
-#![feature(raw)]
-#![feature(ready_macro)]
 #![feature(rustc_attrs)]
 #![feature(rustc_private)]
-#![feature(shrink_to)]
 #![feature(slice_concat_ext)]
 #![feature(slice_internals)]
 #![feature(slice_ptr_get)]
@@ -327,9 +327,10 @@
 #![feature(trace_macros)]
 #![feature(try_blocks)]
 #![feature(try_reserve)]
+#![feature(try_reserve_kind)]
 #![feature(unboxed_closures)]
 #![feature(unsafe_cell_raw_get)]
-#![feature(unwind_attributes)]
+#![feature(unwrap_infallible)]
 #![feature(vec_into_raw_parts)]
 #![feature(vec_spare_capacity)]
 // NB: the above list is sorted to minimize merge conflicts.
@@ -456,9 +457,6 @@ pub use core::pin;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::ptr;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated, deprecated_in_future)]
-pub use core::raw;
-#[stable(feature = "rust1", since = "1.0.0")]
 pub use core::result;
 #[unstable(feature = "async_stream", issue = "79024")]
 pub use core::stream;
@@ -552,17 +550,17 @@ pub use std_detect::{
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated, deprecated_in_future)]
 pub use core::{
-    assert_eq, assert_matches, assert_ne, debug_assert, debug_assert_eq, debug_assert_matches,
-    debug_assert_ne, matches, r#try, todo, unimplemented, unreachable, write, writeln,
+    assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, r#try, todo,
+    unimplemented, unreachable, write, writeln,
 };
 
 // Re-export built-in macros defined through libcore.
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow(deprecated)]
 pub use core::{
-    asm, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
-    format_args_nl, global_asm, include, include_bytes, include_str, line, llvm_asm, log_syntax,
-    module_path, option_env, stringify, trace_macros,
+    assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args,
+    env, file, format_args, format_args_nl, include, include_bytes, include_str, line, llvm_asm,
+    log_syntax, module_path, option_env, stringify, trace_macros,
 };
 
 #[stable(feature = "core_primitive", since = "1.43.0")]
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index b2c5df5410d..5dc75d32ec8 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -6,7 +6,7 @@
 
 #[doc = include_str!("../../core/src/macros/panic.md")]
 #[macro_export]
-#[rustc_builtin_macro = "std_panic"]
+#[rustc_builtin_macro(std_panic)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(edition_panic)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
@@ -289,7 +289,7 @@ macro_rules! dbg {
     // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
     // will be malformed.
     () => {
-        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
+        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!())
     };
     ($val:expr $(,)?) => {
         // Use of `match` here is intentional because it affects the lifetimes
diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs
index 70376d5e065..d3569710c2b 100644
--- a/library/std/src/net/addr.rs
+++ b/library/std/src/net/addr.rs
@@ -874,7 +874,7 @@ pub trait ToSocketAddrs {
 
     /// Converts this object to an iterator of resolved `SocketAddr`s.
     ///
-    /// The returned iterator may not actually yield any values depending on the
+    /// The returned iterator might not actually yield any values depending on the
     /// outcome of any resolution performed.
     ///
     /// Note that this function may block the current thread while resolution is
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 6c2f2eeabd6..ac92cfe19cd 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -84,13 +84,59 @@ pub struct Ipv4Addr {
 /// IPv6 addresses are defined as 128-bit integers in [IETF RFC 4291].
 /// They are usually represented as eight 16-bit segments.
 ///
-/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
-///
 /// The size of an `Ipv6Addr` struct may vary depending on the target operating
 /// system.
 ///
 /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
 ///
+/// # Embedding IPv4 Addresses
+///
+/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
+///
+/// To assist in the transition from IPv4 to IPv6 two types of IPv6 addresses that embed an IPv4 address were defined:
+/// IPv4-compatible and IPv4-mapped addresses. Of these IPv4-compatible addresses have been officially deprecated.
+///
+/// Both types of addresses are not assigned any special meaning by this implementation,
+/// other than what the relevant standards prescribe. This means that an address like `::ffff:127.0.0.1`,
+/// while representing an IPv4 loopback address, is not itself an IPv6 loopback address; only `::1` is.
+/// To handle these so called "IPv4-in-IPv6" addresses, they have to first be converted to their canonical IPv4 address.
+///
+/// ### IPv4-Compatible IPv6 Addresses
+///
+/// IPv4-compatible IPv6 addresses are defined in [IETF RFC 4291 Section 2.5.5.1], and have been officially deprecated.
+/// The RFC describes the format of an "IPv4-Compatible IPv6 address" as follows:
+///
+/// ```text
+/// |                80 bits               | 16 |      32 bits        |
+/// +--------------------------------------+--------------------------+
+/// |0000..............................0000|0000|    IPv4 address     |
+/// +--------------------------------------+----+---------------------+
+/// ```
+/// So `::a.b.c.d` would be an IPv4-compatible IPv6 address representing the IPv4 address `a.b.c.d`.
+///
+/// To convert from an IPv4 address to an IPv4-compatible IPv6 address, use [`Ipv4Addr::to_ipv6_compatible`].
+/// Use [`Ipv6Addr::to_ipv4`] to convert an IPv4-compatible IPv6 address to the canonical IPv4 address.
+///
+/// [IETF RFC 4291 Section 2.5.5.1]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.1
+///
+/// ### IPv4-Mapped IPv6 Addresses
+///
+/// IPv4-mapped IPv6 addresses are defined in [IETF RFC 4291 Section 2.5.5.2].
+/// The RFC describes the format of an "IPv4-Mapped IPv6 address" as follows:
+///
+/// ```text
+/// |                80 bits               | 16 |      32 bits        |
+/// +--------------------------------------+--------------------------+
+/// |0000..............................0000|FFFF|    IPv4 address     |
+/// +--------------------------------------+----+---------------------+
+/// ```
+/// So `::ffff:a.b.c.d` would be an IPv4-mapped IPv6 address representing the IPv4 address `a.b.c.d`.
+///
+/// To convert from an IPv4 address to an IPv4-mapped IPv6 address, use [`Ipv4Addr::to_ipv6_mapped`].
+/// Use [`Ipv6Addr::to_ipv4`] to convert an IPv4-mapped IPv6 address to the canonical IPv4 address.
+///
+/// [IETF RFC 4291 Section 2.5.5.2]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2
+///
 /// # Textual representation
 ///
 /// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
@@ -116,16 +162,58 @@ pub struct Ipv6Addr {
     inner: c::in6_addr,
 }
 
-#[allow(missing_docs)]
+/// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2].
+///
+/// # Stability Guarantees
+///
+/// Not all possible values for a multicast scope have been assigned.
+/// Future RFCs may introduce new scopes, which will be added as variants to this enum;
+/// because of this the enum is marked as `#[non_exhaustive]`.
+///
+/// # Examples
+/// ```
+/// #![feature(ip)]
+///
+/// use std::net::Ipv6Addr;
+/// use std::net::Ipv6MulticastScope::*;
+///
+/// // An IPv6 multicast address with global scope (`ff0e::`).
+/// let address = Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0);
+///
+/// // Will print "Global scope".
+/// match address.multicast_scope() {
+///     Some(InterfaceLocal) => println!("Interface-Local scope"),
+///     Some(LinkLocal) => println!("Link-Local scope"),
+///     Some(RealmLocal) => println!("Realm-Local scope"),
+///     Some(AdminLocal) => println!("Admin-Local scope"),
+///     Some(SiteLocal) => println!("Site-Local scope"),
+///     Some(OrganizationLocal) => println!("Organization-Local scope"),
+///     Some(Global) => println!("Global scope"),
+///     Some(_) => println!("Unknown scope"),
+///     None => println!("Not a multicast address!")
+/// }
+///
+/// ```
+///
+/// [IPv6 multicast address]: Ipv6Addr
+/// [IETF RFC 7346 section 2]: https://tools.ietf.org/html/rfc7346#section-2
 #[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)]
 #[unstable(feature = "ip", issue = "27709")]
+#[non_exhaustive]
 pub enum Ipv6MulticastScope {
+    /// Interface-Local scope.
     InterfaceLocal,
+    /// Link-Local scope.
     LinkLocal,
+    /// Realm-Local scope.
     RealmLocal,
+    /// Admin-Local scope.
     AdminLocal,
+    /// Site-Local scope.
     SiteLocal,
+    /// Organization-Local scope.
     OrganizationLocal,
+    /// Global scope.
     Global,
 }
 
@@ -291,6 +379,29 @@ impl IpAddr {
     pub const fn is_ipv6(&self) -> bool {
         matches!(self, IpAddr::V6(_))
     }
+
+    /// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped IPv6 addresses, otherwise it
+    /// return `self` as-is.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
+    ///
+    /// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).to_canonical().is_loopback(), true);
+    /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).is_loopback(), false);
+    /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).to_canonical().is_loopback(), true);
+    /// ```
+    #[inline]
+    #[rustc_const_unstable(feature = "const_ip", issue = "76205")]
+    #[unstable(feature = "ip", issue = "27709")]
+    pub const fn to_canonical(&self) -> IpAddr {
+        match self {
+            &v4 @ IpAddr::V4(_) => v4,
+            IpAddr::V6(v6) => v6.to_canonical(),
+        }
+    }
 }
 
 impl Ipv4Addr {
@@ -314,7 +425,7 @@ impl Ipv4Addr {
         Ipv4Addr { inner: c::in_addr { s_addr: u32::from_ne_bytes([a, b, c, d]) } }
     }
 
-    /// An IPv4 address with the address pointing to localhost: 127.0.0.1.
+    /// An IPv4 address with the address pointing to localhost: `127.0.0.1`
     ///
     /// # Examples
     ///
@@ -327,7 +438,7 @@ impl Ipv4Addr {
     #[stable(feature = "ip_constructors", since = "1.30.0")]
     pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1);
 
-    /// An IPv4 address representing an unspecified address: 0.0.0.0
+    /// An IPv4 address representing an unspecified address: `0.0.0.0`
     ///
     /// This corresponds to the constant `INADDR_ANY` in other languages.
     ///
@@ -343,7 +454,7 @@ impl Ipv4Addr {
     #[stable(feature = "ip_constructors", since = "1.30.0")]
     pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0);
 
-    /// An IPv4 address representing the broadcast address: 255.255.255.255
+    /// An IPv4 address representing the broadcast address: `255.255.255.255`
     ///
     /// # Examples
     ///
@@ -374,12 +485,12 @@ impl Ipv4Addr {
         self.inner.s_addr.to_ne_bytes()
     }
 
-    /// Returns [`true`] for the special 'unspecified' address (0.0.0.0).
+    /// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`).
     ///
     /// This property is defined in _UNIX Network Programming, Second Edition_,
     /// W. Richard Stevens, p. 891; see also [ip7].
     ///
-    /// [ip7]: http://man7.org/linux/man-pages/man7/ip.7.html
+    /// [ip7]: https://man7.org/linux/man-pages/man7/ip.7.html
     ///
     /// # Examples
     ///
@@ -396,7 +507,7 @@ impl Ipv4Addr {
         self.inner.s_addr == 0
     }
 
-    /// Returns [`true`] if this is a loopback address (127.0.0.0/8).
+    /// Returns [`true`] if this is a loopback address (`127.0.0.0/8`).
     ///
     /// This property is defined by [IETF RFC 1122].
     ///
@@ -421,9 +532,9 @@ impl Ipv4Addr {
     ///
     /// The private address ranges are defined in [IETF RFC 1918] and include:
     ///
-    ///  - 10.0.0.0/8
-    ///  - 172.16.0.0/12
-    ///  - 192.168.0.0/16
+    ///  - `10.0.0.0/8`
+    ///  - `172.16.0.0/12`
+    ///  - `192.168.0.0/16`
     ///
     /// [IETF RFC 1918]: https://tools.ietf.org/html/rfc1918
     ///
@@ -452,7 +563,7 @@ impl Ipv4Addr {
         }
     }
 
-    /// Returns [`true`] if the address is link-local (169.254.0.0/16).
+    /// Returns [`true`] if the address is link-local (`169.254.0.0/16`).
     ///
     /// This property is defined by [IETF RFC 3927].
     ///
@@ -485,9 +596,8 @@ impl Ipv4Addr {
     /// - the broadcast address (see [`Ipv4Addr::is_broadcast()`])
     /// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`])
     /// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole
-    ///   0.0.0.0/8 block
-    /// - addresses reserved for future protocols (see
-    /// [`Ipv4Addr::is_ietf_protocol_assignment()`], except
+    ///   `0.0.0.0/8` block
+    /// - addresses reserved for future protocols, except
     /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
     /// - addresses reserved for future use (see [`Ipv4Addr::is_reserved()`]
     /// - addresses reserved for networking devices benchmarking (see
@@ -560,7 +670,8 @@ impl Ipv4Addr {
             && !self.is_broadcast()
             && !self.is_documentation()
             && !self.is_shared()
-            && !self.is_ietf_protocol_assignment()
+            // addresses reserved for future protocols (`192.0.0.0/24`)
+            && !(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0)
             && !self.is_reserved()
             && !self.is_benchmarking()
             // Make sure the address is not in 0.0.0.0/8
@@ -589,40 +700,6 @@ impl Ipv4Addr {
         self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
     }
 
-    /// Returns [`true`] if this address is part of `192.0.0.0/24`, which is reserved to
-    /// IANA for IETF protocol assignments, as documented in [IETF RFC 6890].
-    ///
-    /// Note that parts of this block are in use:
-    ///
-    /// - `192.0.0.8/32` is the "IPv4 dummy address" (see [IETF RFC 7600])
-    /// - `192.0.0.9/32` is the "Port Control Protocol Anycast" (see [IETF RFC 7723])
-    /// - `192.0.0.10/32` is used for NAT traversal (see [IETF RFC 8155])
-    ///
-    /// [IETF RFC 6890]: https://tools.ietf.org/html/rfc6890
-    /// [IETF RFC 7600]: https://tools.ietf.org/html/rfc7600
-    /// [IETF RFC 7723]: https://tools.ietf.org/html/rfc7723
-    /// [IETF RFC 8155]: https://tools.ietf.org/html/rfc8155
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(ip)]
-    /// use std::net::Ipv4Addr;
-    ///
-    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_ietf_protocol_assignment(), true);
-    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 8).is_ietf_protocol_assignment(), true);
-    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 9).is_ietf_protocol_assignment(), true);
-    /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_ietf_protocol_assignment(), true);
-    /// assert_eq!(Ipv4Addr::new(192, 0, 1, 0).is_ietf_protocol_assignment(), false);
-    /// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false);
-    /// ```
-    #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
-    #[unstable(feature = "ip", issue = "27709")]
-    #[inline]
-    pub const fn is_ietf_protocol_assignment(&self) -> bool {
-        self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
-    }
-
     /// Returns [`true`] if this address part of the `198.18.0.0/15` range, which is reserved for
     /// network devices benchmarking. This range is defined in [IETF RFC 2544] as `192.18.0.0`
     /// through `198.19.255.255` but [errata 423] corrects it to `198.18.0.0/15`.
@@ -682,9 +759,9 @@ impl Ipv4Addr {
         self.octets()[0] & 240 == 240 && !self.is_broadcast()
     }
 
-    /// Returns [`true`] if this is a multicast address (224.0.0.0/4).
+    /// Returns [`true`] if this is a multicast address (`224.0.0.0/4`).
     ///
-    /// Multicast addresses have a most significant octet between 224 and 239,
+    /// Multicast addresses have a most significant octet between `224` and `239`,
     /// and is defined by [IETF RFC 5771].
     ///
     /// [IETF RFC 5771]: https://tools.ietf.org/html/rfc5771
@@ -705,9 +782,9 @@ impl Ipv4Addr {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
     }
 
-    /// Returns [`true`] if this is a broadcast address (255.255.255.255).
+    /// Returns [`true`] if this is a broadcast address (`255.255.255.255`).
     ///
-    /// A broadcast address has all octets set to 255 as defined in [IETF RFC 919].
+    /// A broadcast address has all octets set to `255` as defined in [IETF RFC 919].
     ///
     /// [IETF RFC 919]: https://tools.ietf.org/html/rfc919
     ///
@@ -730,9 +807,9 @@ impl Ipv4Addr {
     ///
     /// This is defined in [IETF RFC 5737]:
     ///
-    /// - 192.0.2.0/24 (TEST-NET-1)
-    /// - 198.51.100.0/24 (TEST-NET-2)
-    /// - 203.0.113.0/24 (TEST-NET-3)
+    /// - `192.0.2.0/24` (TEST-NET-1)
+    /// - `198.51.100.0/24` (TEST-NET-2)
+    /// - `203.0.113.0/24` (TEST-NET-3)
     ///
     /// [IETF RFC 5737]: https://tools.ietf.org/html/rfc5737
     ///
@@ -758,13 +835,14 @@ impl Ipv4Addr {
         }
     }
 
-    /// Converts this address to an IPv4-compatible [`IPv6` address].
+    /// Converts this address to an [IPv4-compatible] [`IPv6` address].
     ///
-    /// a.b.c.d becomes ::a.b.c.d
+    /// `a.b.c.d` becomes `::a.b.c.d`
     ///
-    /// This isn't typically the method you want; these addresses don't typically
-    /// function on modern systems. Use `to_ipv6_mapped` instead.
+    /// Note that IPv4-compatible addresses have been officially deprecated.
+    /// If you don't explicitly need an IPv4-compatible address for legacy reasons, consider using `to_ipv6_mapped` instead.
     ///
+    /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
     /// [`IPv6` address]: Ipv6Addr
     ///
     /// # Examples
@@ -774,7 +852,7 @@ impl Ipv4Addr {
     ///
     /// assert_eq!(
     ///     Ipv4Addr::new(192, 0, 2, 255).to_ipv6_compatible(),
-    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 49152, 767)
+    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc000, 0x2ff)
     /// );
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
@@ -787,10 +865,11 @@ impl Ipv4Addr {
         }
     }
 
-    /// Converts this address to an IPv4-mapped [`IPv6` address].
+    /// Converts this address to an [IPv4-mapped] [`IPv6` address].
     ///
-    /// a.b.c.d becomes ::ffff:a.b.c.d
+    /// `a.b.c.d` becomes `::ffff:a.b.c.d`
     ///
+    /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
     /// [`IPv6` address]: Ipv6Addr
     ///
     /// # Examples
@@ -799,7 +878,7 @@ impl Ipv4Addr {
     /// use std::net::{Ipv4Addr, Ipv6Addr};
     ///
     /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped(),
-    ///            Ipv6Addr::new(0, 0, 0, 0, 0, 65535, 49152, 767));
+    ///            Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff));
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1087,7 +1166,7 @@ impl Ipv6Addr {
     ///
     /// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
     /// ```
-    #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
     #[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1149,7 +1228,7 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
     ///            [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
     /// ```
-    #[rustc_allow_const_fn_unstable(const_fn_transmute)]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_fn_transmute))]
     #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1172,7 +1251,7 @@ impl Ipv6Addr {
         ]
     }
 
-    /// Returns [`true`] for the special 'unspecified' address (::).
+    /// Returns [`true`] for the special 'unspecified' address (`::`).
     ///
     /// This property is defined in [IETF RFC 4291].
     ///
@@ -1193,11 +1272,13 @@ impl Ipv6Addr {
         u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
     }
 
-    /// Returns [`true`] if this is a loopback address (::1).
+    /// Returns [`true`] if this is the [loopback address] (`::1`),
+    /// as defined in [IETF RFC 4291 section 2.5.3].
     ///
-    /// This property is defined in [IETF RFC 4291].
+    /// Contrary to IPv4, in IPv6 there is only one loopback address.
     ///
-    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [loopback address]: Ipv6Addr::LOCALHOST
+    /// [IETF RFC 4291 section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
     ///
     /// # Examples
     ///
@@ -1267,6 +1348,34 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
+    /// Returns [`true`] if this is a unicast address, as defined by [IETF RFC 4291].
+    /// Any address that is not a [multicast address] (`ff00::/8`) is unicast.
+    ///
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [multicast address]: Ipv6Addr::is_multicast
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    ///
+    /// use std::net::Ipv6Addr;
+    ///
+    /// // The unspecified and loopback addresses are unicast.
+    /// assert_eq!(Ipv6Addr::UNSPECIFIED.is_unicast(), true);
+    /// assert_eq!(Ipv6Addr::LOCALHOST.is_unicast(), true);
+    ///
+    /// // Any address that is not a multicast address (`ff00::/8`) is unicast.
+    /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast(), true);
+    /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_unicast(), false);
+    /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    #[unstable(feature = "ip", issue = "27709")]
+    #[inline]
+    pub const fn is_unicast(&self) -> bool {
+        !self.is_multicast()
+    }
+
     /// Returns `true` if the address is a unicast address with link-local scope,
     /// as defined in [RFC 4291].
     ///
@@ -1318,47 +1427,6 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
-    /// Returns [`true`] if this is a deprecated unicast site-local address (fec0::/10). The
-    /// unicast site-local address format is defined in [RFC 4291 section 2.5.7] as:
-    ///
-    /// ```no_rust
-    /// |   10     |
-    /// |  bits    |         54 bits         |         64 bits            |
-    /// +----------+-------------------------+----------------------------+
-    /// |1111111011|        subnet ID        |       interface ID         |
-    /// +----------+-------------------------+----------------------------+
-    /// ```
-    ///
-    /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(ip)]
-    ///
-    /// use std::net::Ipv6Addr;
-    ///
-    /// assert_eq!(
-    ///     Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local(),
-    ///     false
-    /// );
-    /// assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true);
-    /// ```
-    ///
-    /// # Warning
-    ///
-    /// As per [RFC 3879], the whole `FEC0::/10` prefix is
-    /// deprecated. New software must not support site-local
-    /// addresses.
-    ///
-    /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
-    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
-    #[unstable(feature = "ip", issue = "27709")]
-    #[inline]
-    pub const fn is_unicast_site_local(&self) -> bool {
-        (self.segments()[0] & 0xffc0) == 0xfec0
-    }
-
     /// Returns [`true`] if this is an address reserved for documentation
     /// (`2001:db8::/32`).
     ///
@@ -1417,7 +1485,7 @@ impl Ipv6Addr {
     #[unstable(feature = "ip", issue = "27709")]
     #[inline]
     pub const fn is_unicast_global(&self) -> bool {
-        !self.is_multicast()
+        self.is_unicast()
             && !self.is_loopback()
             && !self.is_unicast_link_local()
             && !self.is_unique_local()
@@ -1460,7 +1528,7 @@ impl Ipv6Addr {
         }
     }
 
-    /// Returns [`true`] if this is a multicast address (ff00::/8).
+    /// Returns [`true`] if this is a multicast address (`ff00::/8`).
     ///
     /// This property is defined by [IETF RFC 4291].
     ///
@@ -1481,13 +1549,14 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xff00) == 0xff00
     }
 
-    /// Converts this address to an [`IPv4` address] if it's an "IPv4-mapped IPv6 address"
-    /// defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
+    /// Converts this address to an [`IPv4` address] if it's an [IPv4-mapped] address,
+    /// as defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
     ///
     /// `::ffff:a.b.c.d` becomes `a.b.c.d`.
     /// All addresses *not* starting with `::ffff` will return `None`.
     ///
     /// [`IPv4` address]: Ipv4Addr
+    /// [IPv4-mapped]: Ipv6Addr
     /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
     ///
     /// # Examples
@@ -1514,12 +1583,19 @@ impl Ipv6Addr {
         }
     }
 
-    /// Converts this address to an [`IPv4` address]. Returns [`None`] if this address is
-    /// neither IPv4-compatible or IPv4-mapped.
+    /// Converts this address to an [`IPv4` address] if it is either
+    /// an [IPv4-compatible] address as defined in [IETF RFC 4291 section 2.5.5.1],
+    /// or an [IPv4-mapped] address as defined in [IETF RFC 4291 section 2.5.5.2],
+    /// otherwise returns [`None`].
     ///
-    /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
+    /// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d`
+    /// All addresses *not* starting with either all zeroes or `::ffff` will return `None`.
     ///
-    /// [`IPv4` address]: Ipv4Addr
+    /// [IPv4 address]: Ipv4Addr
+    /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
+    /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
+    /// [IETF RFC 4291 section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1
+    /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
     ///
     /// # Examples
     ///
@@ -1545,6 +1621,28 @@ impl Ipv6Addr {
         }
     }
 
+    /// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped addresses, otherwise it
+    /// returns self wrapped in a `IpAddr::V6`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    /// use std::net::Ipv6Addr;
+    ///
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false);
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).to_canonical().is_loopback(), true);
+    /// ```
+    #[inline]
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    #[unstable(feature = "ip", issue = "27709")]
+    pub const fn to_canonical(&self) -> IpAddr {
+        if let Some(mapped) = self.to_ipv4_mapped() {
+            return IpAddr::V4(mapped);
+        }
+        IpAddr::V6(*self)
+    }
+
     /// Returns the sixteen eight-bit integers the IPv6 address consists of.
     ///
     /// ```
diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs
index 05f8dea0b7c..dbfab9dde40 100644
--- a/library/std/src/net/ip/tests.rs
+++ b/library/std/src/net/ip/tests.rs
@@ -339,7 +339,6 @@ fn ipv4_properties() {
             let broadcast: u16 = 1 << 6;
             let documentation: u16 = 1 << 7;
             let benchmarking: u16 = 1 << 8;
-            let ietf_protocol_assignment: u16 = 1 << 9;
             let reserved: u16 = 1 << 10;
             let shared: u16 = 1 << 11;
 
@@ -397,12 +396,6 @@ fn ipv4_properties() {
                 assert!(!ip!($s).is_benchmarking());
             }
 
-            if ($mask & ietf_protocol_assignment) == ietf_protocol_assignment {
-                assert!(ip!($s).is_ietf_protocol_assignment());
-            } else {
-                assert!(!ip!($s).is_ietf_protocol_assignment());
-            }
-
             if ($mask & reserved) == reserved {
                 assert!(ip!($s).is_reserved());
             } else {
@@ -426,7 +419,6 @@ fn ipv4_properties() {
     let broadcast: u16 = 1 << 6;
     let documentation: u16 = 1 << 7;
     let benchmarking: u16 = 1 << 8;
-    let ietf_protocol_assignment: u16 = 1 << 9;
     let reserved: u16 = 1 << 10;
     let shared: u16 = 1 << 11;
 
@@ -449,9 +441,9 @@ fn ipv4_properties() {
     check!("198.18.0.0", benchmarking);
     check!("198.18.54.2", benchmarking);
     check!("198.19.255.255", benchmarking);
-    check!("192.0.0.0", ietf_protocol_assignment);
-    check!("192.0.0.255", ietf_protocol_assignment);
-    check!("192.0.0.100", ietf_protocol_assignment);
+    check!("192.0.0.0");
+    check!("192.0.0.255");
+    check!("192.0.0.100");
     check!("240.0.0.0", reserved);
     check!("251.54.1.76", reserved);
     check!("254.255.255.255", reserved);
@@ -480,7 +472,6 @@ fn ipv6_properties() {
             let unique_local: u16 = 1 << 2;
             let global: u16 = 1 << 3;
             let unicast_link_local: u16 = 1 << 4;
-            let unicast_site_local: u16 = 1 << 6;
             let unicast_global: u16 = 1 << 7;
             let documentation: u16 = 1 << 8;
             let multicast_interface_local: u16 = 1 << 9;
@@ -523,11 +514,6 @@ fn ipv6_properties() {
             } else {
                 assert!(!ip!($s).is_unicast_link_local());
             }
-            if ($mask & unicast_site_local) == unicast_site_local {
-                assert!(ip!($s).is_unicast_site_local());
-            } else {
-                assert!(!ip!($s).is_unicast_site_local());
-            }
             if ($mask & unicast_global) == unicast_global {
                 assert!(ip!($s).is_unicast_global());
             } else {
@@ -581,7 +567,6 @@ fn ipv6_properties() {
     let unique_local: u16 = 1 << 2;
     let global: u16 = 1 << 3;
     let unicast_link_local: u16 = 1 << 4;
-    let unicast_site_local: u16 = 1 << 6;
     let unicast_global: u16 = 1 << 7;
     let documentation: u16 = 1 << 8;
     let multicast_interface_local: u16 = 1 << 9;
@@ -651,7 +636,7 @@ fn ipv6_properties() {
     check!(
         "fec0::",
         &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        unicast_site_local | unicast_global | global
+        unicast_global | global
     );
 
     check!(
@@ -830,9 +815,6 @@ fn ipv4_const() {
     const IS_SHARED: bool = IP_ADDRESS.is_shared();
     assert!(!IS_SHARED);
 
-    const IS_IETF_PROTOCOL_ASSIGNMENT: bool = IP_ADDRESS.is_ietf_protocol_assignment();
-    assert!(!IS_IETF_PROTOCOL_ASSIGNMENT);
-
     const IS_BENCHMARKING: bool = IP_ADDRESS.is_benchmarking();
     assert!(!IS_BENCHMARKING);
 
@@ -889,9 +871,6 @@ fn ipv6_const() {
     const IS_UNICAST_LINK_LOCAL: bool = IP_ADDRESS.is_unicast_link_local();
     assert!(!IS_UNICAST_LINK_LOCAL);
 
-    const IS_UNICAST_SITE_LOCAL: bool = IP_ADDRESS.is_unicast_site_local();
-    assert!(!IS_UNICAST_SITE_LOCAL);
-
     const IS_DOCUMENTATION: bool = IP_ADDRESS.is_documentation();
     assert!(!IS_DOCUMENTATION);
 
diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs
index abe9bc24cec..387a3617e5e 100644
--- a/library/std/src/net/tcp/tests.rs
+++ b/library/std/src/net/tcp/tests.rs
@@ -342,7 +342,7 @@ fn double_bind() {
             Err(e) => {
                 assert!(
                     e.kind() == ErrorKind::ConnectionRefused
-                        || e.kind() == ErrorKind::Other
+                        || e.kind() == ErrorKind::Uncategorized
                         || e.kind() == ErrorKind::AddrInUse,
                     "unknown error: {} {:?}",
                     e,
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index 18297139b7b..d2088a12b2c 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -408,7 +408,7 @@ impl UdpSocket {
     /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
     ///
     /// If enabled, multicast packets will be looped back to the local socket.
-    /// Note that this may not have any effect on IPv6 sockets.
+    /// Note that this might not have any effect on IPv6 sockets.
     ///
     /// # Examples
     ///
@@ -447,7 +447,7 @@ impl UdpSocket {
     /// this socket. The default value is 1 which means that multicast packets
     /// don't leave the local network unless explicitly requested.
     ///
-    /// Note that this may not have any effect on IPv6 sockets.
+    /// Note that this might not have any effect on IPv6 sockets.
     ///
     /// # Examples
     ///
@@ -483,7 +483,7 @@ impl UdpSocket {
     /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
     ///
     /// Controls whether this socket sees the multicast packets it sends itself.
-    /// Note that this may not have any affect on IPv4 sockets.
+    /// Note that this might not have any affect on IPv4 sockets.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/num.rs b/library/std/src/num.rs
index 0f1c5962685..e7051f0ce95 100644
--- a/library/std/src/num.rs
+++ b/library/std/src/num.rs
@@ -22,12 +22,7 @@ pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8,
 #[stable(feature = "nonzero", since = "1.28.0")]
 pub use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
 
-#[unstable(
-    feature = "int_error_matching",
-    reason = "it can be useful to match errors when making error messages \
-              for integer parsing",
-    issue = "22639"
-)]
+#[stable(feature = "int_error_matching", since = "1.55.0")]
 pub use core::num::IntErrorKind;
 
 #[cfg(test)]
diff --git a/library/std/src/os/espidf/fs.rs b/library/std/src/os/espidf/fs.rs
new file mode 100644
index 00000000000..93dc2c0cab7
--- /dev/null
+++ b/library/std/src/os/espidf/fs.rs
@@ -0,0 +1,117 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+#[allow(deprecated)]
+use crate::os::espidf::raw;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: crate::fs::Metadata
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    #[rustc_deprecated(
+        since = "1.8.0",
+        reason = "deprecated in favor of the accessor \
+                  methods of this trait"
+    )]
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat;
+
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_spare4(&self) -> [u32; 2];
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat {
+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
+    }
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        0
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        0
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        0
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+    fn st_spare4(&self) -> [u32; 2] {
+        let spare4 = self.as_inner().as_inner().st_spare4;
+        [spare4[0] as u32, spare4[1] as u32]
+    }
+}
diff --git a/library/std/src/os/espidf/mod.rs b/library/std/src/os/espidf/mod.rs
new file mode 100644
index 00000000000..a9cef970930
--- /dev/null
+++ b/library/std/src/os/espidf/mod.rs
@@ -0,0 +1,6 @@
+//! Definitions for the ESP-IDF framework.
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod fs;
+pub mod raw;
diff --git a/library/std/src/os/espidf/raw.rs b/library/std/src/os/espidf/raw.rs
new file mode 100644
index 00000000000..fb18ec6f6f8
--- /dev/null
+++ b/library/std/src/os/espidf/raw.rs
@@ -0,0 +1,69 @@
+//! Raw type definitions for the ESP-IDF framework.
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![rustc_deprecated(
+    since = "1.8.0",
+    reason = "these type aliases are no longer supported by \
+              the standard library, the `libc` crate on \
+              crates.io should be used instead for the correct \
+              definitions"
+)]
+
+use crate::os::raw::c_long;
+use crate::os::unix::raw::{gid_t, uid_t};
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = libc::pthread_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blkcnt_t = libc::blkcnt_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blksize_t = libc::blksize_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type dev_t = libc::dev_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type ino_t = libc::ino_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type mode_t = libc::mode_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type nlink_t = libc::nlink_t;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type off_t = libc::off_t;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type time_t = libc::time_t;
+
+#[repr(C)]
+#[derive(Clone)]
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub struct stat {
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_dev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ino: ino_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mode: mode_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_nlink: nlink_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_uid: uid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gid: gid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_rdev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_size: off_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blksize: blksize_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blocks: blkcnt_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_spare4: [c_long; 2usize],
+}
diff --git a/library/std/src/os/fortanix_sgx/arch.rs b/library/std/src/os/fortanix_sgx/arch.rs
index b0170e67446..4ce482e23cb 100644
--- a/library/std/src/os/fortanix_sgx/arch.rs
+++ b/library/std/src/os/fortanix_sgx/arch.rs
@@ -33,13 +33,13 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32>
 
         asm!(
             // rbx is reserved by LLVM
-            "xchg {0}, rbx",
+            "xchg %rbx, {0}",
             "enclu",
-            "mov rbx, {0}",
+            "mov {0}, %rbx",
             inout(reg) request => _,
             inlateout("eax") ENCLU_EGETKEY => error,
             in("rcx") out.as_mut_ptr(),
-            options(nostack),
+            options(att_syntax, nostack),
         );
 
         match error {
@@ -64,14 +64,14 @@ pub fn ereport(
 
         asm!(
             // rbx is reserved by LLVM
-            "xchg {0}, rbx",
+            "xchg %rbx, {0}",
             "enclu",
-            "mov rbx, {0}",
+            "mov {0}, %rbx",
             inout(reg) targetinfo => _,
             in("eax") ENCLU_EREPORT,
             in("rcx") reportdata,
             in("rdx") report.as_mut_ptr(),
-            options(preserves_flags, nostack),
+            options(att_syntax, preserves_flags, nostack),
         );
 
         report.assume_init()
diff --git a/library/std/src/os/fortanix_sgx/ffi.rs b/library/std/src/os/fortanix_sgx/ffi.rs
index 63fc5ff2866..ac1db0e5e39 100644
--- a/library/std/src/os/fortanix_sgx/ffi.rs
+++ b/library/std/src/os/fortanix_sgx/ffi.rs
@@ -34,5 +34,8 @@
 
 #![unstable(feature = "sgx_platform", issue = "56975")]
 
+#[path = "../unix/ffi/os_str.rs"]
+mod os_str;
+
 #[unstable(feature = "sgx_platform", issue = "56975")]
-pub use crate::sys_common::os_str_bytes::*;
+pub use self::os_str::{OsStrExt, OsStringExt};
diff --git a/library/std/src/os/hermit/ffi.rs b/library/std/src/os/hermit/ffi.rs
index 07b59a02556..19761fd99b4 100644
--- a/library/std/src/os/hermit/ffi.rs
+++ b/library/std/src/os/hermit/ffi.rs
@@ -34,5 +34,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[path = "../unix/ffi/os_str.rs"]
+mod os_str;
+
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use crate::sys_common::os_str_bytes::*;
+pub use self::os_str::{OsStrExt, OsStringExt};
diff --git a/library/std/src/os/linux/mod.rs b/library/std/src/os/linux/mod.rs
index 94438defc22..8e7776f6646 100644
--- a/library/std/src/os/linux/mod.rs
+++ b/library/std/src/os/linux/mod.rs
@@ -4,4 +4,5 @@
 #![doc(cfg(target_os = "linux"))]
 
 pub mod fs;
+pub mod process;
 pub mod raw;
diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs
new file mode 100644
index 00000000000..6daff0f003c
--- /dev/null
+++ b/library/std/src/os/linux/process.rs
@@ -0,0 +1,145 @@
+//! Linux-specific extensions to primitives in the `std::process` module.
+
+#![unstable(feature = "linux_pidfd", issue = "82971")]
+
+use crate::io::Result;
+use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+use crate::process;
+use crate::sealed::Sealed;
+#[cfg(not(doc))]
+use crate::sys::fd::FileDesc;
+use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
+
+#[cfg(doc)]
+struct FileDesc;
+
+/// This type represents a file descriptor that refers to a process.
+///
+/// A `PidFd` can be obtained by setting the corresponding option on [`Command`]
+/// with [`create_pidfd`]. Subsequently, the created pidfd can be retrieved
+/// from the [`Child`] by calling [`pidfd`] or [`take_pidfd`].
+///
+/// Example:
+/// ```no_run
+/// #![feature(linux_pidfd)]
+/// use std::os::linux::process::{CommandExt, ChildExt};
+/// use std::process::Command;
+///
+/// let mut child = Command::new("echo")
+///     .create_pidfd(true)
+///     .spawn()
+///     .expect("Failed to spawn child");
+///
+/// let pidfd = child
+///     .take_pidfd()
+///     .expect("Failed to retrieve pidfd");
+///
+/// // The file descriptor will be closed when `pidfd` is dropped.
+/// ```
+/// Refer to the man page of [`pidfd_open(2)`] for further details.
+///
+/// [`Command`]: process::Command
+/// [`create_pidfd`]: CommandExt::create_pidfd
+/// [`Child`]: process::Child
+/// [`pidfd`]: fn@ChildExt::pidfd
+/// [`take_pidfd`]: ChildExt::take_pidfd
+/// [`pidfd_open(2)`]: https://man7.org/linux/man-pages/man2/pidfd_open.2.html
+#[derive(Debug)]
+pub struct PidFd {
+    inner: FileDesc,
+}
+
+impl AsInner<FileDesc> for PidFd {
+    fn as_inner(&self) -> &FileDesc {
+        &self.inner
+    }
+}
+
+impl FromInner<FileDesc> for PidFd {
+    fn from_inner(inner: FileDesc) -> PidFd {
+        PidFd { inner }
+    }
+}
+
+impl IntoInner<FileDesc> for PidFd {
+    fn into_inner(self) -> FileDesc {
+        self.inner
+    }
+}
+
+impl AsRawFd for PidFd {
+    fn as_raw_fd(&self) -> RawFd {
+        self.as_inner().raw()
+    }
+}
+
+impl FromRawFd for PidFd {
+    unsafe fn from_raw_fd(fd: RawFd) -> Self {
+        Self::from_inner(FileDesc::new(fd))
+    }
+}
+
+impl IntoRawFd for PidFd {
+    fn into_raw_fd(self) -> RawFd {
+        self.into_inner().into_raw()
+    }
+}
+
+/// Os-specific extensions for [`Child`]
+///
+/// [`Child`]: process::Child
+pub trait ChildExt: Sealed {
+    /// Obtains a reference to the [`PidFd`] created for this [`Child`], if available.
+    ///
+    /// A pidfd will only be available if its creation was requested with
+    /// [`create_pidfd`] when the corresponding [`Command`] was created.
+    ///
+    /// Even if requested, a pidfd may not be available due to an older
+    /// version of Linux being in use, or if some other error occurred.
+    ///
+    /// [`Command`]: process::Command
+    /// [`create_pidfd`]: CommandExt::create_pidfd
+    /// [`Child`]: process::Child
+    fn pidfd(&self) -> Result<&PidFd>;
+
+    /// Takes ownership of the [`PidFd`] created for this [`Child`], if available.
+    ///
+    /// A pidfd will only be available if its creation was requested with
+    /// [`create_pidfd`] when the corresponding [`Command`] was created.
+    ///
+    /// Even if requested, a pidfd may not be available due to an older
+    /// version of Linux being in use, or if some other error occurred.
+    ///
+    /// [`Command`]: process::Command
+    /// [`create_pidfd`]: CommandExt::create_pidfd
+    /// [`Child`]: process::Child
+    fn take_pidfd(&mut self) -> Result<PidFd>;
+}
+
+/// Os-specific extensions for [`Command`]
+///
+/// [`Command`]: process::Command
+pub trait CommandExt: Sealed {
+    /// Sets whether a [`PidFd`](struct@PidFd) should be created for the [`Child`]
+    /// spawned by this [`Command`].
+    /// By default, no pidfd will be created.
+    ///
+    /// The pidfd can be retrieved from the child with [`pidfd`] or [`take_pidfd`].
+    ///
+    /// A pidfd will only be created if it is possible to do so
+    /// in a guaranteed race-free manner (e.g. if the `clone3` system call
+    /// is supported). Otherwise, [`pidfd`] will return an error.
+    ///
+    /// [`Command`]: process::Command
+    /// [`Child`]: process::Child
+    /// [`pidfd`]: fn@ChildExt::pidfd
+    /// [`take_pidfd`]: ChildExt::take_pidfd
+    fn create_pidfd(&mut self, val: bool) -> &mut process::Command;
+}
+
+impl CommandExt for process::Command {
+    fn create_pidfd(&mut self, val: bool) -> &mut process::Command {
+        self.as_inner_mut().create_pidfd(val);
+        self
+    }
+}
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 07e29ebf368..4c9814919cd 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -80,6 +80,8 @@ mod imp {
     pub mod dragonfly;
     #[cfg(target_os = "emscripten")]
     pub mod emscripten;
+    #[cfg(target_os = "espidf")]
+    pub mod espidf;
     #[cfg(target_os = "freebsd")]
     pub mod freebsd;
     #[cfg(target_os = "fuchsia")]
diff --git a/library/std/src/os/unix/ffi.rs b/library/std/src/os/unix/ffi/mod.rs
index 123f85deaf9..c29df6596fd 100644
--- a/library/std/src/os/unix/ffi.rs
+++ b/library/std/src/os/unix/ffi/mod.rs
@@ -34,5 +34,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+mod os_str;
+
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use crate::sys_common::os_str_bytes::*;
+pub use self::os_str::{OsStrExt, OsStringExt};
diff --git a/library/std/src/os/unix/ffi/os_str.rs b/library/std/src/os/unix/ffi/os_str.rs
new file mode 100644
index 00000000000..54c9a9382f2
--- /dev/null
+++ b/library/std/src/os/unix/ffi/os_str.rs
@@ -0,0 +1,68 @@
+use crate::ffi::{OsStr, OsString};
+use crate::mem;
+use crate::sealed::Sealed;
+use crate::sys::os_str::Buf;
+use crate::sys_common::{AsInner, FromInner, IntoInner};
+
+// Note: this file is currently reused in other `std::os::{platform}::ffi` modules to reduce duplication.
+// Keep this in mind when applying changes to this file that only apply to `unix`.
+
+/// Platform-specific extensions to [`OsString`].
+///
+/// This trait is sealed: it cannot be implemented outside the standard library.
+/// This is so that future additional methods are not breaking changes.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStringExt: Sealed {
+    /// Creates an [`OsString`] from a byte vector.
+    ///
+    /// See the module documentation for an example.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn from_vec(vec: Vec<u8>) -> Self;
+
+    /// Yields the underlying byte vector of this [`OsString`].
+    ///
+    /// See the module documentation for an example.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into_vec(self) -> Vec<u8>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStringExt for OsString {
+    fn from_vec(vec: Vec<u8>) -> OsString {
+        FromInner::from_inner(Buf { inner: vec })
+    }
+    fn into_vec(self) -> Vec<u8> {
+        self.into_inner().inner
+    }
+}
+
+/// Platform-specific extensions to [`OsStr`].
+///
+/// This trait is sealed: it cannot be implemented outside the standard library.
+/// This is so that future additional methods are not breaking changes.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStrExt: Sealed {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    /// Creates an [`OsStr`] from a byte slice.
+    ///
+    /// See the module documentation for an example.
+    fn from_bytes(slice: &[u8]) -> &Self;
+
+    /// Gets the underlying byte view of the [`OsStr`] slice.
+    ///
+    /// See the module documentation for an example.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn as_bytes(&self) -> &[u8];
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStrExt for OsStr {
+    #[inline]
+    fn from_bytes(slice: &[u8]) -> &OsStr {
+        unsafe { mem::transmute(slice) }
+    }
+    #[inline]
+    fn as_bytes(&self) -> &[u8] {
+        &self.as_inner().inner
+    }
+}
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index 913c71d4108..e4ce788f741 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -9,6 +9,8 @@ use crate::path::Path;
 use crate::sys;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
 // Used for `File::read` on intra-doc links
+use crate::ffi::OsStr;
+use crate::sealed::Sealed;
 #[allow(unused_imports)]
 use io::{Read, Write};
 
@@ -839,6 +841,43 @@ impl DirEntryExt for fs::DirEntry {
     }
 }
 
+/// Sealed Unix-specific extension methods for [`fs::DirEntry`].
+#[unstable(feature = "dir_entry_ext2", issue = "85573")]
+pub trait DirEntryExt2: Sealed {
+    /// Returns a reference to the underlying `OsStr` of this entry's filename.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(dir_entry_ext2)]
+    /// use std::os::unix::fs::DirEntryExt2;
+    /// use std::{fs, io};
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut entries = fs::read_dir(".")?.collect::<Result<Vec<_>, io::Error>>()?;
+    ///     entries.sort_unstable_by(|a, b| a.file_name_ref().cmp(b.file_name_ref()));
+    ///
+    ///     for p in entries {
+    ///         println!("{:?}", p);
+    ///     }
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    fn file_name_ref(&self) -> &OsStr;
+}
+
+/// Allows extension traits within `std`.
+#[unstable(feature = "sealed", issue = "none")]
+impl Sealed for fs::DirEntry {}
+
+#[unstable(feature = "dir_entry_ext2", issue = "85573")]
+impl DirEntryExt2 for fs::DirEntry {
+    fn file_name_ref(&self) -> &OsStr {
+        self.as_inner().file_name_os_str()
+    }
+}
+
 /// Creates a new symbolic link on the filesystem.
 ///
 /// The `link` path will be a symbolic link pointing to the `original` path.
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index 6fc1c89a2ba..6c73d4b21dd 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -40,6 +40,8 @@ mod platform {
     pub use crate::os::dragonfly::*;
     #[cfg(target_os = "emscripten")]
     pub use crate::os::emscripten::*;
+    #[cfg(target_os = "espidf")]
+    pub use crate::os::espidf::*;
     #[cfg(target_os = "freebsd")]
     pub use crate::os::freebsd::*;
     #[cfg(target_os = "fuchsia")]
@@ -82,6 +84,7 @@ pub mod thread;
     target_os = "freebsd",
     target_os = "ios",
     target_os = "macos",
+    target_os = "netbsd",
     target_os = "openbsd"
 ))]
 pub mod ucred;
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 459f3590e64..62bfde8bfd4 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -31,7 +31,7 @@ pub(super) unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un,
     if bytes.contains(&0) {
         return Err(io::Error::new_const(
             io::ErrorKind::InvalidInput,
-            &"paths may not contain interior null bytes",
+            &"paths must not contain interior null bytes",
         ));
     }
 
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 15ce7056fea..cd429d14269 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -32,23 +32,8 @@ pub(super) fn recv_vectored_with_ancillary_from(
         msg.msg_name = &mut msg_name as *mut _ as *mut _;
         msg.msg_namelen = size_of::<libc::sockaddr_un>() as libc::socklen_t;
         msg.msg_iov = bufs.as_mut_ptr().cast();
-        cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
-                msg.msg_iovlen = bufs.len() as libc::size_t;
-                msg.msg_controllen = ancillary.buffer.len() as libc::size_t;
-            } else if #[cfg(any(
-                          target_os = "dragonfly",
-                          target_os = "emscripten",
-                          target_os = "freebsd",
-                          all(target_os = "linux", target_env = "musl",),
-                          target_os = "macos",
-                          target_os = "netbsd",
-                          target_os = "openbsd",
-                      ))] {
-                msg.msg_iovlen = bufs.len() as libc::c_int;
-                msg.msg_controllen = ancillary.buffer.len() as libc::socklen_t;
-            }
-        }
+        msg.msg_iovlen = bufs.len() as _;
+        msg.msg_controllen = ancillary.buffer.len() as _;
         // macos requires that the control pointer is null when the len is 0.
         if msg.msg_controllen > 0 {
             msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
@@ -80,23 +65,8 @@ pub(super) fn send_vectored_with_ancillary_to(
         msg.msg_name = &mut msg_name as *mut _ as *mut _;
         msg.msg_namelen = msg_namelen;
         msg.msg_iov = bufs.as_ptr() as *mut _;
-        cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
-                msg.msg_iovlen = bufs.len() as libc::size_t;
-                msg.msg_controllen = ancillary.length as libc::size_t;
-            } else if #[cfg(any(
-                          target_os = "dragonfly",
-                          target_os = "emscripten",
-                          target_os = "freebsd",
-                          all(target_os = "linux", target_env = "musl",),
-                          target_os = "macos",
-                          target_os = "netbsd",
-                          target_os = "openbsd",
-                      ))] {
-                msg.msg_iovlen = bufs.len() as libc::c_int;
-                msg.msg_controllen = ancillary.length as libc::socklen_t;
-            }
-        }
+        msg.msg_iovlen = bufs.len() as _;
+        msg.msg_controllen = ancillary.length as _;
         // macos requires that the control pointer is null when the len is 0.
         if msg.msg_controllen > 0 {
             msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
@@ -144,21 +114,7 @@ fn add_to_ancillary_data<T>(
 
         let mut msg: libc::msghdr = zeroed();
         msg.msg_control = buffer.as_mut_ptr().cast();
-        cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
-                msg.msg_controllen = *length as libc::size_t;
-            } else if #[cfg(any(
-                          target_os = "dragonfly",
-                          target_os = "emscripten",
-                          target_os = "freebsd",
-                          all(target_os = "linux", target_env = "musl",),
-                          target_os = "macos",
-                          target_os = "netbsd",
-                          target_os = "openbsd",
-                      ))] {
-                msg.msg_controllen = *length as libc::socklen_t;
-            }
-        }
+        msg.msg_controllen = *length as _;
 
         let mut cmsg = libc::CMSG_FIRSTHDR(&msg);
         let mut previous_cmsg = cmsg;
@@ -180,21 +136,7 @@ fn add_to_ancillary_data<T>(
 
         (*previous_cmsg).cmsg_level = cmsg_level;
         (*previous_cmsg).cmsg_type = cmsg_type;
-        cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
-                (*previous_cmsg).cmsg_len = libc::CMSG_LEN(source_len) as libc::size_t;
-            } else if #[cfg(any(
-                          target_os = "dragonfly",
-                          target_os = "emscripten",
-                          target_os = "freebsd",
-                          all(target_os = "linux", target_env = "musl",),
-                          target_os = "macos",
-                          target_os = "netbsd",
-                          target_os = "openbsd",
-                      ))] {
-                (*previous_cmsg).cmsg_len = libc::CMSG_LEN(source_len) as libc::socklen_t;
-            }
-        }
+        (*previous_cmsg).cmsg_len = libc::CMSG_LEN(source_len) as _;
 
         let data = libc::CMSG_DATA(previous_cmsg).cast();
 
@@ -364,28 +306,10 @@ impl<'a> AncillaryData<'a> {
 
     fn try_from_cmsghdr(cmsg: &'a libc::cmsghdr) -> Result<Self, AncillaryError> {
         unsafe {
-            cfg_if::cfg_if! {
-                if #[cfg(any(
-                        target_os = "android",
-                        all(target_os = "linux", target_env = "gnu"),
-                        all(target_os = "linux", target_env = "uclibc"),
-                   ))] {
-                    let cmsg_len_zero = libc::CMSG_LEN(0) as libc::size_t;
-                } else if #[cfg(any(
-                              target_os = "dragonfly",
-                              target_os = "emscripten",
-                              target_os = "freebsd",
-                              all(target_os = "linux", target_env = "musl",),
-                              target_os = "macos",
-                              target_os = "netbsd",
-                              target_os = "openbsd",
-                          ))] {
-                    let cmsg_len_zero = libc::CMSG_LEN(0) as libc::socklen_t;
-                }
-            }
-            let data_len = (*cmsg).cmsg_len - cmsg_len_zero;
+            let cmsg_len_zero = libc::CMSG_LEN(0) as usize;
+            let data_len = (*cmsg).cmsg_len as usize - cmsg_len_zero;
             let data = libc::CMSG_DATA(cmsg).cast();
-            let data = from_raw_parts(data, data_len as usize);
+            let data = from_raw_parts(data, data_len);
 
             match (*cmsg).cmsg_level {
                 libc::SOL_SOCKET => match (*cmsg).cmsg_type {
@@ -419,21 +343,7 @@ impl<'a> Iterator for Messages<'a> {
         unsafe {
             let mut msg: libc::msghdr = zeroed();
             msg.msg_control = self.buffer.as_ptr() as *mut _;
-            cfg_if::cfg_if! {
-                if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
-                    msg.msg_controllen = self.buffer.len() as libc::size_t;
-                } else if #[cfg(any(
-                              target_os = "dragonfly",
-                              target_os = "emscripten",
-                              target_os = "freebsd",
-                              all(target_os = "linux", target_env = "musl",),
-                              target_os = "macos",
-                              target_os = "netbsd",
-                              target_os = "openbsd",
-                          ))] {
-                    msg.msg_controllen = self.buffer.len() as libc::socklen_t;
-                }
-            }
+            msg.msg_controllen = self.buffer.len() as _;
 
             let cmsg = if let Some(current) = self.current {
                 libc::CMSG_NXTHDR(&msg, current)
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index a6f6e091305..fba084375e5 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -21,6 +21,7 @@ use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
     target_os = "freebsd",
     target_os = "ios",
     target_os = "macos",
+    target_os = "netbsd",
     target_os = "openbsd"
 ))]
 use crate::os::unix::ucred;
@@ -38,6 +39,7 @@ use crate::time::Duration;
     target_os = "freebsd",
     target_os = "ios",
     target_os = "macos",
+    target_os = "netbsd",
     target_os = "openbsd"
 ))]
 pub use ucred::UCred;
@@ -208,6 +210,7 @@ impl UnixStream {
         target_os = "freebsd",
         target_os = "ios",
         target_os = "macos",
+        target_os = "netbsd",
         target_os = "openbsd"
     ))]
     pub fn peer_cred(&self) -> io::Result<UCred> {
diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs
index 3dc389b7582..615290d2703 100644
--- a/library/std/src/os/unix/process.rs
+++ b/library/std/src/os/unix/process.rs
@@ -83,7 +83,7 @@ pub trait CommandExt: Sealed {
     ///
     /// When this closure is run, aspects such as the stdio file descriptors and
     /// working directory have successfully been changed, so output to these
-    /// locations may not appear where intended.
+    /// locations might not appear where intended.
     ///
     /// [POSIX fork() specification]:
     ///     https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html
@@ -226,7 +226,7 @@ pub trait ExitStatusExt: Sealed {
     ///
     /// Panics on an attempt to make an `ExitStatusError` from a wait status of `0`.
     ///
-    /// Making an `ExitStatus` always succeds and never panics.
+    /// Making an `ExitStatus` always succeeds and never panics.
     #[stable(feature = "exit_status_from", since = "1.12.0")]
     fn from_raw(raw: i32) -> Self;
 
diff --git a/library/std/src/os/unix/ucred.rs b/library/std/src/os/unix/ucred.rs
index 1b4c18d3d84..32e6430d3f6 100644
--- a/library/std/src/os/unix/ucred.rs
+++ b/library/std/src/os/unix/ucred.rs
@@ -28,7 +28,12 @@ pub struct UCred {
 #[cfg(any(target_os = "android", target_os = "linux"))]
 pub use self::impl_linux::peer_cred;
 
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
+#[cfg(any(
+    target_os = "dragonfly",
+    target_os = "freebsd",
+    target_os = "openbsd",
+    target_os = "netbsd"
+))]
 pub use self::impl_bsd::peer_cred;
 
 #[cfg(any(target_os = "macos", target_os = "ios",))]
@@ -70,7 +75,12 @@ pub mod impl_linux {
     }
 }
 
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
+#[cfg(any(
+    target_os = "dragonfly",
+    target_os = "freebsd",
+    target_os = "openbsd",
+    target_os = "netbsd"
+))]
 pub mod impl_bsd {
     use super::UCred;
     use crate::io;
diff --git a/library/std/src/os/wasi/ffi.rs b/library/std/src/os/wasi/ffi.rs
index f71f316d1ba..17e12a395a6 100644
--- a/library/std/src/os/wasi/ffi.rs
+++ b/library/std/src/os/wasi/ffi.rs
@@ -2,5 +2,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[path = "../unix/ffi/os_str.rs"]
+mod os_str;
+
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use crate::sys_common::os_str_bytes::*;
+pub use self::os_str::{OsStrExt, OsStringExt};
diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs
index ba4057bd34c..bd30d6ae3f3 100644
--- a/library/std/src/os/wasi/fs.rs
+++ b/library/std/src/os/wasi/fs.rs
@@ -1,7 +1,7 @@
 //! WASI-specific extensions to primitives in the `std::fs` module.
 
 #![deny(unsafe_op_in_unsafe_fn)]
-#![unstable(feature = "wasi_ext", issue = "none")]
+#![unstable(feature = "wasi_ext", issue = "71213")]
 
 use crate::ffi::OsStr;
 use crate::fs::{self, File, Metadata, OpenOptions};
@@ -532,5 +532,6 @@ pub fn symlink_path<P: AsRef<Path>, U: AsRef<Path>>(old_path: P, new_path: U) ->
 }
 
 fn osstr2str(f: &OsStr) -> io::Result<&str> {
-    f.to_str().ok_or_else(|| io::Error::new_const(io::ErrorKind::Other, &"input must be utf-8"))
+    f.to_str()
+        .ok_or_else(|| io::Error::new_const(io::ErrorKind::Uncategorized, &"input must be utf-8"))
 }
diff --git a/library/std/src/os/wasi/io.rs b/library/std/src/os/wasi/io.rs
index b2e79cc1b4a..b6bc74da8e7 100644
--- a/library/std/src/os/wasi/io.rs
+++ b/library/std/src/os/wasi/io.rs
@@ -1,16 +1,23 @@
 //! WASI-specific extensions to general I/O primitives
 
 #![deny(unsafe_op_in_unsafe_fn)]
-#![unstable(feature = "wasi_ext", issue = "none")]
+#![unstable(feature = "wasi_ext", issue = "71213")]
 
 use crate::fs;
 use crate::io;
 use crate::net;
+use crate::os::raw;
 use crate::sys;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 
 /// Raw file descriptors.
-pub type RawFd = u32;
+///
+/// This has type `c_int` to ease compatibility with code that also compiles on
+/// Unix configurations, however unlike Unix and POSIX, in WASI negative file
+/// descriptors are valid. Only `-1` is reserved for indicating errors. Code
+/// intending to be portable across Unix platforms and WASI should avoid
+/// assuming that negative file descriptors are invalid.
+pub type RawFd = raw::c_int;
 
 /// A trait to extract the raw WASI file descriptor from an underlying
 /// object.
@@ -161,41 +168,41 @@ impl IntoRawFd for fs::File {
 impl AsRawFd for io::Stdin {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDIN_FILENO as RawFd
+        libc::STDIN_FILENO
     }
 }
 
 impl AsRawFd for io::Stdout {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDOUT_FILENO as RawFd
+        libc::STDOUT_FILENO
     }
 }
 
 impl AsRawFd for io::Stderr {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDERR_FILENO as RawFd
+        libc::STDERR_FILENO
     }
 }
 
 impl<'a> AsRawFd for io::StdinLock<'a> {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDIN_FILENO as RawFd
+        libc::STDIN_FILENO
     }
 }
 
 impl<'a> AsRawFd for io::StdoutLock<'a> {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDOUT_FILENO as RawFd
+        libc::STDOUT_FILENO
     }
 }
 
 impl<'a> AsRawFd for io::StderrLock<'a> {
     #[inline]
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDERR_FILENO as RawFd
+        libc::STDERR_FILENO
     }
 }
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 67756b15531..9e7ccd015b6 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -2,6 +2,7 @@
 
 #![stable(feature = "process_extensions", since = "1.2.0")]
 
+use crate::ffi::OsStr;
 use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
 use crate::process;
 use crate::sealed::Sealed;
@@ -125,6 +126,13 @@ pub trait CommandExt: Sealed {
     /// [2]: <https://msdn.microsoft.com/en-us/library/17w5ykft.aspx>
     #[unstable(feature = "windows_process_extensions_force_quotes", issue = "82227")]
     fn force_quotes(&mut self, enabled: bool) -> &mut process::Command;
+
+    /// Append literal text to the command line without any quoting or escaping.
+    ///
+    /// This is useful for passing arguments to `cmd.exe /c`, which doesn't follow
+    /// `CommandLineToArgvW` escaping rules.
+    #[unstable(feature = "windows_process_extensions_raw_arg", issue = "29494")]
+    fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut process::Command;
 }
 
 #[stable(feature = "windows_process_extensions", since = "1.16.0")]
@@ -138,4 +146,9 @@ impl CommandExt for process::Command {
         self.as_inner_mut().force_quotes(enabled);
         self
     }
+
+    fn raw_arg<S: AsRef<OsStr>>(&mut self, raw_text: S) -> &mut process::Command {
+        self.as_inner_mut().raw_arg(raw_text.as_ref());
+        self
+    }
 }
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 9e3880dfd41..c1c03958497 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -3,24 +3,14 @@
 #![stable(feature = "std_panic", since = "1.9.0")]
 
 use crate::any::Any;
-use crate::cell::UnsafeCell;
 use crate::collections;
-use crate::fmt;
-use crate::future::Future;
-use crate::ops::{Deref, DerefMut};
 use crate::panicking;
-use crate::pin::Pin;
-use crate::ptr::{NonNull, Unique};
-use crate::rc::Rc;
-use crate::stream::Stream;
-use crate::sync::atomic;
-use crate::sync::{Arc, Mutex, RwLock};
-use crate::task::{Context, Poll};
+use crate::sync::{Mutex, RwLock};
 use crate::thread::Result;
 
 #[doc(hidden)]
 #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
-#[allow_internal_unstable(libstd_sys_internals)]
+#[allow_internal_unstable(libstd_sys_internals, const_format_args)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro panic_2015 {
@@ -31,7 +21,7 @@ pub macro panic_2015 {
         $crate::rt::begin_panic($msg)
     }),
     ($fmt:expr, $($arg:tt)+) => ({
-        $crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+))
+        $crate::rt::begin_panic_fmt(&$crate::const_format_args!($fmt, $($arg)+))
     }),
 }
 
@@ -45,6 +35,9 @@ pub use crate::panicking::{set_hook, take_hook};
 #[stable(feature = "panic_hooks", since = "1.10.0")]
 pub use core::panic::{Location, PanicInfo};
 
+#[stable(feature = "catch_unwind", since = "1.9.0")]
+pub use core::panic::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};
+
 /// Panic the current thread with the given message as the panic payload.
 ///
 /// The message can be of any (`Any + Send`) type, not just strings.
@@ -60,259 +53,16 @@ pub fn panic_any<M: 'static + Any + Send>(msg: M) -> ! {
     crate::panicking::begin_panic(msg);
 }
 
-/// A marker trait which represents "panic safe" types in Rust.
-///
-/// This trait is implemented by default for many types and behaves similarly in
-/// terms of inference of implementation to the [`Send`] and [`Sync`] traits. The
-/// purpose of this trait is to encode what types are safe to cross a [`catch_unwind`]
-/// boundary with no fear of unwind safety.
-///
-/// ## What is unwind safety?
-///
-/// In Rust a function can "return" early if it either panics or calls a
-/// function which transitively panics. This sort of control flow is not always
-/// anticipated, and has the possibility of causing subtle bugs through a
-/// combination of two critical components:
-///
-/// 1. A data structure is in a temporarily invalid state when the thread
-///    panics.
-/// 2. This broken invariant is then later observed.
-///
-/// Typically in Rust, it is difficult to perform step (2) because catching a
-/// panic involves either spawning a thread (which in turns makes it difficult
-/// to later witness broken invariants) or using the `catch_unwind` function in this
-/// module. Additionally, even if an invariant is witnessed, it typically isn't a
-/// problem in Rust because there are no uninitialized values (like in C or C++).
-///
-/// It is possible, however, for **logical** invariants to be broken in Rust,
-/// which can end up causing behavioral bugs. Another key aspect of unwind safety
-/// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
-/// memory unsafety.
-///
-/// That was a bit of a whirlwind tour of unwind safety, but for more information
-/// about unwind safety and how it applies to Rust, see an [associated RFC][rfc].
-///
-/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
-///
-/// ## What is `UnwindSafe`?
-///
-/// Now that we've got an idea of what unwind safety is in Rust, it's also
-/// important to understand what this trait represents. As mentioned above, one
-/// way to witness broken invariants is through the `catch_unwind` function in this
-/// module as it allows catching a panic and then re-using the environment of
-/// the closure.
-///
-/// Simply put, a type `T` implements `UnwindSafe` if it cannot easily allow
-/// witnessing a broken invariant through the use of `catch_unwind` (catching a
-/// panic). This trait is an auto trait, so it is automatically implemented for
-/// many types, and it is also structurally composed (e.g., a struct is unwind
-/// safe if all of its components are unwind safe).
-///
-/// Note, however, that this is not an unsafe trait, so there is not a succinct
-/// contract that this trait is providing. Instead it is intended as more of a
-/// "speed bump" to alert users of `catch_unwind` that broken invariants may be
-/// witnessed and may need to be accounted for.
-///
-/// ## Who implements `UnwindSafe`?
-///
-/// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
-/// unwind safe. The general idea is that any mutable state which can be shared
-/// across `catch_unwind` is not unwind safe by default. This is because it is very
-/// easy to witness a broken invariant outside of `catch_unwind` as the data is
-/// simply accessed as usual.
-///
-/// Types like `&Mutex<T>`, however, are unwind safe because they implement
-/// poisoning by default. They still allow witnessing a broken invariant, but
-/// they already provide their own "speed bumps" to do so.
-///
-/// ## When should `UnwindSafe` be used?
-///
-/// It is not intended that most types or functions need to worry about this trait.
-/// It is only used as a bound on the `catch_unwind` function and as mentioned
-/// above, the lack of `unsafe` means it is mostly an advisory. The
-/// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be
-/// implemented for any closed over variables passed to `catch_unwind`.
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-#[cfg_attr(all(not(bootstrap), not(test)), lang = "unwind_safe")]
-#[rustc_on_unimplemented(
-    message = "the type `{Self}` may not be safely transferred across an unwind boundary",
-    label = "`{Self}` may not be safely transferred across an unwind boundary"
-)]
-pub auto trait UnwindSafe {}
-
-/// A marker trait representing types where a shared reference is considered
-/// unwind safe.
-///
-/// This trait is namely not implemented by [`UnsafeCell`], the root of all
-/// interior mutability.
-///
-/// This is a "helper marker trait" used to provide impl blocks for the
-/// [`UnwindSafe`] trait, for more information see that documentation.
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-#[cfg_attr(all(not(bootstrap), not(test)), lang = "ref_unwind_safe")]
-#[rustc_on_unimplemented(
-    message = "the type `{Self}` may contain interior mutability and a reference may not be safely \
-               transferrable across a catch_unwind boundary",
-    label = "`{Self}` may contain interior mutability and a reference may not be safely \
-             transferrable across a catch_unwind boundary"
-)]
-pub auto trait RefUnwindSafe {}
-
-/// A simple wrapper around a type to assert that it is unwind safe.
-///
-/// When using [`catch_unwind`] it may be the case that some of the closed over
-/// variables are not unwind safe. For example if `&mut T` is captured the
-/// compiler will generate a warning indicating that it is not unwind safe. It
-/// may not be the case, however, that this is actually a problem due to the
-/// specific usage of [`catch_unwind`] if unwind safety is specifically taken into
-/// account. This wrapper struct is useful for a quick and lightweight
-/// annotation that a variable is indeed unwind safe.
-///
-/// # Examples
-///
-/// One way to use `AssertUnwindSafe` is to assert that the entire closure
-/// itself is unwind safe, bypassing all checks for all variables:
-///
-/// ```
-/// use std::panic::{self, AssertUnwindSafe};
-///
-/// let mut variable = 4;
-///
-/// // This code will not compile because the closure captures `&mut variable`
-/// // which is not considered unwind safe by default.
-///
-/// // panic::catch_unwind(|| {
-/// //     variable += 3;
-/// // });
-///
-/// // This, however, will compile due to the `AssertUnwindSafe` wrapper
-/// let result = panic::catch_unwind(AssertUnwindSafe(|| {
-///     variable += 3;
-/// }));
-/// // ...
-/// ```
-///
-/// Wrapping the entire closure amounts to a blanket assertion that all captured
-/// variables are unwind safe. This has the downside that if new captures are
-/// added in the future, they will also be considered unwind safe. Therefore,
-/// you may prefer to just wrap individual captures, as shown below. This is
-/// more annotation, but it ensures that if a new capture is added which is not
-/// unwind safe, you will get a compilation error at that time, which will
-/// allow you to consider whether that new capture in fact represent a bug or
-/// not.
-///
-/// ```
-/// use std::panic::{self, AssertUnwindSafe};
-///
-/// let mut variable = 4;
-/// let other_capture = 3;
-///
-/// let result = {
-///     let mut wrapper = AssertUnwindSafe(&mut variable);
-///     panic::catch_unwind(move || {
-///         **wrapper += other_capture;
-///     })
-/// };
-/// // ...
-/// ```
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-pub struct AssertUnwindSafe<T>(#[stable(feature = "catch_unwind", since = "1.9.0")] pub T);
-
-// Implementations of the `UnwindSafe` trait:
-//
-// * By default everything is unwind safe
-// * pointers T contains mutability of some form are not unwind safe
-// * Unique, an owning pointer, lifts an implementation
-// * Types like Mutex/RwLock which are explicitly poisoned are unwind safe
-// * Our custom AssertUnwindSafe wrapper is indeed unwind safe
-
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T: ?Sized> !UnwindSafe for &mut T {}
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T: RefUnwindSafe + ?Sized> UnwindSafe for &T {}
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
-#[unstable(feature = "ptr_internals", issue = "none")]
-impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
-#[stable(feature = "nonnull", since = "1.25.0")]
-impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: ?Sized> UnwindSafe for Mutex<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: ?Sized> UnwindSafe for RwLock<T> {}
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T> UnwindSafe for AssertUnwindSafe<T> {}
-
-// not covered via the Shared impl above b/c the inner contents use
-// Cell/AtomicUsize, but the usage here is unwind safe so we can lift the
-// impl up one level to Arc/Rc itself
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
-
-// Pretty simple implementations for the `RefUnwindSafe` marker trait,
-// basically just saying that `UnsafeCell` is the
-// only thing which doesn't implement it (which then transitively applies to
-// everything else).
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
 
 #[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
 impl<T: ?Sized> RefUnwindSafe for Mutex<T> {}
 #[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
 impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}
 
-#[cfg(target_has_atomic_load_store = "ptr")]
-#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
-impl RefUnwindSafe for atomic::AtomicIsize {}
-#[cfg(target_has_atomic_load_store = "8")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicI8 {}
-#[cfg(target_has_atomic_load_store = "16")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicI16 {}
-#[cfg(target_has_atomic_load_store = "32")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicI32 {}
-#[cfg(target_has_atomic_load_store = "64")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicI64 {}
-#[cfg(target_has_atomic_load_store = "128")]
-#[unstable(feature = "integer_atomics", issue = "32976")]
-impl RefUnwindSafe for atomic::AtomicI128 {}
-
-#[cfg(target_has_atomic_load_store = "ptr")]
-#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
-impl RefUnwindSafe for atomic::AtomicUsize {}
-#[cfg(target_has_atomic_load_store = "8")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicU8 {}
-#[cfg(target_has_atomic_load_store = "16")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicU16 {}
-#[cfg(target_has_atomic_load_store = "32")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicU32 {}
-#[cfg(target_has_atomic_load_store = "64")]
-#[stable(feature = "integer_atomics_stable", since = "1.34.0")]
-impl RefUnwindSafe for atomic::AtomicU64 {}
-#[cfg(target_has_atomic_load_store = "128")]
-#[unstable(feature = "integer_atomics", issue = "32976")]
-impl RefUnwindSafe for atomic::AtomicU128 {}
-
-#[cfg(target_has_atomic_load_store = "8")]
-#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
-impl RefUnwindSafe for atomic::AtomicBool {}
-
-#[cfg(target_has_atomic_load_store = "ptr")]
-#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
-impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
-
 // https://github.com/rust-lang/rust/issues/62301
 #[stable(feature = "hashbrown", since = "1.36.0")]
 impl<K, V, S> UnwindSafe for collections::HashMap<K, V, S>
@@ -323,61 +73,6 @@ where
 {
 }
 
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T> Deref for AssertUnwindSafe<T> {
-    type Target = T;
-
-    fn deref(&self) -> &T {
-        &self.0
-    }
-}
-
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<T> DerefMut for AssertUnwindSafe<T> {
-    fn deref_mut(&mut self) -> &mut T {
-        &mut self.0
-    }
-}
-
-#[stable(feature = "catch_unwind", since = "1.9.0")]
-impl<R, F: FnOnce() -> R> FnOnce<()> for AssertUnwindSafe<F> {
-    type Output = R;
-
-    extern "rust-call" fn call_once(self, _args: ()) -> R {
-        (self.0)()
-    }
-}
-
-#[stable(feature = "std_debug", since = "1.16.0")]
-impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_tuple("AssertUnwindSafe").field(&self.0).finish()
-    }
-}
-
-#[stable(feature = "futures_api", since = "1.36.0")]
-impl<F: Future> Future for AssertUnwindSafe<F> {
-    type Output = F::Output;
-
-    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-        let pinned_field = unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) };
-        F::poll(pinned_field, cx)
-    }
-}
-
-#[unstable(feature = "async_stream", issue = "79024")]
-impl<S: Stream> Stream for AssertUnwindSafe<S> {
-    type Item = S::Item;
-
-    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<S::Item>> {
-        unsafe { self.map_unchecked_mut(|x| &mut x.0) }.poll_next(cx)
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.0.size_hint()
-    }
-}
-
 /// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
 ///
 /// This function will return `Ok` with the closure's result if the closure
@@ -406,7 +101,7 @@ impl<S: Stream> Stream for AssertUnwindSafe<S> {
 ///
 /// # Notes
 ///
-/// Note that this function **may not catch all panics** in Rust. A panic in
+/// Note that this function **might not catch all panics** in Rust. A panic in
 /// Rust is not always implemented via unwinding, but can be implemented by
 /// aborting the process as well. This function *only* catches unwinding panics,
 /// not those that abort the process.
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 02957e75a74..7de70091bec 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -19,7 +19,7 @@ use crate::process;
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::stdio::panic_output;
 use crate::sys_common::backtrace::{self, RustBacktrace};
-use crate::sys_common::rwlock::RWLock;
+use crate::sys_common::rwlock::StaticRWLock;
 use crate::sys_common::thread_info;
 use crate::thread;
 
@@ -43,11 +43,13 @@ use realstd::io::set_output_capture;
 #[allow(improper_ctypes)]
 extern "C" {
     fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static);
+}
 
+#[allow(improper_ctypes)]
+extern "C-unwind" {
     /// `payload` is passed through another layer of raw pointers as `&mut dyn Trait` is not
     /// FFI-safe. `BoxMeUp` lazily performs allocation only when needed (this avoids allocations
     /// when using the "abort" panic runtime).
-    #[unwind(allowed)]
     fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32;
 }
 
@@ -74,7 +76,7 @@ enum Hook {
     Custom(*mut (dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send)),
 }
 
-static HOOK_LOCK: RWLock = RWLock::new();
+static HOOK_LOCK: StaticRWLock = StaticRWLock::new();
 static mut HOOK: Hook = Hook::Default;
 
 /// Registers a custom panic hook, replacing any that was previously registered.
@@ -117,10 +119,10 @@ pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) {
     }
 
     unsafe {
-        HOOK_LOCK.write();
+        let guard = HOOK_LOCK.write();
         let old_hook = HOOK;
         HOOK = Hook::Custom(Box::into_raw(hook));
-        HOOK_LOCK.write_unlock();
+        drop(guard);
 
         if let Hook::Custom(ptr) = old_hook {
             #[allow(unused_must_use)]
@@ -165,10 +167,10 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
     }
 
     unsafe {
-        HOOK_LOCK.write();
+        let guard = HOOK_LOCK.write();
         let hook = HOOK;
         HOOK = Hook::Default;
-        HOOK_LOCK.write_unlock();
+        drop(guard);
 
         match hook {
             Hook::Default => Box::new(default_hook),
@@ -193,7 +195,7 @@ fn default_hook(info: &PanicInfo<'_>) {
         Some(s) => *s,
         None => match info.payload().downcast_ref::<String>() {
             Some(s) => &s[..],
-            None => "Box<Any>",
+            None => "Box<dyn Any>",
         },
     };
     let thread = thread_info::current_thread();
@@ -448,6 +450,7 @@ pub fn panicking() -> bool {
 #[cfg_attr(not(feature = "panic_immediate_abort"), track_caller)]
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cfg_attr(all(not(bootstrap), not(test)), lang = "begin_panic_fmt")]
 pub fn begin_panic_fmt(msg: &fmt::Arguments<'_>) -> ! {
     if cfg!(feature = "panic_immediate_abort") {
         intrinsics::abort()
@@ -459,7 +462,6 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments<'_>) -> ! {
 
 /// Entry point of panics from the libcore crate (`panic_impl` lang item).
 #[cfg_attr(not(test), panic_handler)]
-#[unwind(allowed)]
 pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
     struct PanicPayload<'a> {
         inner: &'a fmt::Arguments<'a>,
@@ -608,7 +610,7 @@ fn rust_panic_with_hook(
 
     unsafe {
         let mut info = PanicInfo::internal_constructor(message, location);
-        HOOK_LOCK.read();
+        let _guard = HOOK_LOCK.read();
         match HOOK {
             // Some platforms (like wasm) know that printing to stderr won't ever actually
             // print anything, and if that's the case we can skip the default
@@ -626,7 +628,6 @@ fn rust_panic_with_hook(
                 (*ptr)(&info);
             }
         };
-        HOOK_LOCK.read_unlock();
     }
 
     if panics > 1 {
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index ede147aca12..69419145b1b 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -951,7 +951,7 @@ impl FusedIterator for Components<'_> {}
 impl<'a> cmp::PartialEq for Components<'a> {
     #[inline]
     fn eq(&self, other: &Components<'a>) -> bool {
-        Iterator::eq(self.clone(), other.clone())
+        Iterator::eq(self.clone().rev(), other.clone().rev())
     }
 }
 
@@ -1398,7 +1398,7 @@ impl PathBuf {
     /// Invokes [`shrink_to`] on the underlying instance of [`OsString`].
     ///
     /// [`shrink_to`]: OsString::shrink_to
-    #[unstable(feature = "shrink_to", issue = "56431")]
+    #[stable(feature = "shrink_to", since = "1.56.0")]
     #[inline]
     pub fn shrink_to(&mut self, min_capacity: usize) {
         self.inner.shrink_to(min_capacity)
@@ -2592,6 +2592,32 @@ impl Path {
         fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
     }
 
+    /// Returns true if the path exists on disk and is pointing at a symbolic link.
+    ///
+    /// This function will not traverse symbolic links.
+    /// In case of a broken symbolic link this will also return true.
+    ///
+    /// If you cannot access the directory containing the file, e.g., because of a
+    /// permission error, this will return false.
+    ///
+    /// # Examples
+    ///
+    #[cfg_attr(unix, doc = "```no_run")]
+    #[cfg_attr(not(unix), doc = "```ignore")]
+    /// #![feature(is_symlink)]
+    /// use std::path::Path;
+    /// use std::os::unix::fs::symlink;
+    ///
+    /// let link_path = Path::new("link");
+    /// symlink("/origin_does_not_exists/", link_path).unwrap();
+    /// assert_eq!(link_path.is_symlink(), true);
+    /// assert_eq!(link_path.exists(), false);
+    /// ```
+    #[unstable(feature = "is_symlink", issue = "85748")]
+    pub fn is_symlink(&self) -> bool {
+        fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
+    }
+
     /// Converts a [`Box<Path>`](Box) into a [`PathBuf`] without copying or
     /// allocating.
     #[stable(feature = "into_boxed_path", since = "1.20.0")]
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 12d52cc8e0b..d4bf6aeefee 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -25,8 +25,10 @@
 //!
 //! # Prelude contents
 //!
-//! The current version of the prelude (version 1) lives in
-//! [`std::prelude::v1`], and re-exports the following:
+//! The first version of the prelude is used in Rust 2015 and Rust 2018,
+//! and lives in [`std::prelude::v1`].
+//! [`std::prelude::rust_2015`] and [`std::prelude::rust_2018`] re-export this prelude.
+//! It re-exports the following:
 //!
 //! * <code>[std::marker]::{[Copy], [Send], [Sized], [Sync], [Unpin]}</code>,
 //!   marker traits that indicate fundamental properties of types.
@@ -58,6 +60,12 @@
 //! * <code>[std::string]::{[String], [ToString]}</code>, heap-allocated strings.
 //! * <code>[std::vec]::[Vec]</code>, a growable, heap-allocated vector.
 //!
+//! The prelude used in Rust 2021, [`std::prelude::rust_2021`], includes all of the above,
+//! and in addition re-exports:
+//!
+//! * <code>[std::convert]::{[TryFrom], [TryInto]}</code>,
+//! * <code>[std::iter]::[FromIterator]</code>.
+//!
 //! [mem::drop]: crate::mem::drop
 //! [std::borrow]: crate::borrow
 //! [std::boxed]: crate::boxed
@@ -71,10 +79,16 @@
 //! [std::ops]: crate::ops
 //! [std::option]: crate::option
 //! [`std::prelude::v1`]: v1
+//! [`std::prelude::rust_2015`]: rust_2015
+//! [`std::prelude::rust_2018`]: rust_2018
+//! [`std::prelude::rust_2021`]: rust_2021
 //! [std::result]: crate::result
 //! [std::slice]: crate::slice
 //! [std::string]: crate::string
 //! [std::vec]: mod@crate::vec
+//! [TryFrom]: crate::convert::TryFrom
+//! [TryInto]: crate::convert::TryInto
+//! [FromIterator]: crate::iter::FromIterator
 //! [`to_owned`]: crate::borrow::ToOwned::to_owned
 //! [book-closures]: ../../book/ch13-01-closures.html
 //! [book-dtor]: ../../book/ch15-03-drop.html
@@ -88,9 +102,9 @@ pub mod v1;
 /// The 2015 version of the prelude of The Rust Standard Library.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2015", issue = "85684")]
+#[stable(feature = "prelude_2015", since = "1.55.0")]
 pub mod rust_2015 {
-    #[unstable(feature = "prelude_2015", issue = "85684")]
+    #[stable(feature = "prelude_2015", since = "1.55.0")]
     #[doc(no_inline)]
     pub use super::v1::*;
 }
@@ -98,9 +112,9 @@ pub mod rust_2015 {
 /// The 2018 version of the prelude of The Rust Standard Library.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2018", issue = "85684")]
+#[stable(feature = "prelude_2018", since = "1.55.0")]
 pub mod rust_2018 {
-    #[unstable(feature = "prelude_2018", issue = "85684")]
+    #[stable(feature = "prelude_2018", since = "1.55.0")]
     #[doc(no_inline)]
     pub use super::v1::*;
 }
@@ -108,13 +122,13 @@ pub mod rust_2018 {
 /// The 2021 version of the prelude of The Rust Standard Library.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2021", issue = "85684")]
+#[stable(feature = "prelude_2021", since = "1.55.0")]
 pub mod rust_2021 {
-    #[unstable(feature = "prelude_2021", issue = "85684")]
+    #[stable(feature = "prelude_2021", since = "1.55.0")]
     #[doc(no_inline)]
     pub use super::v1::*;
 
-    #[unstable(feature = "prelude_2021", issue = "85684")]
+    #[stable(feature = "prelude_2021", since = "1.55.0")]
     #[doc(no_inline)]
     pub use core::prelude::rust_2021::*;
 }
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index 4a3c3ba1635..772044f0149 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -39,12 +39,28 @@ pub use crate::result::Result::{self, Err, Ok};
 #[allow(deprecated)]
 #[doc(no_inline)]
 pub use core::prelude::v1::{
-    asm, assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
-    format_args_nl, global_asm, include, include_bytes, include_str, line, llvm_asm, log_syntax,
-    module_path, option_env, stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord,
-    PartialEq, PartialOrd,
+    assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
+    format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path,
+    option_env, stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq,
+    PartialOrd,
 };
 
+#[unstable(
+    feature = "asm",
+    issue = "72016",
+    reason = "inline assembly is not stable enough for use and is subject to change"
+)]
+#[doc(no_inline)]
+pub use core::prelude::v1::asm;
+
+#[unstable(
+    feature = "global_asm",
+    issue = "35119",
+    reason = "`global_asm!` is not stable enough for use and is subject to change"
+)]
+#[doc(no_inline)]
+pub use core::prelude::v1::global_asm;
+
 // FIXME: Attribute and internal derive macros are not documented because for them rustdoc generates
 // dead links which fail link checker testing.
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index 8a3e425350a..dc4572cd936 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -277,8 +277,8 @@ mod prim_never {}
 /// scalar value]', which is similar to, but not the same as, a '[Unicode code
 /// point]'.
 ///
-/// [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
-/// [Unicode code point]: http://www.unicode.org/glossary/#code_point
+/// [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
+/// [Unicode code point]: https://www.unicode.org/glossary/#code_point
 ///
 /// This documentation describes a number of methods and trait implementations on the
 /// `char` type. For technical reasons, there is additional, separate
@@ -303,7 +303,7 @@ mod prim_never {}
 ///
 /// [`String`]: string/struct.String.html
 ///
-/// As always, remember that a human intuition for 'character' may not map to
+/// As always, remember that a human intuition for 'character' might not map to
 /// Unicode's definitions. For example, despite looking similar, the 'é'
 /// character is one Unicode code point while 'é' is two Unicode code points:
 ///
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 6903ba90560..f5ce5210f81 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -166,7 +166,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// [`wait`]: Child::wait
 #[stable(feature = "process", since = "1.0.0")]
 pub struct Child {
-    handle: imp::Process,
+    pub(crate) handle: imp::Process,
 
     /// The handle for writing to the child's standard input (stdin), if it has
     /// been captured. To avoid partially moving
@@ -205,6 +205,10 @@ pub struct Child {
     pub stderr: Option<ChildStderr>,
 }
 
+/// Allows extension traits within `std`.
+#[unstable(feature = "sealed", issue = "none")]
+impl crate::sealed::Sealed for Child {}
+
 impl AsInner<imp::Process> for Child {
     fn as_inner(&self) -> &imp::Process {
         &self.handle
@@ -452,7 +456,7 @@ impl fmt::Debug for ChildStderr {
 ///
 /// let output = if cfg!(target_os = "windows") {
 ///     Command::new("cmd")
-///             .args(&["/C", "echo hello"])
+///             .args(["/C", "echo hello"])
 ///             .output()
 ///             .expect("failed to execute process")
 /// } else {
@@ -609,7 +613,7 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .args(&["-l", "-a"])
+    ///         .args(["-l", "-a"])
     ///         .spawn()
     ///         .expect("ls command failed to start");
     /// ```
@@ -1453,7 +1457,7 @@ impl ExitStatus {
     ///
     /// In Unix terms the return value is the **exit status**: the value passed to `exit`, if the
     /// process finished by calling `exit`.  Note that on Unix the exit status is truncated to 8
-    /// bits, and that values that didn't come from a program's call to `exit` may be invented the
+    /// bits, and that values that didn't come from a program's call to `exit` may be invented by the
     /// runtime system (often, for example, 255, 254, 127 or 126).
     ///
     /// On Unix, this will return `None` if the process was terminated by a signal.
@@ -1568,7 +1572,7 @@ impl ExitStatusError {
 
     /// Reports the exit code, if applicable, from an `ExitStatusError`, as a `NonZero`
     ///
-    /// This is exaclty like [`code()`](Self::code), except that it returns a `NonZeroI32`.
+    /// This is exactly like [`code()`](Self::code), except that it returns a `NonZeroI32`.
     ///
     /// Plain `code`, returning a plain integer, is provided because is is often more convenient.
     /// The returned value from `code()` is indeed also nonzero; use `code_nonzero()` when you want
@@ -1658,8 +1662,7 @@ impl Child {
     /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
     /// error is returned.
     ///
-    /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function,
-    /// especially the [`Other`] kind might change to more specific kinds in the future.
+    /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function.
     ///
     /// This is equivalent to sending a SIGKILL on Unix platforms.
     ///
@@ -1680,7 +1683,6 @@ impl Child {
     ///
     /// [`ErrorKind`]: io::ErrorKind
     /// [`InvalidInput`]: io::ErrorKind::InvalidInput
-    /// [`Other`]: io::ErrorKind::Other
     #[stable(feature = "process", since = "1.0.0")]
     pub fn kill(&mut self) -> io::Result<()> {
         self.handle.kill()
@@ -1900,6 +1902,9 @@ pub fn exit(code: i32) -> ! {
 /// process, no destructors on the current stack or any other thread's stack
 /// will be run.
 ///
+/// Rust IO buffers (eg, from `BufWriter`) will not be flushed.
+/// Likewise, C stdio buffers will (on most platforms) not be flushed.
+///
 /// This is in contrast to the default behaviour of [`panic!`] which unwinds
 /// the current thread's stack and calls all destructors.
 /// When `panic="abort"` is set, either as an argument to `rustc` or in a
@@ -1910,6 +1915,10 @@ pub fn exit(code: i32) -> ! {
 /// this function at a known point where there are no more destructors left
 /// to run.
 ///
+/// The process's termination will be similar to that from the C `abort()`
+/// function.  On Unix, the process will terminate with signal `SIGABRT`, which
+/// typically means that the shell prints "Aborted".
+///
 /// # Examples
 ///
 /// ```no_run
diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs
index 05e093434be..bc71c150550 100644
--- a/library/std/src/process/tests.rs
+++ b/library/std/src/process/tests.rs
@@ -399,3 +399,12 @@ fn test_command_implements_send_sync() {
     fn take_send_sync_type<T: Send + Sync>(_: T) {}
     take_send_sync_type(Command::new(""))
 }
+
+// Ensure that starting a process with no environment variables works on Windows.
+// This will fail if the environment block is ill-formed.
+#[test]
+#[cfg(windows)]
+fn env_empty() {
+    let p = Command::new("cmd").args(&["/C", "exit 0"]).env_clear().spawn();
+    assert!(p.is_ok());
+}
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 1e19aff51f8..72e6c23ee49 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -24,18 +24,32 @@ fn lang_start_internal(
     main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),
     argc: isize,
     argv: *const *const u8,
-) -> isize {
-    use crate::panic;
-    use crate::sys_common;
-
+) -> Result<isize, !> {
+    use crate::{mem, panic, sys, sys_common};
+    let rt_abort = move |e| {
+        mem::forget(e);
+        rtabort!("initialization or cleanup bug");
+    };
+    // Guard against the code called by this function from unwinding outside of the Rust-controlled
+    // code, which is UB. This is a requirement imposed by a combination of how the
+    // `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking
+    // mechanism itself.
+    //
+    // There are a couple of instances where unwinding can begin. First is inside of the
+    // `rt::init`, `rt::cleanup` and similar functions controlled by libstd. In those instances a
+    // panic is a libstd implementation bug. A quite likely one too, as there isn't any way to
+    // prevent libstd from accidentally introducing a panic to these functions. Another is from
+    // user code from `main` or, more nefariously, as described in e.g. issue #86030.
     // SAFETY: Only called once during runtime initialization.
-    unsafe { sys_common::rt::init(argc, argv) };
-
-    let exit_code = panic::catch_unwind(main);
-
-    sys_common::rt::cleanup();
-
-    exit_code.unwrap_or(101) as isize
+    panic::catch_unwind(move || unsafe { sys_common::rt::init(argc, argv) }).map_err(rt_abort)?;
+    let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
+        .map_err(move |e| {
+            mem::forget(e);
+            rtprintpanic!("drop of the panic payload panicked");
+            sys::abort_internal()
+        });
+    panic::catch_unwind(sys_common::rt::cleanup).map_err(rt_abort)?;
+    ret_code
 }
 
 #[cfg(not(test))]
@@ -50,4 +64,5 @@ fn lang_start<T: crate::process::Termination + 'static>(
         argc,
         argv,
     )
+    .into_ok()
 }
diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs
index 2f0b32c90d0..00a4afc5705 100644
--- a/library/std/src/sync/condvar.rs
+++ b/library/std/src/sync/condvar.rs
@@ -254,7 +254,7 @@ impl Condvar {
     /// except that the thread will be blocked for roughly no longer
     /// than `ms` milliseconds. This method should not be used for
     /// precise timing due to anomalies such as preemption or platform
-    /// differences that may not cause the maximum amount of time
+    /// differences that might not cause the maximum amount of time
     /// waited to be precisely `ms`.
     ///
     /// Note that the best effort is made to ensure that the time waited is
@@ -317,7 +317,7 @@ impl Condvar {
     /// The semantics of this function are equivalent to [`wait`] except that
     /// the thread will be blocked for roughly no longer than `dur`. This
     /// method should not be used for precise timing due to anomalies such as
-    /// preemption or platform differences that may not cause the maximum
+    /// preemption or platform differences that might not cause the maximum
     /// amount of time waited to be precisely `dur`.
     ///
     /// Note that the best effort is made to ensure that the time waited is
@@ -392,7 +392,7 @@ impl Condvar {
     /// The semantics of this function are equivalent to [`wait_while`] except
     /// that the thread will be blocked for roughly no longer than `dur`. This
     /// method should not be used for precise timing due to anomalies such as
-    /// preemption or platform differences that may not cause the maximum
+    /// preemption or platform differences that might not cause the maximum
     /// amount of time waited to be precisely `dur`.
     ///
     /// Note that the best effort is made to ensure that the time waited is
diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs
index ea1d598d264..b4f4456537b 100644
--- a/library/std/src/sync/mpsc/mod.rs
+++ b/library/std/src/sync/mpsc/mod.rs
@@ -105,6 +105,35 @@
 //! });
 //! rx.recv().unwrap();
 //! ```
+//!
+//! Unbounded receive loop:
+//!
+//! ```
+//! use std::sync::mpsc::sync_channel;
+//! use std::thread;
+//!
+//! let (tx, rx) = sync_channel(3);
+//!
+//! for _ in 0..3 {
+//!     // It would be the same without thread and clone here
+//!     // since there will still be one `tx` left.
+//!     let tx = tx.clone();
+//!     // cloned tx dropped within thread
+//!     thread::spawn(move || tx.send("ok").unwrap());
+//! }
+//!
+//! // Drop the last sender to stop `rx` waiting for message.
+//! // The program will not complete if we comment this out.
+//! // **All** `tx` needs to be dropped for `rx` to have `Err`.
+//! drop(tx);
+//!
+//! // Unbounded receiver waiting for all senders to complete.
+//! while let Ok(msg) = rx.recv() {
+//!     println!("{}", msg);
+//! }
+//!
+//! println!("completed");
+//! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -437,6 +466,9 @@ pub struct IntoIter<T> {
 ///
 /// Messages can be sent through this channel with [`send`].
 ///
+/// Note: all senders (the original and the clones) need to be dropped for the receiver
+/// to stop blocking to receive messages with [`Receiver::recv`].
+///
 /// [`send`]: Sender::send
 ///
 /// # Examples
@@ -643,7 +675,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// the same order as it was sent, and no [`send`] will block the calling thread
 /// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
 /// block after its buffer limit is reached). [`recv`] will block until a message
-/// is available.
+/// is available while there is at least one [`Sender`] alive (including clones).
 ///
 /// The [`Sender`] can be cloned to [`send`] to the same channel multiple times, but
 /// only one [`Receiver`] is supported.
@@ -806,6 +838,11 @@ impl<T> Sender<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Clone for Sender<T> {
+    /// Clone a sender to send to other threads.
+    ///
+    /// Note, be aware of the lifetime of the sender because all senders
+    /// (including the original) need to be dropped in order for
+    /// [`Receiver::recv`] to stop blocking.
     fn clone(&self) -> Sender<T> {
         let packet = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
@@ -1064,9 +1101,10 @@ impl<T> Receiver<T> {
     /// corresponding channel has hung up.
     ///
     /// This function will always block the current thread if there is no data
-    /// available and it's possible for more data to be sent. Once a message is
-    /// sent to the corresponding [`Sender`] (or [`SyncSender`]), then this
-    /// receiver will wake up and return that message.
+    /// available and it's possible for more data to be sent (at least one sender
+    /// still exists). Once a message is sent to the corresponding [`Sender`]
+    /// (or [`SyncSender`]), this receiver will wake up and return that
+    /// message.
     ///
     /// If the corresponding [`Sender`] has disconnected, or it disconnects while
     /// this call is blocking, this call will wake up and return [`Err`] to
@@ -1146,9 +1184,10 @@ impl<T> Receiver<T> {
     /// corresponding channel has hung up, or if it waits more than `timeout`.
     ///
     /// This function will always block the current thread if there is no data
-    /// available and it's possible for more data to be sent. Once a message is
-    /// sent to the corresponding [`Sender`] (or [`SyncSender`]), then this
-    /// receiver will wake up and return that message.
+    /// available and it's possible for more data to be sent (at least one sender
+    /// still exists). Once a message is sent to the corresponding [`Sender`]
+    /// (or [`SyncSender`]), this receiver will wake up and return that
+    /// message.
     ///
     /// If the corresponding [`Sender`] has disconnected, or it disconnects while
     /// this call is blocking, this call will wake up and return [`Err`] to
diff --git a/library/std/src/sync/mpsc/mpsc_queue.rs b/library/std/src/sync/mpsc/mpsc_queue.rs
index 42bc639dc25..cdd64a5def5 100644
--- a/library/std/src/sync/mpsc/mpsc_queue.rs
+++ b/library/std/src/sync/mpsc/mpsc_queue.rs
@@ -6,10 +6,10 @@
 //!
 //! Note that the current implementation of this queue has a caveat of the `pop`
 //! method, and see the method for more information about it. Due to this
-//! caveat, this queue may not be appropriate for all use-cases.
+//! caveat, this queue might not be appropriate for all use-cases.
 
-// http://www.1024cores.net/home/lock-free-algorithms
-//                         /queues/non-intrusive-mpsc-node-based-queue
+// https://www.1024cores.net/home/lock-free-algorithms
+//                          /queues/non-intrusive-mpsc-node-based-queue
 
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests;
diff --git a/library/std/src/sync/mpsc/spsc_queue.rs b/library/std/src/sync/mpsc/spsc_queue.rs
index 9bf99f193ca..7e745eb31de 100644
--- a/library/std/src/sync/mpsc/spsc_queue.rs
+++ b/library/std/src/sync/mpsc/spsc_queue.rs
@@ -4,7 +4,7 @@
 //! concurrently between two threads. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
-// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+// https://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
 
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests;
diff --git a/library/std/src/sync/mpsc/stream.rs b/library/std/src/sync/mpsc/stream.rs
index a652f24c58a..2a1d3f8967e 100644
--- a/library/std/src/sync/mpsc/stream.rs
+++ b/library/std/src/sync/mpsc/stream.rs
@@ -339,7 +339,7 @@ impl<T> Packet<T> {
 
         // At this point in time, we have gated all future senders from sending,
         // and we have flagged the channel as being disconnected. The senders
-        // still have some responsibility, however, because some sends may not
+        // still have some responsibility, however, because some sends might not
         // complete until after we flag the disconnection. There are more
         // details in the sending methods that see DISCONNECTED
     }
@@ -370,7 +370,7 @@ impl<T> Packet<T> {
         // at all.
         //
         // Hence, because of these invariants, we immediately return `Ok(true)`.
-        // Note that the data may not actually be sent on the channel just yet.
+        // Note that the data might not actually be sent on the channel just yet.
         // The other end could have flagged the upgrade but not sent data to
         // this end. This is fine because we know it's a small bounded windows
         // of time until the data is actually sent.
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index e7c5479ab9b..e1d6324c17e 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -217,26 +217,6 @@ impl<T> Mutex<T> {
             data: UnsafeCell::new(t),
         }
     }
-
-    /// Immediately drops the guard, and consequently unlocks the mutex.
-    ///
-    /// This function is equivalent to calling [`drop`] on the guard but is more self-documenting.
-    /// Alternately, the guard will be automatically dropped when it goes out of scope.
-    ///
-    /// ```
-    /// #![feature(mutex_unlock)]
-    ///
-    /// use std::sync::Mutex;
-    /// let mutex = Mutex::new(0);
-    ///
-    /// let mut guard = mutex.lock().unwrap();
-    /// *guard += 20;
-    /// Mutex::unlock(guard);
-    /// ```
-    #[unstable(feature = "mutex_unlock", issue = "81872")]
-    pub fn unlock(guard: MutexGuard<'_, T>) {
-        drop(guard);
-    }
 }
 
 impl<T: ?Sized> Mutex<T> {
@@ -333,6 +313,26 @@ impl<T: ?Sized> Mutex<T> {
         }
     }
 
+    /// Immediately drops the guard, and consequently unlocks the mutex.
+    ///
+    /// This function is equivalent to calling [`drop`] on the guard but is more self-documenting.
+    /// Alternately, the guard will be automatically dropped when it goes out of scope.
+    ///
+    /// ```
+    /// #![feature(mutex_unlock)]
+    ///
+    /// use std::sync::Mutex;
+    /// let mutex = Mutex::new(0);
+    ///
+    /// let mut guard = mutex.lock().unwrap();
+    /// *guard += 20;
+    /// Mutex::unlock(guard);
+    /// ```
+    #[unstable(feature = "mutex_unlock", issue = "81872")]
+    pub fn unlock(guard: MutexGuard<'_, T>) {
+        drop(guard);
+    }
+
     /// Determines whether the mutex is poisoned.
     ///
     /// If another thread is active, the mutex can still become poisoned at any
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index 6da6c18e477..a2e935a0ceb 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -198,7 +198,7 @@ impl Once {
     /// routine is currently running.
     ///
     /// When this function returns, it is guaranteed that some initialization
-    /// has run and completed (it may not be the closure specified). It is also
+    /// has run and completed (it might not be the closure specified). It is also
     /// guaranteed that any memory writes performed by the executed closure can
     /// be reliably observed by other threads at this point (there is a
     /// happens-before relation between the closure and code executing after the
diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs
index 05e1833c3e5..fa950331e64 100644
--- a/library/std/src/sync/poison.rs
+++ b/library/std/src/sync/poison.rs
@@ -120,7 +120,7 @@ pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
 /// A type alias for the result of a nonblocking locking method.
 ///
 /// For more information, see [`LockResult`]. A `TryLockResult` doesn't
-/// necessarily hold the associated guard in the [`Err`] type as the lock may not
+/// necessarily hold the associated guard in the [`Err`] type as the lock might not
 /// have been acquired for other reasons.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 9d521ab14cb..e50d62d8173 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -3,9 +3,7 @@ mod tests;
 
 use crate::cell::UnsafeCell;
 use crate::fmt;
-use crate::mem;
 use crate::ops::{Deref, DerefMut};
-use crate::ptr;
 use crate::sync::{poison, LockResult, TryLockError, TryLockResult};
 use crate::sys_common::rwlock as sys;
 
@@ -25,7 +23,19 @@ use crate::sys_common::rwlock as sys;
 /// system's implementation, and this type does not guarantee that any
 /// particular policy will be used. In particular, a writer which is waiting to
 /// acquire the lock in `write` might or might not block concurrent calls to
-/// `read`.
+/// `read`, e.g.:
+///
+/// <details><summary>Potential deadlock example</summary>
+///
+/// ```text
+/// // Thread 1             |  // Thread 2
+/// let _rg = lock.read();  |
+///                         |  // will block
+///                         |  let _wg = lock.write();
+/// // may deadlock         |
+/// let _rg = lock.read();  |
+/// ```
+/// </details>
 ///
 /// The type parameter `T` represents the data that this lock protects. It is
 /// required that `T` satisfies [`Send`] to be shared across threads and
@@ -66,7 +76,7 @@ use crate::sys_common::rwlock as sys;
 /// [`Mutex`]: super::Mutex
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RwLock<T: ?Sized> {
-    inner: Box<sys::RWLock>,
+    inner: sys::MovableRWLock,
     poison: poison::Flag,
     data: UnsafeCell<T>,
 }
@@ -130,7 +140,7 @@ impl<T> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
         RwLock {
-            inner: box sys::RWLock::new(),
+            inner: sys::MovableRWLock::new(),
             poison: poison::Flag::new(),
             data: UnsafeCell::new(t),
         }
@@ -376,24 +386,8 @@ impl<T: ?Sized> RwLock<T> {
     where
         T: Sized,
     {
-        // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner lock.
-        //
-        // To get the inner value, we'd like to call `data.into_inner()`,
-        // but because `RwLock` impl-s `Drop`, we can't move out of it, so
-        // we'll have to destructure it manually instead.
-        unsafe {
-            // Like `let RwLock { inner, poison, data } = self`.
-            let (inner, poison, data) = {
-                let RwLock { ref inner, ref poison, ref data } = self;
-                (ptr::read(inner), ptr::read(poison), ptr::read(data))
-            };
-            mem::forget(self);
-            inner.destroy(); // Keep in sync with the `Drop` impl.
-            drop(inner);
-
-            poison::map_result(poison.borrow(), |_| data.into_inner())
-        }
+        let data = self.data.into_inner();
+        poison::map_result(self.poison.borrow(), |_| data)
     }
 
     /// Returns a mutable reference to the underlying data.
@@ -425,14 +419,6 @@ impl<T: ?Sized> RwLock<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock<T> {
-    fn drop(&mut self) {
-        // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
-        unsafe { self.inner.destroy() }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut d = f.debug_struct("RwLock");
diff --git a/library/std/src/sys/common/alloc.rs b/library/std/src/sys/common/alloc.rs
index 2a54e99020e..576667c0173 100644
--- a/library/std/src/sys/common/alloc.rs
+++ b/library/std/src/sys/common/alloc.rs
@@ -14,7 +14,8 @@ use crate::ptr;
     target_arch = "asmjs",
     target_arch = "wasm32",
     target_arch = "hexagon",
-    target_arch = "riscv32"
+    target_arch = "riscv32",
+    target_arch = "xtensa"
 )))]
 pub const MIN_ALIGN: usize = 8;
 #[cfg(all(any(
diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs
index 4eb0d8437ba..1c7e1dd8d57 100644
--- a/library/std/src/sys/hermit/args.rs
+++ b/library/std/src/sys/hermit/args.rs
@@ -55,8 +55,8 @@ impl DoubleEndedIterator for Args {
 mod imp {
     use super::Args;
     use crate::ffi::{CStr, OsString};
+    use crate::os::unix::ffi::OsStringExt;
     use crate::ptr;
-    use crate::sys_common::os_str_bytes::*;
 
     use crate::sys_common::mutex::StaticMutex;
 
diff --git a/library/std/src/sys/hermit/condvar.rs b/library/std/src/sys/hermit/condvar.rs
index b45e8718f08..fa8ef8fc37a 100644
--- a/library/std/src/sys/hermit/condvar.rs
+++ b/library/std/src/sys/hermit/condvar.rs
@@ -14,7 +14,7 @@ pub struct Condvar {
     sem2: *const c_void,
 }
 
-pub type MovableCondvar = Box<Condvar>;
+pub type MovableCondvar = Condvar;
 
 unsafe impl Send for Condvar {}
 unsafe impl Sync for Condvar {}
diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs
index 76ea70d997f..be019d4435d 100644
--- a/library/std/src/sys/hermit/fs.rs
+++ b/library/std/src/sys/hermit/fs.rs
@@ -3,6 +3,7 @@ use crate::fmt;
 use crate::hash::{Hash, Hasher};
 use crate::io::{self, Error, ErrorKind};
 use crate::io::{IoSlice, IoSliceMut, SeekFrom};
+use crate::os::unix::ffi::OsStrExt;
 use crate::path::{Path, PathBuf};
 use crate::sys::cvt;
 use crate::sys::hermit::abi;
@@ -10,7 +11,6 @@ use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRU
 use crate::sys::hermit::fd::FileDesc;
 use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
-use crate::sys_common::os_str_bytes::OsStrExt;
 
 pub use crate::sys_common::fs::{copy, try_exists};
 //pub use crate::sys_common::fs::remove_dir_all;
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 15a76bbd2c9..185b68c0a78 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -32,6 +32,8 @@ pub mod memchr;
 pub mod mutex;
 pub mod net;
 pub mod os;
+#[path = "../unix/os_str.rs"]
+pub mod os_str;
 #[path = "../unix/path.rs"]
 pub mod path;
 #[path = "../unsupported/pipe.rs"]
@@ -47,7 +49,6 @@ pub mod thread_local_key;
 pub mod time;
 
 use crate::io::ErrorKind;
-pub use crate::sys_common::os_str_bytes as os_str;
 
 #[allow(unused_extern_crates)]
 pub extern crate hermit_abi as abi;
@@ -149,7 +150,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         x if x == 1 as i32 => ErrorKind::PermissionDenied,
         x if x == 32 as i32 => ErrorKind::BrokenPipe,
         x if x == 110 as i32 => ErrorKind::TimedOut,
-        _ => ErrorKind::Other,
+        _ => ErrorKind::Uncategorized,
     }
 }
 
diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index 885389ca54c..691e7e07902 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -14,7 +14,7 @@ use crate::sys::hermit::abi;
 /// This structure behaves a lot like a common mutex. There are some differences:
 ///
 /// - By using busy waiting, it can be used outside the runtime.
-/// - It is a so called ticket lock and is completly fair.
+/// - It is a so called ticket lock and is completely fair.
 #[cfg_attr(target_arch = "x86_64", repr(align(128)))]
 #[cfg_attr(not(target_arch = "x86_64"), repr(align(64)))]
 struct Spinlock<T: ?Sized> {
@@ -156,7 +156,7 @@ pub struct Mutex {
     inner: Spinlock<MutexInner>,
 }
 
-pub type MovableMutex = Box<Mutex>;
+pub type MovableMutex = Mutex;
 
 unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs
index 5f8839157ea..3f0c99cf742 100644
--- a/library/std/src/sys/hermit/net.rs
+++ b/library/std/src/sys/hermit/net.rs
@@ -15,7 +15,7 @@ use crate::time::Duration;
 pub fn init() -> io::Result<()> {
     if abi::network_init() < 0 {
         return Err(io::Error::new_const(
-            ErrorKind::Other,
+            ErrorKind::Uncategorized,
             &"Unable to initialize network interface",
         ));
     }
@@ -51,7 +51,7 @@ impl TcpStream {
         match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) {
             Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
             _ => Err(io::Error::new_const(
-                ErrorKind::Other,
+                ErrorKind::Uncategorized,
                 &"Unable to initiate a connection on a socket",
             )),
         }
@@ -65,7 +65,7 @@ impl TcpStream {
         ) {
             Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))),
             _ => Err(io::Error::new_const(
-                ErrorKind::Other,
+                ErrorKind::Uncategorized,
                 &"Unable to initiate a connection on a socket",
             )),
         }
@@ -73,7 +73,9 @@ impl TcpStream {
 
     pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
         abi::tcpstream::set_read_timeout(*self.0.as_inner(), duration.map(|d| d.as_millis() as u64))
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"Unable to set timeout value"))
+            .map_err(|_| {
+                io::Error::new_const(ErrorKind::Uncategorized, &"Unable to set timeout value")
+            })
     }
 
     pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> {
@@ -81,12 +83,12 @@ impl TcpStream {
             *self.0.as_inner(),
             duration.map(|d| d.as_millis() as u64),
         )
-        .map_err(|_| io::Error::new_const(ErrorKind::Other, &"Unable to set timeout value"))
+        .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"Unable to set timeout value"))
     }
 
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         let duration = abi::tcpstream::get_read_timeout(*self.0.as_inner()).map_err(|_| {
-            io::Error::new_const(ErrorKind::Other, &"Unable to determine timeout value")
+            io::Error::new_const(ErrorKind::Uncategorized, &"Unable to determine timeout value")
         })?;
 
         Ok(duration.map(|d| Duration::from_millis(d)))
@@ -94,7 +96,7 @@ impl TcpStream {
 
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         let duration = abi::tcpstream::get_write_timeout(*self.0.as_inner()).map_err(|_| {
-            io::Error::new_const(ErrorKind::Other, &"Unable to determine timeout value")
+            io::Error::new_const(ErrorKind::Uncategorized, &"Unable to determine timeout value")
         })?;
 
         Ok(duration.map(|d| Duration::from_millis(d)))
@@ -102,7 +104,7 @@ impl TcpStream {
 
     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
         abi::tcpstream::peek(*self.0.as_inner(), buf)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"set_nodelay failed"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"peek failed"))
     }
 
     pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> {
@@ -113,8 +115,9 @@ impl TcpStream {
         let mut size: usize = 0;
 
         for i in ioslice.iter_mut() {
-            let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..])
-                .map_err(|_| io::Error::new_const(ErrorKind::Other, &"Unable to read on socket"))?;
+            let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..]).map_err(|_| {
+                io::Error::new_const(ErrorKind::Uncategorized, &"Unable to read on socket")
+            })?;
 
             if ret != 0 {
                 size += ret;
@@ -138,7 +141,7 @@ impl TcpStream {
 
         for i in ioslice.iter() {
             size += abi::tcpstream::write(*self.0.as_inner(), i).map_err(|_| {
-                io::Error::new_const(ErrorKind::Other, &"Unable to write on socket")
+                io::Error::new_const(ErrorKind::Uncategorized, &"Unable to write on socket")
             })?;
         }
 
@@ -152,13 +155,13 @@ impl TcpStream {
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         let (ipaddr, port) = abi::tcpstream::peer_addr(*self.0.as_inner())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"peer_addr failed"))?;
+            .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"peer_addr failed"))?;
 
         let saddr = match ipaddr {
             Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
             Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
             _ => {
-                return Err(io::Error::new_const(ErrorKind::Other, &"peer_addr failed"));
+                return Err(io::Error::new_const(ErrorKind::Uncategorized, &"peer_addr failed"));
             }
         };
 
@@ -170,8 +173,9 @@ impl TcpStream {
     }
 
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
-        abi::tcpstream::shutdown(*self.0.as_inner(), how as i32)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to shutdown socket"))
+        abi::tcpstream::shutdown(*self.0.as_inner(), how as i32).map_err(|_| {
+            io::Error::new_const(ErrorKind::Uncategorized, &"unable to shutdown socket")
+        })
     }
 
     pub fn duplicate(&self) -> io::Result<TcpStream> {
@@ -180,22 +184,22 @@ impl TcpStream {
 
     pub fn set_nodelay(&self, mode: bool) -> io::Result<()> {
         abi::tcpstream::set_nodelay(*self.0.as_inner(), mode)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"set_nodelay failed"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"set_nodelay failed"))
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
         abi::tcpstream::nodelay(*self.0.as_inner())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"nodelay failed"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"nodelay failed"))
     }
 
     pub fn set_ttl(&self, tll: u32) -> io::Result<()> {
         abi::tcpstream::set_tll(*self.0.as_inner(), tll)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to set TTL"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"unable to set TTL"))
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
         abi::tcpstream::get_tll(*self.0.as_inner())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to get TTL"))
+            .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"unable to get TTL"))
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
@@ -203,8 +207,9 @@ impl TcpStream {
     }
 
     pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> {
-        abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode)
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"unable to set blocking mode"))
+        abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode).map_err(|_| {
+            io::Error::new_const(ErrorKind::Uncategorized, &"unable to set blocking mode")
+        })
     }
 }
 
@@ -230,12 +235,12 @@ impl TcpListener {
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
         let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port())
-            .map_err(|_| io::Error::new_const(ErrorKind::Other, &"accept failed"))?;
+            .map_err(|_| io::Error::new_const(ErrorKind::Uncategorized, &"accept failed"))?;
         let saddr = match ipaddr {
             Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port),
             Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port),
             _ => {
-                return Err(io::Error::new_const(ErrorKind::Other, &"accept failed"));
+                return Err(io::Error::new_const(ErrorKind::Uncategorized, &"accept failed"));
             }
         };
 
diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs
index 40bd393098f..8f927df85be 100644
--- a/library/std/src/sys/hermit/os.rs
+++ b/library/std/src/sys/hermit/os.rs
@@ -4,13 +4,13 @@ use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
 use crate::io;
 use crate::marker::PhantomData;
+use crate::os::unix::ffi::OsStringExt;
 use crate::path::{self, PathBuf};
 use crate::str;
 use crate::sync::Mutex;
 use crate::sys::hermit::abi;
 use crate::sys::memchr;
 use crate::sys::unsupported;
-use crate::sys_common::os_str_bytes::*;
 use crate::vec;
 
 pub fn errno() -> i32 {
@@ -140,13 +140,8 @@ pub fn env() -> Env {
     }
 }
 
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
-    unsafe {
-        match ENV.as_ref().unwrap().lock().unwrap().get_mut(k) {
-            Some(value) => Ok(Some(value.clone())),
-            None => Ok(None),
-        }
-    }
+pub fn getenv(k: &OsStr) -> Option<OsString> {
+    unsafe { ENV.as_ref().unwrap().lock().unwrap().get_mut(k).cloned() }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs
index 06442e925f4..64eaa2fc482 100644
--- a/library/std/src/sys/hermit/rwlock.rs
+++ b/library/std/src/sys/hermit/rwlock.rs
@@ -8,6 +8,8 @@ pub struct RWLock {
     state: UnsafeCell<State>,
 }
 
+pub type MovableRWLock = RWLock;
+
 enum State {
     Unlocked,
     Reading(usize),
diff --git a/library/std/src/sys/hermit/stdio.rs b/library/std/src/sys/hermit/stdio.rs
index 6bff13ca92c..33b8390431f 100644
--- a/library/std/src/sys/hermit/stdio.rs
+++ b/library/std/src/sys/hermit/stdio.rs
@@ -40,7 +40,7 @@ impl io::Write for Stdout {
         unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stdout is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Uncategorized, &"Stdout is not able to print"))
         } else {
             Ok(len as usize)
         }
@@ -52,7 +52,7 @@ impl io::Write for Stdout {
         unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stdout is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Uncategorized, &"Stdout is not able to print"))
         } else {
             Ok(len as usize)
         }
@@ -81,7 +81,7 @@ impl io::Write for Stderr {
         unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stderr is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Uncategorized, &"Stderr is not able to print"))
         } else {
             Ok(len as usize)
         }
@@ -93,7 +93,7 @@ impl io::Write for Stderr {
         unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
 
         if len < 0 {
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Stderr is not able to print"))
+            Err(io::Error::new_const(io::ErrorKind::Uncategorized, &"Stderr is not able to print"))
         } else {
             Ok(len as usize)
         }
diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs
index f35a3a8a80f..8be25f84999 100644
--- a/library/std/src/sys/hermit/thread.rs
+++ b/library/std/src/sys/hermit/thread.rs
@@ -1,8 +1,10 @@
 #![allow(dead_code)]
 
+use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
+use crate::num::NonZeroUsize;
 use crate::sys::hermit::abi;
 use crate::sys::hermit::thread_local_dtor::run_dtors;
 use crate::time::Duration;
@@ -37,7 +39,7 @@ impl Thread {
             // The thread failed to start and as a result p was not consumed. Therefore, it is
             // safe to reconstruct the box so that it gets deallocated.
             drop(Box::from_raw(p));
-            Err(io::Error::new_const(io::ErrorKind::Other, &"Unable to create thread!"))
+            Err(io::Error::new_const(io::ErrorKind::Uncategorized, &"Unable to create thread!"))
         } else {
             Ok(Thread { tid: tid })
         };
@@ -95,6 +97,10 @@ impl Thread {
     }
 }
 
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    unsupported()
+}
+
 pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> {
diff --git a/library/std/src/sys/sgx/abi/mem.rs b/library/std/src/sys/sgx/abi/mem.rs
index 1e743894a9f..52e8bec937c 100644
--- a/library/std/src/sys/sgx/abi/mem.rs
+++ b/library/std/src/sys/sgx/abi/mem.rs
@@ -36,9 +36,9 @@ pub fn image_base() -> u64 {
     let base: u64;
     unsafe {
         asm!(
-            "lea {}, qword ptr [rip + IMAGE_BASE]",
+            "lea IMAGE_BASE(%rip), {}",
             lateout(reg) base,
-            options(nostack, preserves_flags, nomem, pure),
+            options(att_syntax, nostack, preserves_flags, nomem, pure),
         )
     };
     base
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index cdfceca19fc..a2a763c2b4e 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -26,6 +26,8 @@ pub mod memchr;
 pub mod mutex;
 pub mod net;
 pub mod os;
+#[path = "../unix/os_str.rs"]
+pub mod os_str;
 pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
@@ -37,8 +39,6 @@ pub mod thread;
 pub mod thread_local_key;
 pub mod time;
 
-pub use crate::sys_common::os_str_bytes as os_str;
-
 // SAFETY: must be called only once during runtime initialization.
 // NOTE: this is not guaranteed to run, for example when Rust code is called externally.
 pub unsafe fn init(argc: isize, argv: *const *const u8) {
@@ -70,7 +70,7 @@ pub fn sgx_ineffective<T>(v: T) -> crate::io::Result<T> {
     static SGX_INEFFECTIVE_ERROR: AtomicBool = AtomicBool::new(false);
     if SGX_INEFFECTIVE_ERROR.load(Ordering::Relaxed) {
         Err(crate::io::Error::new_const(
-            ErrorKind::Other,
+            ErrorKind::Uncategorized,
             &"operation can't be trusted to have any effect on SGX",
         ))
     } else {
@@ -115,11 +115,11 @@ pub fn decode_error_kind(code: i32) -> ErrorKind {
     } else if code == Error::Interrupted as _ {
         ErrorKind::Interrupted
     } else if code == Error::Other as _ {
-        ErrorKind::Other
+        ErrorKind::Uncategorized
     } else if code == Error::UnexpectedEof as _ {
         ErrorKind::UnexpectedEof
     } else {
-        ErrorKind::Other
+        ErrorKind::Uncategorized
     }
 }
 
diff --git a/library/std/src/sys/sgx/mutex.rs b/library/std/src/sys/sgx/mutex.rs
index 1b5ced4178f..0b2d1f4487f 100644
--- a/library/std/src/sys/sgx/mutex.rs
+++ b/library/std/src/sys/sgx/mutex.rs
@@ -8,7 +8,8 @@ pub struct Mutex {
     inner: SpinMutex<WaitVariable<bool>>,
 }
 
-pub type MovableMutex = Mutex;
+// not movable: see UnsafeList implementation
+pub type MovableMutex = Box<Mutex>;
 
 // Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28
 impl Mutex {
diff --git a/library/std/src/sys/sgx/net.rs b/library/std/src/sys/sgx/net.rs
index 5ccedece0f8..3a69aa039ef 100644
--- a/library/std/src/sys/sgx/net.rs
+++ b/library/std/src/sys/sgx/net.rs
@@ -466,7 +466,7 @@ pub struct LookupHost(!);
 
 impl LookupHost {
     fn new(host: String) -> io::Result<LookupHost> {
-        Err(io::Error::new(io::ErrorKind::Other, NonIpSockAddr { host }))
+        Err(io::Error::new(io::ErrorKind::Uncategorized, NonIpSockAddr { host }))
     }
 
     pub fn port(&self) -> u16 {
diff --git a/library/std/src/sys/sgx/os.rs b/library/std/src/sys/sgx/os.rs
index 144248d60c9..5f8b8def7c6 100644
--- a/library/std/src/sys/sgx/os.rs
+++ b/library/std/src/sys/sgx/os.rs
@@ -106,8 +106,8 @@ pub fn env() -> Env {
     get_env_store().map(|env| clone_to_vec(&env.lock().unwrap())).unwrap_or_default().into_iter()
 }
 
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
-    Ok(get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned()))
+pub fn getenv(k: &OsStr) -> Option<OsString> {
+    get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned())
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs
index 0c96e3fcddc..2d038b51896 100644
--- a/library/std/src/sys/sgx/rwlock.rs
+++ b/library/std/src/sys/sgx/rwlock.rs
@@ -13,6 +13,8 @@ pub struct RWLock {
     writer: SpinMutex<WaitVariable<bool>>,
 }
 
+pub type MovableRWLock = Box<RWLock>;
+
 // Check at compile time that RWLock size matches C definition (see test_c_rwlock_initializer below)
 //
 // # Safety
diff --git a/library/std/src/sys/sgx/stdio.rs b/library/std/src/sys/sgx/stdio.rs
index 548e28a43d6..8ccf043b5b5 100644
--- a/library/std/src/sys/sgx/stdio.rs
+++ b/library/std/src/sys/sgx/stdio.rs
@@ -65,7 +65,7 @@ impl io::Write for Stderr {
 pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
 
 pub fn is_ebadf(err: &io::Error) -> bool {
-    // FIXME: Rust normally maps Unix EBADF to `Other`
+    // FIXME: Rust normally maps Unix EBADF to `Uncategorized`
     err.raw_os_error() == Some(abi::Error::BrokenPipe as _)
 }
 
diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs
index 67e2e8b59d3..cbb8ba96401 100644
--- a/library/std/src/sys/sgx/thread.rs
+++ b/library/std/src/sys/sgx/thread.rs
@@ -1,6 +1,8 @@
 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
+use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
+use crate::num::NonZeroUsize;
 use crate::time::Duration;
 
 use super::abi::usercalls;
@@ -135,6 +137,10 @@ impl Thread {
     }
 }
 
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    unsupported()
+}
+
 pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> {
diff --git a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
index cf2f0886c15..c736cab576e 100644
--- a/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
+++ b/library/std/src/sys/sgx/waitqueue/unsafe_list.rs
@@ -23,6 +23,7 @@ impl<T> UnsafeListEntry<T> {
     }
 }
 
+// WARNING: self-referential struct!
 pub struct UnsafeList<T> {
     head_tail: NonNull<UnsafeListEntry<T>>,
     head_tail_entry: Option<UnsafeListEntry<T>>,
diff --git a/library/std/src/sys/unix/alloc.rs b/library/std/src/sys/unix/alloc.rs
index 1b71905aa09..7c3d9573940 100644
--- a/library/std/src/sys/unix/alloc.rs
+++ b/library/std/src/sys/unix/alloc.rs
@@ -57,7 +57,8 @@ cfg_if::cfg_if! {
         target_os = "android",
         target_os = "illumos",
         target_os = "redox",
-        target_os = "solaris"
+        target_os = "solaris",
+        target_os = "espidf"
     ))] {
         #[inline]
         unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
diff --git a/library/std/src/sys/unix/android.rs b/library/std/src/sys/unix/android.rs
index cf6aa31b7cf..6a46525f682 100644
--- a/library/std/src/sys/unix/android.rs
+++ b/library/std/src/sys/unix/android.rs
@@ -21,7 +21,7 @@
 use libc::{c_int, c_void, sighandler_t, size_t, ssize_t};
 use libc::{ftruncate, pread, pwrite};
 
-use super::{cvt, cvt_r};
+use super::{cvt, cvt_r, weak::weak};
 use crate::io;
 
 // The `log2` and `log2f` functions apparently appeared in android-18, or at
diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs
index fc423e393d4..ee5e3983ac2 100644
--- a/library/std/src/sys/unix/args.rs
+++ b/library/std/src/sys/unix/args.rs
@@ -14,11 +14,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
     imp::init(argc, argv)
 }
 
-/// One-time global cleanup.
-pub unsafe fn cleanup() {
-    imp::cleanup()
-}
-
 /// Returns the command line arguments
 pub fn args() -> Args {
     imp::args()
@@ -82,16 +77,18 @@ mod imp {
     use crate::ptr;
     use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
 
-    use crate::sys_common::mutex::StaticMutex;
-
+    // The system-provided argc and argv, which we store in static memory
+    // here so that we can defer the work of parsing them until its actually
+    // needed.
+    //
+    // Note that we never mutate argv/argc, the argv array, or the argv
+    // strings, which allows the code in this file to be very simple.
     static ARGC: AtomicIsize = AtomicIsize::new(0);
     static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
-    // We never call `ENV_LOCK.init()`, so it is UB to attempt to
-    // acquire this mutex reentrantly!
-    static LOCK: StaticMutex = StaticMutex::new();
 
     unsafe fn really_init(argc: isize, argv: *const *const u8) {
-        let _guard = LOCK.lock();
+        // These don't need to be ordered with each other or other stores,
+        // because they only hold the unmodified system-provide argv/argc.
         ARGC.store(argc, Ordering::Relaxed);
         ARGV.store(argv as *mut _, Ordering::Relaxed);
     }
@@ -127,21 +124,22 @@ mod imp {
         init_wrapper
     };
 
-    pub unsafe fn cleanup() {
-        let _guard = LOCK.lock();
-        ARGC.store(0, Ordering::Relaxed);
-        ARGV.store(ptr::null_mut(), Ordering::Relaxed);
-    }
-
     pub fn args() -> Args {
         Args { iter: clone().into_iter() }
     }
 
     fn clone() -> Vec<OsString> {
         unsafe {
-            let _guard = LOCK.lock();
-            let argc = ARGC.load(Ordering::Relaxed);
+            // Load ARGC and ARGV, which hold the unmodified system-provided
+            // argc/argv, so we can read the pointed-to memory without atomics
+            // or synchronization.
+            //
+            // If either ARGC or ARGV is still zero or null, then either there
+            // really are no arguments, or someone is asking for `args()`
+            // before initialization has completed, and we return an empty
+            // list.
             let argv = ARGV.load(Ordering::Relaxed);
+            let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
             (0..argc)
                 .map(|i| {
                     let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
@@ -159,8 +157,6 @@ mod imp {
 
     pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
 
-    pub fn cleanup() {}
-
     #[cfg(target_os = "macos")]
     pub fn args() -> Args {
         use crate::os::unix::prelude::*;
@@ -250,3 +246,15 @@ mod imp {
         Args { iter: res.into_iter() }
     }
 }
+
+#[cfg(target_os = "espidf")]
+mod imp {
+    use super::Args;
+
+    #[inline(always)]
+    pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
+
+    pub fn args() -> Args {
+        Args { iter: Vec::new().into_iter() }
+    }
+}
diff --git a/library/std/src/sys/unix/condvar.rs b/library/std/src/sys/unix/condvar.rs
index e38f91af9f0..61261c0aa84 100644
--- a/library/std/src/sys/unix/condvar.rs
+++ b/library/std/src/sys/unix/condvar.rs
@@ -34,12 +34,23 @@ impl Condvar {
     ))]
     pub unsafe fn init(&mut self) {}
 
+    // NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet
+    // So on that platform, init() should always be called
+    // Moreover, that platform does not have pthread_condattr_setclock support,
+    // hence that initialization should be skipped as well
+    #[cfg(target_os = "espidf")]
+    pub unsafe fn init(&mut self) {
+        let r = libc::pthread_cond_init(self.inner.get(), crate::ptr::null());
+        assert_eq!(r, 0);
+    }
+
     #[cfg(not(any(
         target_os = "macos",
         target_os = "ios",
         target_os = "l4re",
         target_os = "android",
-        target_os = "redox"
+        target_os = "redox",
+        target_os = "espidf"
     )))]
     pub unsafe fn init(&mut self) {
         use crate::mem::MaybeUninit;
@@ -76,7 +87,12 @@ impl Condvar {
     // where we configure condition variable to use monotonic clock (instead of
     // default system clock). This approach avoids all problems that result
     // from changes made to the system time.
-    #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
+    #[cfg(not(any(
+        target_os = "macos",
+        target_os = "ios",
+        target_os = "android",
+        target_os = "espidf"
+    )))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use crate::mem;
 
@@ -103,7 +119,12 @@ impl Condvar {
     // This implementation is modeled after libcxx's condition_variable
     // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
     // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
-    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
+    #[cfg(any(
+        target_os = "macos",
+        target_os = "ios",
+        target_os = "android",
+        target_os = "espidf"
+    ))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
         use crate::ptr;
         use crate::time::Instant;
diff --git a/library/std/src/sys/unix/env.rs b/library/std/src/sys/unix/env.rs
index 3a88dc083b0..60551aeb3e7 100644
--- a/library/std/src/sys/unix/env.rs
+++ b/library/std/src/sys/unix/env.rs
@@ -184,3 +184,14 @@ pub mod os {
     pub const EXE_SUFFIX: &str = "";
     pub const EXE_EXTENSION: &str = "";
 }
+
+#[cfg(target_os = "espidf")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "espidf";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".so";
+    pub const DLL_EXTENSION: &str = "so";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
+}
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index 821851a6c65..28e32681e15 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -91,6 +91,7 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
+    #[cfg(not(target_os = "espidf"))]
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         let ret = cvt(unsafe {
             libc::readv(
@@ -102,9 +103,14 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
+    #[cfg(target_os = "espidf")]
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        return crate::io::default_read_vectored(|b| self.read(b), bufs);
+    }
+
     #[inline]
     pub fn is_read_vectored(&self) -> bool {
-        true
+        cfg!(not(target_os = "espidf"))
     }
 
     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
@@ -148,6 +154,7 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
+    #[cfg(not(target_os = "espidf"))]
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
         let ret = cvt(unsafe {
             libc::writev(
@@ -159,9 +166,14 @@ impl FileDesc {
         Ok(ret as usize)
     }
 
+    #[cfg(target_os = "espidf")]
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        return crate::io::default_write_vectored(|b| self.write(b), bufs);
+    }
+
     #[inline]
     pub fn is_write_vectored(&self) -> bool {
-        true
+        cfg!(not(target_os = "espidf"))
     }
 
     pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
@@ -217,7 +229,7 @@ impl FileDesc {
         }
     }
     #[cfg(any(
-        target_env = "newlib",
+        all(target_env = "newlib", not(target_os = "espidf")),
         target_os = "solaris",
         target_os = "illumos",
         target_os = "emscripten",
@@ -238,6 +250,12 @@ impl FileDesc {
             Ok(())
         }
     }
+    #[cfg(target_os = "espidf")]
+    pub fn set_cloexec(&self) -> io::Result<()> {
+        // FD_CLOEXEC is not supported in ESP-IDF but there's no need to,
+        // because ESP-IDF does not support spawning processes either.
+        Ok(())
+    }
 
     #[cfg(target_os = "linux")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
@@ -268,7 +286,17 @@ impl FileDesc {
         // We want to atomically duplicate this file descriptor and set the
         // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
         // is a POSIX flag that was added to Linux in 2.6.24.
-        let fd = cvt(unsafe { libc::fcntl(self.raw(), libc::F_DUPFD_CLOEXEC, 0) })?;
+        #[cfg(not(target_os = "espidf"))]
+        let cmd = libc::F_DUPFD_CLOEXEC;
+
+        // For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics
+        // will never be supported, as this is a bare metal framework with
+        // no capabilities for multi-process execution.  While F_DUPFD is also
+        // not supported yet, it might be (currently it returns ENOSYS).
+        #[cfg(target_os = "espidf")]
+        let cmd = libc::F_DUPFD;
+
+        let fd = cvt(unsafe { libc::fcntl(self.raw(), cmd, 0) })?;
         Ok(FileDesc::new(fd))
     }
 }
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index f8ca67c844c..fd4defd72eb 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -12,8 +12,23 @@ use crate::sys::time::SystemTime;
 use crate::sys::{cvt, cvt_r};
 use crate::sys_common::{AsInner, FromInner};
 
+#[cfg(any(
+    all(target_os = "linux", target_env = "gnu"),
+    target_os = "macos",
+    target_os = "ios",
+))]
+use crate::sys::weak::syscall;
+#[cfg(target_os = "macos")]
+use crate::sys::weak::weak;
+
 use libc::{c_int, mode_t};
 
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    all(target_os = "linux", target_env = "gnu")
+))]
+use libc::c_char;
 #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
 use libc::dirfd;
 #[cfg(any(target_os = "linux", target_os = "emscripten"))]
@@ -92,7 +107,7 @@ cfg_has_statx! {{
     // Default `stat64` contains no creation time.
     unsafe fn try_statx(
         fd: c_int,
-        path: *const libc::c_char,
+        path: *const c_char,
         flags: i32,
         mask: u32,
     ) -> Option<io::Result<FileAttr>> {
@@ -107,7 +122,7 @@ cfg_has_statx! {{
         syscall! {
             fn statx(
                 fd: c_int,
-                pathname: *const libc::c_char,
+                pathname: *const c_char,
                 flags: c_int,
                 mask: libc::c_uint,
                 statxbuf: *mut libc::statx
@@ -297,7 +312,7 @@ impl FileAttr {
 
 #[cfg(not(target_os = "netbsd"))]
 impl FileAttr {
-    #[cfg(not(target_os = "vxworks"))]
+    #[cfg(all(not(target_os = "vxworks"), not(target_os = "espidf")))]
     pub fn modified(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_mtime as libc::time_t,
@@ -305,7 +320,7 @@ impl FileAttr {
         }))
     }
 
-    #[cfg(target_os = "vxworks")]
+    #[cfg(any(target_os = "vxworks", target_os = "espidf"))]
     pub fn modified(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_mtime as libc::time_t,
@@ -313,7 +328,7 @@ impl FileAttr {
         }))
     }
 
-    #[cfg(not(target_os = "vxworks"))]
+    #[cfg(all(not(target_os = "vxworks"), not(target_os = "espidf")))]
     pub fn accessed(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_atime as libc::time_t,
@@ -321,7 +336,7 @@ impl FileAttr {
         }))
     }
 
-    #[cfg(target_os = "vxworks")]
+    #[cfg(any(target_os = "vxworks", target_os = "espidf"))]
     pub fn accessed(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_atime as libc::time_t,
@@ -358,7 +373,7 @@ impl FileAttr {
                     }))
                 } else {
                     Err(io::Error::new_const(
-                        io::ErrorKind::Other,
+                        io::ErrorKind::Uncategorized,
                         &"creation time is not available for the filesystem",
                     ))
                 };
@@ -594,7 +609,8 @@ impl DirEntry {
         target_os = "l4re",
         target_os = "fuchsia",
         target_os = "redox",
-        target_os = "vxworks"
+        target_os = "vxworks",
+        target_os = "espidf"
     ))]
     pub fn ino(&self) -> u64 {
         self.entry.d_ino as u64
@@ -633,7 +649,8 @@ impl DirEntry {
         target_os = "emscripten",
         target_os = "l4re",
         target_os = "haiku",
-        target_os = "vxworks"
+        target_os = "vxworks",
+        target_os = "espidf"
     ))]
     fn name_bytes(&self) -> &[u8] {
         unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() }
@@ -647,6 +664,10 @@ impl DirEntry {
     fn name_bytes(&self) -> &[u8] {
         &*self.name
     }
+
+    pub fn file_name_os_str(&self) -> &OsStr {
+        OsStr::from_bytes(self.name_bytes())
+    }
 }
 
 impl OpenOptions {
@@ -752,7 +773,7 @@ impl File {
         cfg_has_statx! {
             if let Some(ret) = unsafe { try_statx(
                 fd,
-                b"\0" as *const _ as *const libc::c_char,
+                b"\0" as *const _ as *const c_char,
                 libc::AT_EMPTY_PATH | libc::AT_STATX_SYNC_AS_STAT,
                 libc::STATX_ALL,
             ) } {
@@ -920,7 +941,7 @@ impl FromInner<c_int> for File {
 
 impl fmt::Debug for File {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        #[cfg(target_os = "linux")]
+        #[cfg(any(target_os = "linux", target_os = "netbsd"))]
         fn get_path(fd: c_int) -> Option<PathBuf> {
             let mut p = PathBuf::from("/proc/self/fd");
             p.push(&fd.to_string());
@@ -957,7 +978,12 @@ impl fmt::Debug for File {
             Some(PathBuf::from(OsString::from_vec(buf)))
         }
 
-        #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "vxworks")))]
+        #[cfg(not(any(
+            target_os = "linux",
+            target_os = "macos",
+            target_os = "vxworks",
+            target_os = "netbsd"
+        )))]
         fn get_path(_fd: c_int) -> Option<PathBuf> {
             // FIXME(#24570): implement this for other Unix platforms
             None
@@ -1082,16 +1108,29 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> {
     let original = cstr(original)?;
     let link = cstr(link)?;
     cfg_if::cfg_if! {
-        if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android"))] {
-            // VxWorks, Redox, and old versions of Android lack `linkat`, so use
-            // `link` instead. POSIX leaves it implementation-defined whether
-            // `link` follows symlinks, so rely on the `symlink_hard_link` test
-            // in library/std/src/fs/tests.rs to check the behavior.
+        if #[cfg(any(target_os = "vxworks", target_os = "redox", target_os = "android", target_os = "espidf"))] {
+            // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. POSIX leaves
+            // it implementation-defined whether `link` follows symlinks, so rely on the
+            // `symlink_hard_link` test in library/std/src/fs/tests.rs to check the behavior.
+            // Android has `linkat` on newer versions, but we happen to know `link`
+            // always has the correct behavior, so it's here as well.
             cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
+        } else if #[cfg(target_os = "macos")] {
+            // On MacOS, older versions (<=10.9) lack support for linkat while newer
+            // versions have it. We want to use linkat if it is available, so we use weak!
+            // to check. `linkat` is preferable to `link` ecause it gives us a flag to
+            // specify how symlinks should be handled. We pass 0 as the flags argument,
+            // meaning it shouldn't follow symlinks.
+            weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int);
+
+            if let Some(f) = linkat.get() {
+                cvt(unsafe { f(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
+            } else {
+                cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?;
+            };
         } else {
-            // Use `linkat` with `AT_FDCWD` instead of `link` as `linkat` gives
-            // us a flag to specify how symlinks should be handled. Pass 0 as
-            // the flags argument, meaning don't follow symlinks.
+            // Where we can, use `linkat` instead of `link`; see the comment above
+            // this one for details on why.
             cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?;
         }
     }
@@ -1162,6 +1201,18 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)>
     Ok((reader, metadata))
 }
 
+#[cfg(target_os = "espidf")]
+fn open_to_and_set_permissions(
+    to: &Path,
+    reader_metadata: crate::fs::Metadata,
+) -> io::Result<(crate::fs::File, crate::fs::Metadata)> {
+    use crate::fs::OpenOptions;
+    let writer = OpenOptions::new().open(to)?;
+    let writer_metadata = writer.metadata()?;
+    Ok((writer, writer_metadata))
+}
+
+#[cfg(not(target_os = "espidf"))]
 fn open_to_and_set_permissions(
     to: &Path,
     reader_metadata: crate::fs::Metadata,
@@ -1274,7 +1325,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
         fn fclonefileat(
             srcfd: libc::c_int,
             dst_dirfd: libc::c_int,
-            dst: *const libc::c_char,
+            dst: *const c_char,
             flags: libc::c_int
         ) -> libc::c_int
     }
diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs
index 9687576bb6a..a6b43229ba6 100644
--- a/library/std/src/sys/unix/kernel_copy.rs
+++ b/library/std/src/sys/unix/kernel_copy.rs
@@ -61,6 +61,7 @@ use crate::process::{ChildStderr, ChildStdin, ChildStdout};
 use crate::ptr;
 use crate::sync::atomic::{AtomicBool, AtomicU8, Ordering};
 use crate::sys::cvt;
+use crate::sys::weak::syscall;
 use libc::{EBADF, EINVAL, ENOSYS, EOPNOTSUPP, EOVERFLOW, EPERM, EXDEV};
 
 #[cfg(test)]
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index ca9cc8ca7ba..f5424e3d282 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -5,6 +5,7 @@ use crate::io::ErrorKind;
 pub use self::rand::hashmap_random_keys;
 pub use libc::strlen;
 
+#[cfg(not(target_os = "espidf"))]
 #[macro_use]
 pub mod weak;
 
@@ -30,6 +31,7 @@ pub mod net;
 #[cfg(target_os = "l4re")]
 pub use self::l4re::net;
 pub mod os;
+pub mod os_str;
 pub mod path;
 pub mod pipe;
 pub mod process;
@@ -42,8 +44,10 @@ pub mod thread_local_dtor;
 pub mod thread_local_key;
 pub mod time;
 
-pub use crate::sys_common::os_str_bytes as os_str;
+#[cfg(target_os = "espidf")]
+pub fn init(argc: isize, argv: *const *const u8) {}
 
+#[cfg(not(target_os = "espidf"))]
 // SAFETY: must be called only once during runtime initialization.
 // NOTE: this is not guaranteed to run, for example when Rust code is called externally.
 pub unsafe fn init(argc: isize, argv: *const *const u8) {
@@ -123,7 +127,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
 // SAFETY: must be called only once during runtime cleanup.
 // NOTE: this is not guaranteed to run, for example when the program aborts.
 pub unsafe fn cleanup() {
-    args::cleanup();
     stack_overflow::cleanup();
 }
 
@@ -133,29 +136,51 @@ pub use crate::sys::android::signal;
 pub use libc::signal;
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
+    use ErrorKind::*;
     match errno as libc::c_int {
-        libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
-        libc::ECONNRESET => ErrorKind::ConnectionReset,
-        libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
-        libc::EPIPE => ErrorKind::BrokenPipe,
-        libc::ENOTCONN => ErrorKind::NotConnected,
-        libc::ECONNABORTED => ErrorKind::ConnectionAborted,
-        libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
-        libc::EADDRINUSE => ErrorKind::AddrInUse,
-        libc::ENOENT => ErrorKind::NotFound,
-        libc::EINTR => ErrorKind::Interrupted,
-        libc::EINVAL => ErrorKind::InvalidInput,
-        libc::ETIMEDOUT => ErrorKind::TimedOut,
-        libc::EEXIST => ErrorKind::AlreadyExists,
-        libc::ENOSYS => ErrorKind::Unsupported,
-        libc::ENOMEM => ErrorKind::OutOfMemory,
+        libc::E2BIG => ArgumentListTooLong,
+        libc::EADDRINUSE => AddrInUse,
+        libc::EADDRNOTAVAIL => AddrNotAvailable,
+        libc::EBUSY => ResourceBusy,
+        libc::ECONNABORTED => ConnectionAborted,
+        libc::ECONNREFUSED => ConnectionRefused,
+        libc::ECONNRESET => ConnectionReset,
+        libc::EDEADLK => Deadlock,
+        libc::EDQUOT => FilesystemQuotaExceeded,
+        libc::EEXIST => AlreadyExists,
+        libc::EFBIG => FileTooLarge,
+        libc::EHOSTUNREACH => HostUnreachable,
+        libc::EINTR => Interrupted,
+        libc::EINVAL => InvalidInput,
+        libc::EISDIR => IsADirectory,
+        libc::ELOOP => FilesystemLoop,
+        libc::ENOENT => NotFound,
+        libc::ENOMEM => OutOfMemory,
+        libc::ENOSPC => StorageFull,
+        libc::ENOSYS => Unsupported,
+        libc::EMLINK => TooManyLinks,
+        libc::ENAMETOOLONG => FilenameTooLong,
+        libc::ENETDOWN => NetworkDown,
+        libc::ENETUNREACH => NetworkUnreachable,
+        libc::ENOTCONN => NotConnected,
+        libc::ENOTDIR => NotADirectory,
+        libc::ENOTEMPTY => DirectoryNotEmpty,
+        libc::EPIPE => BrokenPipe,
+        libc::EROFS => ReadOnlyFilesystem,
+        libc::ESPIPE => NotSeekable,
+        libc::ESTALE => StaleNetworkFileHandle,
+        libc::ETIMEDOUT => TimedOut,
+        libc::ETXTBSY => ExecutableFileBusy,
+        libc::EXDEV => CrossesDevices,
+
+        libc::EACCES | libc::EPERM => PermissionDenied,
 
         // These two constants can have the same value on some systems,
         // but different values on others, so we can't use a match
         // clause
-        x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => ErrorKind::WouldBlock,
+        x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
 
-        _ => ErrorKind::Other,
+        _ => Uncategorized,
     }
 }
 
@@ -195,13 +220,41 @@ pub fn cvt_nz(error: libc::c_int) -> crate::io::Result<()> {
     if error == 0 { Ok(()) } else { Err(crate::io::Error::from_raw_os_error(error)) }
 }
 
-// On Unix-like platforms, libc::abort will unregister signal handlers
-// including the SIGABRT handler, preventing the abort from being blocked, and
-// fclose streams, with the side effect of flushing them so libc buffered
-// output will be printed.  Additionally the shell will generally print a more
-// understandable error message like "Abort trap" rather than "Illegal
-// instruction" that intrinsics::abort would cause, as intrinsics::abort is
-// implemented as an illegal instruction.
+// libc::abort() will run the SIGABRT handler.  That's fine because anyone who
+// installs a SIGABRT handler already has to expect it to run in Very Bad
+// situations (eg, malloc crashing).
+//
+// Current glibc's abort() function unblocks SIGABRT, raises SIGABRT, clears the
+// SIGABRT handler and raises it again, and then starts to get creative.
+//
+// See the public documentation for `intrinsics::abort()` and `process::abort()`
+// for further discussion.
+//
+// There is confusion about whether libc::abort() flushes stdio streams.
+// libc::abort() is required by ISO C 99 (7.14.1.1p5) to be async-signal-safe,
+// so flushing streams is at least extremely hard, if not entirely impossible.
+//
+// However, some versions of POSIX (eg IEEE Std 1003.1-2001) required abort to
+// do so.  In 1003.1-2004 this was fixed.
+//
+// glibc's implementation did the flush, unsafely, before glibc commit
+// 91e7cf982d01 `abort: Do not flush stdio streams [BZ #15436]' by Florian
+// Weimer.  According to glibc's NEWS:
+//
+//    The abort function terminates the process immediately, without flushing
+//    stdio streams.  Previous glibc versions used to flush streams, resulting
+//    in deadlocks and further data corruption.  This change also affects
+//    process aborts as the result of assertion failures.
+//
+// This is an accurate description of the problem.  The only solution for
+// program with nontrivial use of C stdio is a fixed libc - one which does not
+// try to flush in abort - since even libc-internal errors, and assertion
+// failures generated from C, will go via abort().
+//
+// On systems with old, buggy, libcs, the impact can be severe for a
+// multithreaded C program.  It is much less severe for Rust, because Rust
+// stdlib doesn't use libc stdio buffering.  In a typical Rust program, which
+// does not use C stdio, even a buggy libc::abort() is, in fact, safe.
 pub fn abort_internal() -> ! {
     unsafe { libc::abort() }
 }
@@ -240,7 +293,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "macos")] {
         #[link(name = "System")]
         // res_init and friends require -lresolv on macOS/iOS.
-        // See #41582 and http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
+        // See #41582 and https://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
         #[link(name = "resolv")]
         extern "C" {}
     } else if #[cfg(target_os = "ios")] {
@@ -256,3 +309,19 @@ cfg_if::cfg_if! {
         extern "C" {}
     }
 }
+
+#[cfg(target_os = "espidf")]
+mod unsupported {
+    use crate::io;
+
+    pub fn unsupported<T>() -> io::Result<T> {
+        Err(unsupported_err())
+    }
+
+    pub fn unsupported_err() -> io::Error {
+        io::Error::new_const(
+            io::ErrorKind::Unsupported,
+            &"operation not supported on this platform",
+        )
+    }
+}
diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs
index d5a15964c08..3f614fde08a 100644
--- a/library/std/src/sys/unix/net.rs
+++ b/library/std/src/sys/unix/net.rs
@@ -9,7 +9,7 @@ use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::{Duration, Instant};
 
-use libc::{c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK};
+use libc::{c_int, c_void, size_t, sockaddr, socklen_t, MSG_PEEK};
 
 pub use crate::sys::{cvt, cvt_r};
 
@@ -30,15 +30,21 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
     // We may need to trigger a glibc workaround. See on_resolver_failure() for details.
     on_resolver_failure();
 
-    if err == EAI_SYSTEM {
+    #[cfg(not(target_os = "espidf"))]
+    if err == libc::EAI_SYSTEM {
         return Err(io::Error::last_os_error());
     }
 
+    #[cfg(not(target_os = "espidf"))]
     let detail = unsafe {
         str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap().to_owned()
     };
+
+    #[cfg(target_os = "espidf")]
+    let detail = "";
+
     Err(io::Error::new(
-        io::ErrorKind::Other,
+        io::ErrorKind::Uncategorized,
         &format!("failed to lookup address information: {}", detail)[..],
     ))
 }
@@ -178,7 +184,7 @@ impl Socket {
                     if pollfd.revents & libc::POLLHUP != 0 {
                         let e = self.take_error()?.unwrap_or_else(|| {
                             io::Error::new_const(
-                                io::ErrorKind::Other,
+                                io::ErrorKind::Uncategorized,
                                 &"no error set after POLLHUP",
                             )
                         });
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index bbc4691d963..1d5ffb07321 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -20,10 +20,12 @@ use crate::str;
 use crate::sys::cvt;
 use crate::sys::fd;
 use crate::sys::memchr;
-use crate::sys::rwlock::{RWLockReadGuard, StaticRWLock};
-use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard};
+use crate::sys_common::rwlock::{StaticRWLock, StaticRWLockReadGuard};
 use crate::vec;
 
+#[cfg(all(target_env = "gnu", not(target_os = "vxworks")))]
+use crate::sys::weak::weak;
+
 use libc::{c_char, c_int, c_void};
 
 const TMPBUF_SZ: usize = 128;
@@ -126,6 +128,12 @@ pub fn error_string(errno: i32) -> String {
     }
 }
 
+#[cfg(target_os = "espidf")]
+pub fn getcwd() -> io::Result<PathBuf> {
+    Ok(PathBuf::from("/"))
+}
+
+#[cfg(not(target_os = "espidf"))]
 pub fn getcwd() -> io::Result<PathBuf> {
     let mut buf = Vec::with_capacity(512);
     loop {
@@ -152,6 +160,12 @@ pub fn getcwd() -> io::Result<PathBuf> {
     }
 }
 
+#[cfg(target_os = "espidf")]
+pub fn chdir(p: &path::Path) -> io::Result<()> {
+    super::unsupported::unsupported()
+}
+
+#[cfg(not(target_os = "espidf"))]
 pub fn chdir(p: &path::Path) -> io::Result<()> {
     let p: &OsStr = p.as_ref();
     let p = CString::new(p.as_bytes())?;
@@ -280,7 +294,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
             ))?;
             if path_len <= 1 {
                 return Err(io::Error::new_const(
-                    io::ErrorKind::Other,
+                    io::ErrorKind::Uncategorized,
                     &"KERN_PROC_PATHNAME sysctl returned zero-length string",
                 ));
             }
@@ -303,7 +317,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
             return crate::fs::read_link(curproc_exe);
         }
         Err(io::Error::new_const(
-            io::ErrorKind::Other,
+            io::ErrorKind::Uncategorized,
             &"/proc/curproc/exe doesn't point to regular file.",
         ))
     }
@@ -321,7 +335,10 @@ pub fn current_exe() -> io::Result<PathBuf> {
         cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?;
         argv.set_len(argv_len as usize);
         if argv[0].is_null() {
-            return Err(io::Error::new_const(io::ErrorKind::Other, &"no current exe available"));
+            return Err(io::Error::new_const(
+                io::ErrorKind::Uncategorized,
+                &"no current exe available",
+            ));
         }
         let argv0 = CStr::from_ptr(argv[0]).to_bytes();
         if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
@@ -336,7 +353,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 pub fn current_exe() -> io::Result<PathBuf> {
     match crate::fs::read_link("/proc/self/exe") {
         Err(ref e) if e.kind() == io::ErrorKind::NotFound => Err(io::Error::new_const(
-            io::ErrorKind::Other,
+            io::ErrorKind::Uncategorized,
             &"no /proc/self/exe available. Is /proc mounted?",
         )),
         other => other,
@@ -345,17 +362,14 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 pub fn current_exe() -> io::Result<PathBuf> {
-    extern "C" {
-        fn _NSGetExecutablePath(buf: *mut libc::c_char, bufsize: *mut u32) -> libc::c_int;
-    }
     unsafe {
         let mut sz: u32 = 0;
-        _NSGetExecutablePath(ptr::null_mut(), &mut sz);
+        libc::_NSGetExecutablePath(ptr::null_mut(), &mut sz);
         if sz == 0 {
             return Err(io::Error::last_os_error());
         }
         let mut v: Vec<u8> = Vec::with_capacity(sz as usize);
-        let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
+        let err = libc::_NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
         if err != 0 {
             return Err(io::Error::last_os_error());
         }
@@ -386,46 +400,21 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 #[cfg(target_os = "haiku")]
 pub fn current_exe() -> io::Result<PathBuf> {
-    // Use Haiku's image info functions
-    #[repr(C)]
-    struct image_info {
-        id: i32,
-        type_: i32,
-        sequence: i32,
-        init_order: i32,
-        init_routine: *mut libc::c_void, // function pointer
-        term_routine: *mut libc::c_void, // function pointer
-        device: libc::dev_t,
-        node: libc::ino_t,
-        name: [libc::c_char; 1024], // MAXPATHLEN
-        text: *mut libc::c_void,
-        data: *mut libc::c_void,
-        text_size: i32,
-        data_size: i32,
-        api_version: i32,
-        abi: i32,
-    }
-
     unsafe {
-        extern "C" {
-            fn _get_next_image_info(
-                team_id: i32,
-                cookie: *mut i32,
-                info: *mut image_info,
-                size: i32,
-            ) -> i32;
-        }
-
-        let mut info: image_info = mem::zeroed();
+        let mut info: mem::MaybeUninit<libc::image_info> = mem::MaybeUninit::uninit();
         let mut cookie: i32 = 0;
         // the executable can be found at team id 0
-        let result =
-            _get_next_image_info(0, &mut cookie, &mut info, mem::size_of::<image_info>() as i32);
+        let result = libc::_get_next_image_info(
+            0,
+            &mut cookie,
+            info.as_mut_ptr(),
+            mem::size_of::<libc::image_info>(),
+        );
         if result != 0 {
             use crate::io::ErrorKind;
-            Err(io::Error::new_const(ErrorKind::Other, &"Error getting executable path"))
+            Err(io::Error::new_const(ErrorKind::Uncategorized, &"Error getting executable path"))
         } else {
-            let name = CStr::from_ptr(info.name.as_ptr()).to_bytes();
+            let name = CStr::from_ptr((*info.as_ptr()).name.as_ptr()).to_bytes();
             Ok(PathBuf::from(OsStr::from_bytes(name)))
         }
     }
@@ -455,6 +444,11 @@ pub fn current_exe() -> io::Result<PathBuf> {
     path.canonicalize()
 }
 
+#[cfg(target_os = "espidf")]
+pub fn current_exe() -> io::Result<PathBuf> {
+    super::unsupported::unsupported()
+}
+
 pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
 }
@@ -490,8 +484,8 @@ pub unsafe fn environ() -> *mut *const *const c_char {
 
 static ENV_LOCK: StaticRWLock = StaticRWLock::new();
 
-pub fn env_read_lock() -> RWLockReadGuard {
-    ENV_LOCK.read_with_guard()
+pub fn env_read_lock() -> StaticRWLockReadGuard {
+    ENV_LOCK.read()
 }
 
 /// Returns a vector of (variable, value) byte-vector pairs for all the
@@ -530,19 +524,18 @@ pub fn env() -> Env {
     }
 }
 
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
+pub fn getenv(k: &OsStr) -> Option<OsString> {
     // environment variables with a nul byte can't be set, so their value is
     // always None as well
-    let k = CString::new(k.as_bytes())?;
+    let k = CString::new(k.as_bytes()).ok()?;
     unsafe {
         let _guard = env_read_lock();
         let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
-        let ret = if s.is_null() {
+        if s.is_null() {
             None
         } else {
             Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
-        };
-        Ok(ret)
+        }
     }
 }
 
@@ -551,7 +544,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
     let v = CString::new(v.as_bytes())?;
 
     unsafe {
-        let _guard = ENV_LOCK.write_with_guard();
+        let _guard = ENV_LOCK.write();
         cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
     }
 }
@@ -560,11 +553,12 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> {
     let nbuf = CString::new(n.as_bytes())?;
 
     unsafe {
-        let _guard = ENV_LOCK.write_with_guard();
+        let _guard = ENV_LOCK.write();
         cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
     }
 }
 
+#[cfg(not(target_os = "espidf"))]
 pub fn page_size() -> usize {
     unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
 }
@@ -587,7 +581,8 @@ pub fn home_dir() -> Option<PathBuf> {
         target_os = "ios",
         target_os = "emscripten",
         target_os = "redox",
-        target_os = "vxworks"
+        target_os = "vxworks",
+        target_os = "espidf"
     ))]
     unsafe fn fallback() -> Option<OsString> {
         None
@@ -597,7 +592,8 @@ pub fn home_dir() -> Option<PathBuf> {
         target_os = "ios",
         target_os = "emscripten",
         target_os = "redox",
-        target_os = "vxworks"
+        target_os = "vxworks",
+        target_os = "espidf"
     )))]
     unsafe fn fallback() -> Option<OsString> {
         let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
diff --git a/library/std/src/sys/unix/os/tests.rs b/library/std/src/sys/unix/os/tests.rs
index 0e1dcb390a0..c445acf2722 100644
--- a/library/std/src/sys/unix/os/tests.rs
+++ b/library/std/src/sys/unix/os/tests.rs
@@ -1,12 +1,14 @@
 use super::*;
 
 #[test]
+#[cfg(not(target_os = "vxworks"))]
 fn test_glibc_version() {
     // This mostly just tests that the weak linkage doesn't panic wildly...
     glibc_version();
 }
 
 #[test]
+#[cfg(not(target_os = "vxworks"))]
 fn test_parse_glibc_version() {
     let cases = [
         ("0.0", Some((0, 0))),
diff --git a/library/std/src/sys_common/os_str_bytes.rs b/library/std/src/sys/unix/os_str.rs
index 32705c432fa..ae96d6b4df4 100644
--- a/library/std/src/sys_common/os_str_bytes.rs
+++ b/library/std/src/sys/unix/os_str.rs
@@ -2,36 +2,46 @@
 //! systems: just a `Vec<u8>`/`[u8]`.
 
 use crate::borrow::Cow;
-use crate::ffi::{OsStr, OsString};
 use crate::fmt;
+use crate::fmt::Write;
 use crate::mem;
 use crate::rc::Rc;
-use crate::sealed::Sealed;
 use crate::str;
 use crate::sync::Arc;
-use crate::sys_common::bytestring::debug_fmt_bytestring;
-use crate::sys_common::{AsInner, FromInner, IntoInner};
+use crate::sys_common::{AsInner, IntoInner};
 
-use core::str::lossy::Utf8Lossy;
+use core::str::lossy::{Utf8Lossy, Utf8LossyChunk};
+
+#[cfg(test)]
+#[path = "../unix/os_str/tests.rs"]
+mod tests;
 
 #[derive(Hash)]
-pub(crate) struct Buf {
+#[repr(transparent)]
+pub struct Buf {
     pub inner: Vec<u8>,
 }
 
-// FIXME:
-// `Buf::as_slice` current implementation relies
-// on `Slice` being layout-compatible with `[u8]`.
-// When attribute privacy is implemented, `Slice` should be annotated as `#[repr(transparent)]`.
-// Anyway, `Slice` representation and layout are considered implementation detail, are
-// not documented and must not be relied upon.
-pub(crate) struct Slice {
+#[repr(transparent)]
+pub struct Slice {
     pub inner: [u8],
 }
 
 impl fmt::Debug for Slice {
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        debug_fmt_bytestring(&self.inner, formatter)
+        // Writes out a valid unicode string with the correct escape sequences
+
+        formatter.write_str("\"")?;
+        for Utf8LossyChunk { valid, broken } in Utf8Lossy::from_bytes(&self.inner).chunks() {
+            for c in valid.chars().flat_map(|c| c.escape_debug()) {
+                formatter.write_char(c)?
+            }
+
+            for b in broken {
+                write!(formatter, "\\x{:02X}", b)?;
+            }
+        }
+        formatter.write_str("\"")
     }
 }
 
@@ -243,63 +253,3 @@ impl Slice {
         self.inner.eq_ignore_ascii_case(&other.inner)
     }
 }
-
-/// Platform-specific extensions to [`OsString`].
-///
-/// This trait is sealed: it cannot be implemented outside the standard library.
-/// This is so that future additional methods are not breaking changes.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStringExt: Sealed {
-    /// Creates an [`OsString`] from a byte vector.
-    ///
-    /// See the module documentation for an example.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn from_vec(vec: Vec<u8>) -> Self;
-
-    /// Yields the underlying byte vector of this [`OsString`].
-    ///
-    /// See the module documentation for an example.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn into_vec(self) -> Vec<u8>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStringExt for OsString {
-    fn from_vec(vec: Vec<u8>) -> OsString {
-        FromInner::from_inner(Buf { inner: vec })
-    }
-    fn into_vec(self) -> Vec<u8> {
-        self.into_inner().inner
-    }
-}
-
-/// Platform-specific extensions to [`OsStr`].
-///
-/// This trait is sealed: it cannot be implemented outside the standard library.
-/// This is so that future additional methods are not breaking changes.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStrExt: Sealed {
-    #[stable(feature = "rust1", since = "1.0.0")]
-    /// Creates an [`OsStr`] from a byte slice.
-    ///
-    /// See the module documentation for an example.
-    fn from_bytes(slice: &[u8]) -> &Self;
-
-    /// Gets the underlying byte view of the [`OsStr`] slice.
-    ///
-    /// See the module documentation for an example.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn as_bytes(&self) -> &[u8];
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStrExt for OsStr {
-    #[inline]
-    fn from_bytes(slice: &[u8]) -> &OsStr {
-        unsafe { mem::transmute(slice) }
-    }
-    #[inline]
-    fn as_bytes(&self) -> &[u8] {
-        &self.as_inner().inner
-    }
-}
diff --git a/library/std/src/sys/unix/os_str/tests.rs b/library/std/src/sys/unix/os_str/tests.rs
new file mode 100644
index 00000000000..37967378155
--- /dev/null
+++ b/library/std/src/sys/unix/os_str/tests.rs
@@ -0,0 +1,10 @@
+use super::*;
+
+#[test]
+fn slice_debug_output() {
+    let input = Slice::from_u8_slice(b"\xF0hello,\tworld");
+    let expected = r#""\xF0hello,\tworld""#;
+    let output = format!("{:?}", input);
+
+    assert_eq!(output, expected);
+}
diff --git a/library/std/src/sys/unix/process/mod.rs b/library/std/src/sys/unix/process/mod.rs
index b5a19ed54a2..0165ece849e 100644
--- a/library/std/src/sys/unix/process/mod.rs
+++ b/library/std/src/sys/unix/process/mod.rs
@@ -13,6 +13,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "vxworks")] {
         #[path = "process_vxworks.rs"]
         mod process_inner;
+    } else if #[cfg(target_os = "espidf")] {
+        #[path = "process_unsupported.rs"]
+        mod process_inner;
     } else {
         #[path = "process_unix.rs"]
         mod process_inner;
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
index c5bdd1bda4a..a1972380a9f 100644
--- a/library/std/src/sys/unix/process/process_common.rs
+++ b/library/std/src/sys/unix/process/process_common.rs
@@ -50,7 +50,7 @@ cfg_if::cfg_if! {
             raw[bit / 8] |= 1 << (bit % 8);
             return 0;
         }
-    } else if #[cfg(not(target_os = "vxworks"))] {
+    } else {
         pub use libc::{sigemptyset, sigaddset};
     }
 }
@@ -79,6 +79,8 @@ pub struct Command {
     stdin: Option<Stdio>,
     stdout: Option<Stdio>,
     stderr: Option<Stdio>,
+    #[cfg(target_os = "linux")]
+    create_pidfd: bool,
 }
 
 // Create a new type for argv, so that we can make it `Send` and `Sync`
@@ -124,6 +126,28 @@ pub enum Stdio {
 }
 
 impl Command {
+    #[cfg(not(target_os = "linux"))]
+    pub fn new(program: &OsStr) -> Command {
+        let mut saw_nul = false;
+        let program = os2c(program, &mut saw_nul);
+        Command {
+            argv: Argv(vec![program.as_ptr(), ptr::null()]),
+            args: vec![program.clone()],
+            program,
+            env: Default::default(),
+            cwd: None,
+            uid: None,
+            gid: None,
+            saw_nul,
+            closures: Vec::new(),
+            groups: None,
+            stdin: None,
+            stdout: None,
+            stderr: None,
+        }
+    }
+
+    #[cfg(target_os = "linux")]
     pub fn new(program: &OsStr) -> Command {
         let mut saw_nul = false;
         let program = os2c(program, &mut saw_nul);
@@ -141,6 +165,7 @@ impl Command {
             stdin: None,
             stdout: None,
             stderr: None,
+            create_pidfd: false,
         }
     }
 
@@ -177,6 +202,22 @@ impl Command {
         self.groups = Some(Box::from(groups));
     }
 
+    #[cfg(target_os = "linux")]
+    pub fn create_pidfd(&mut self, val: bool) {
+        self.create_pidfd = val;
+    }
+
+    #[cfg(not(target_os = "linux"))]
+    #[allow(dead_code)]
+    pub fn get_create_pidfd(&self) -> bool {
+        false
+    }
+
+    #[cfg(target_os = "linux")]
+    pub fn get_create_pidfd(&self) -> bool {
+        self.create_pidfd
+    }
+
     pub fn saw_nul(&self) -> bool {
         self.saw_nul
     }
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index ed55e1aa715..4b210d6af13 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -9,6 +9,20 @@ use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::process_common::*;
 
+#[cfg(target_os = "linux")]
+use crate::os::linux::process::PidFd;
+
+#[cfg(target_os = "linux")]
+use crate::sys::weak::syscall;
+
+#[cfg(any(
+    target_os = "macos",
+    target_os = "freebsd",
+    all(target_os = "linux", target_env = "gnu"),
+    all(target_os = "linux", target_env = "musl"),
+))]
+use crate::sys::weak::weak;
+
 #[cfg(target_os = "vxworks")]
 use libc::RTP_ID as pid_t;
 
@@ -53,7 +67,8 @@ impl Command {
         // a lock any more because the parent won't do anything and the child is
         // in its own process. Thus the parent drops the lock guard while the child
         // forgets it to avoid unlocking it on a new thread, which would be invalid.
-        let (env_lock, pid) = unsafe { (sys::os::env_read_lock(), cvt(libc::fork())?) };
+        let env_lock = sys::os::env_read_lock();
+        let (pid, pidfd) = unsafe { self.do_fork()? };
 
         if pid == 0 {
             crate::panic::always_abort();
@@ -82,7 +97,7 @@ impl Command {
         drop(env_lock);
         drop(output);
 
-        let mut p = Process { pid, status: None };
+        let mut p = Process::new(pid, pidfd);
         let mut bytes = [0; 8];
 
         // loop to handle EINTR
@@ -114,6 +129,92 @@ impl Command {
         }
     }
 
+    // Attempts to fork the process. If successful, returns Ok((0, -1))
+    // in the child, and Ok((child_pid, -1)) in the parent.
+    #[cfg(not(target_os = "linux"))]
+    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
+        cvt(libc::fork()).map(|res| (res, -1))
+    }
+
+    // Attempts to fork the process. If successful, returns Ok((0, -1))
+    // in the child, and Ok((child_pid, child_pidfd)) in the parent.
+    #[cfg(target_os = "linux")]
+    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
+        use crate::sync::atomic::{AtomicBool, Ordering};
+
+        static HAS_CLONE3: AtomicBool = AtomicBool::new(true);
+        const CLONE_PIDFD: u64 = 0x00001000;
+
+        #[repr(C)]
+        struct clone_args {
+            flags: u64,
+            pidfd: u64,
+            child_tid: u64,
+            parent_tid: u64,
+            exit_signal: u64,
+            stack: u64,
+            stack_size: u64,
+            tls: u64,
+            set_tid: u64,
+            set_tid_size: u64,
+            cgroup: u64,
+        }
+
+        syscall! {
+            fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long
+        }
+
+        // If we fail to create a pidfd for any reason, this will
+        // stay as -1, which indicates an error.
+        let mut pidfd: pid_t = -1;
+
+        // Attempt to use the `clone3` syscall, which supports more arguments
+        // (in particular, the ability to create a pidfd). If this fails,
+        // we will fall through this block to a call to `fork()`
+        if HAS_CLONE3.load(Ordering::Relaxed) {
+            let mut flags = 0;
+            if self.get_create_pidfd() {
+                flags |= CLONE_PIDFD;
+            }
+
+            let mut args = clone_args {
+                flags,
+                pidfd: &mut pidfd as *mut pid_t as u64,
+                child_tid: 0,
+                parent_tid: 0,
+                exit_signal: libc::SIGCHLD as u64,
+                stack: 0,
+                stack_size: 0,
+                tls: 0,
+                set_tid: 0,
+                set_tid_size: 0,
+                cgroup: 0,
+            };
+
+            let args_ptr = &mut args as *mut clone_args;
+            let args_size = crate::mem::size_of::<clone_args>();
+
+            let res = cvt(clone3(args_ptr, args_size));
+            match res {
+                Ok(n) => return Ok((n as pid_t, pidfd)),
+                Err(e) => match e.raw_os_error() {
+                    // Multiple threads can race to execute this store,
+                    // but that's fine - that just means that multiple threads
+                    // will have tried and failed to execute the same syscall,
+                    // with no other side effects.
+                    Some(libc::ENOSYS) => HAS_CLONE3.store(false, Ordering::Relaxed),
+                    // Fallback to fork if `EPERM` is returned. (e.g. blocked by seccomp)
+                    Some(libc::EPERM) => {}
+                    _ => return Err(e),
+                },
+            }
+        }
+
+        // If we get here, the 'clone3' syscall does not exist
+        // or we do not have permission to call it
+        cvt(libc::fork()).map(|res| (res, pidfd))
+    }
+
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         let envp = self.capture_env();
 
@@ -300,6 +401,7 @@ impl Command {
             || (self.env_saw_path() && !self.program_is_path())
             || !self.get_closures().is_empty()
             || self.get_groups().is_some()
+            || self.get_create_pidfd()
         {
             return Ok(None);
         }
@@ -344,7 +446,7 @@ impl Command {
             None => None,
         };
 
-        let mut p = Process { pid: 0, status: None };
+        let mut p = Process::new(0, -1);
 
         struct PosixSpawnFileActions<'a>(&'a mut MaybeUninit<libc::posix_spawn_file_actions_t>);
 
@@ -433,9 +535,27 @@ impl Command {
 pub struct Process {
     pid: pid_t,
     status: Option<ExitStatus>,
+    // On Linux, stores the pidfd created for this child.
+    // This is None if the user did not request pidfd creation,
+    // or if the pidfd could not be created for some reason
+    // (e.g. the `clone3` syscall was not available).
+    #[cfg(target_os = "linux")]
+    pidfd: Option<PidFd>,
 }
 
 impl Process {
+    #[cfg(target_os = "linux")]
+    fn new(pid: pid_t, pidfd: pid_t) -> Self {
+        use crate::sys_common::FromInner;
+        let pidfd = (pidfd >= 0).then(|| PidFd::from_inner(sys::fd::FileDesc::new(pidfd)));
+        Process { pid, status: None, pidfd }
+    }
+
+    #[cfg(not(target_os = "linux"))]
+    fn new(pid: pid_t, _pidfd: pid_t) -> Self {
+        Process { pid, status: None }
+    }
+
     pub fn id(&self) -> u32 {
         self.pid as u32
     }
@@ -572,6 +692,24 @@ impl ExitStatusError {
     }
 }
 
+#[cfg(target_os = "linux")]
+#[unstable(feature = "linux_pidfd", issue = "82971")]
+impl crate::os::linux::process::ChildExt for crate::process::Child {
+    fn pidfd(&self) -> io::Result<&PidFd> {
+        self.handle
+            .pidfd
+            .as_ref()
+            .ok_or_else(|| Error::new(ErrorKind::Other, "No pidfd was created."))
+    }
+
+    fn take_pidfd(&mut self) -> io::Result<PidFd> {
+        self.handle
+            .pidfd
+            .take()
+            .ok_or_else(|| Error::new(ErrorKind::Other, "No pidfd was created."))
+    }
+}
+
 #[cfg(test)]
 #[path = "process_unix/tests.rs"]
 mod tests;
diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs
new file mode 100644
index 00000000000..7d549d060fd
--- /dev/null
+++ b/library/std/src/sys/unix/process/process_unsupported.rs
@@ -0,0 +1,122 @@
+use crate::convert::{TryFrom, TryInto};
+use crate::fmt;
+use crate::io;
+use crate::io::ErrorKind;
+use crate::num::NonZeroI32;
+use crate::os::raw::NonZero_c_int;
+use crate::sys;
+use crate::sys::cvt;
+use crate::sys::pipe::AnonPipe;
+use crate::sys::process::process_common::*;
+use crate::sys::unix::unsupported::*;
+
+use libc::{c_int, pid_t};
+
+////////////////////////////////////////////////////////////////////////////////
+// Command
+////////////////////////////////////////////////////////////////////////////////
+
+impl Command {
+    pub fn spawn(
+        &mut self,
+        default: Stdio,
+        needs_stdin: bool,
+    ) -> io::Result<(Process, StdioPipes)> {
+        unsupported()
+    }
+
+    pub fn exec(&mut self, default: Stdio) -> io::Error {
+        unsupported_err()
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Processes
+////////////////////////////////////////////////////////////////////////////////
+
+pub struct Process {
+    handle: pid_t,
+}
+
+impl Process {
+    pub fn id(&self) -> u32 {
+        0
+    }
+
+    pub fn kill(&mut self) -> io::Result<()> {
+        unsupported()
+    }
+
+    pub fn wait(&mut self) -> io::Result<ExitStatus> {
+        unsupported()
+    }
+
+    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
+        unsupported()
+    }
+}
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitStatus(c_int);
+
+impl ExitStatus {
+    pub fn success(&self) -> bool {
+        self.code() == Some(0)
+    }
+
+    pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
+        Err(ExitStatusError(1.try_into().unwrap()))
+    }
+
+    pub fn code(&self) -> Option<i32> {
+        None
+    }
+
+    pub fn signal(&self) -> Option<i32> {
+        None
+    }
+
+    pub fn core_dumped(&self) -> bool {
+        false
+    }
+
+    pub fn stopped_signal(&self) -> Option<i32> {
+        None
+    }
+
+    pub fn continued(&self) -> bool {
+        false
+    }
+
+    pub fn into_raw(&self) -> c_int {
+        0
+    }
+}
+
+/// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying.
+impl From<c_int> for ExitStatus {
+    fn from(a: c_int) -> ExitStatus {
+        ExitStatus(a as i32)
+    }
+}
+
+impl fmt::Display for ExitStatus {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "exit code: {}", self.0)
+    }
+}
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitStatusError(NonZero_c_int);
+
+impl Into<ExitStatus> for ExitStatusError {
+    fn into(self) -> ExitStatus {
+        ExitStatus(self.0.into())
+    }
+}
+
+impl ExitStatusError {
+    pub fn code(self) -> Option<NonZeroI32> {
+        ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap())
+    }
+}
diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs
index 44f9eabc319..7a3f6b0d95a 100644
--- a/library/std/src/sys/unix/rand.rs
+++ b/library/std/src/sys/unix/rand.rs
@@ -26,6 +26,9 @@ mod imp {
     use crate::io::Read;
 
     #[cfg(any(target_os = "linux", target_os = "android"))]
+    use crate::sys::weak::syscall;
+
+    #[cfg(any(target_os = "linux", target_os = "android"))]
     fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
         // A weak symbol allows interposition, e.g. for perf measurements that want to
         // disable randomness for consistency. Otherwise, we'll try a raw syscall.
@@ -41,12 +44,17 @@ mod imp {
         unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) }
     }
 
-    #[cfg(not(any(target_os = "linux", target_os = "android")))]
+    #[cfg(target_os = "espidf")]
+    fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
+        unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
+    }
+
+    #[cfg(not(any(target_os = "linux", target_os = "android", target_os = "espidf")))]
     fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool {
         false
     }
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
+    #[cfg(any(target_os = "linux", target_os = "android", target_os = "espidf"))]
     fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
         use crate::sync::atomic::{AtomicBool, Ordering};
         use crate::sys::os::errno;
@@ -108,6 +116,7 @@ mod imp {
     use crate::fs::File;
     use crate::io::Read;
     use crate::sys::os::errno;
+    use crate::sys::weak::weak;
     use libc::{c_int, c_void, size_t};
 
     fn getentropy_fill_bytes(v: &mut [u8]) -> bool {
diff --git a/library/std/src/sys/unix/rwlock.rs b/library/std/src/sys/unix/rwlock.rs
index d97d9d712fc..b1faf12c226 100644
--- a/library/std/src/sys/unix/rwlock.rs
+++ b/library/std/src/sys/unix/rwlock.rs
@@ -7,6 +7,8 @@ pub struct RWLock {
     num_readers: AtomicUsize,
 }
 
+pub type MovableRWLock = Box<RWLock>;
+
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
@@ -139,55 +141,3 @@ impl RWLock {
         }
     }
 }
-
-pub struct StaticRWLock(RWLock);
-
-impl StaticRWLock {
-    pub const fn new() -> StaticRWLock {
-        StaticRWLock(RWLock::new())
-    }
-
-    /// Acquires shared access to the underlying lock, blocking the current
-    /// thread to do so.
-    ///
-    /// The lock is automatically unlocked when the returned guard is dropped.
-    #[inline]
-    pub fn read_with_guard(&'static self) -> RWLockReadGuard {
-        // SAFETY: All methods require static references, therefore self
-        // cannot be moved between invocations.
-        unsafe {
-            self.0.read();
-        }
-        RWLockReadGuard(&self.0)
-    }
-
-    /// Acquires write access to the underlying lock, blocking the current thread
-    /// to do so.
-    ///
-    /// The lock is automatically unlocked when the returned guard is dropped.
-    #[inline]
-    pub fn write_with_guard(&'static self) -> RWLockWriteGuard {
-        // SAFETY: All methods require static references, therefore self
-        // cannot be moved between invocations.
-        unsafe {
-            self.0.write();
-        }
-        RWLockWriteGuard(&self.0)
-    }
-}
-
-pub struct RWLockReadGuard(&'static RWLock);
-
-impl Drop for RWLockReadGuard {
-    fn drop(&mut self) {
-        unsafe { self.0.read_unlock() }
-    }
-}
-
-pub struct RWLockWriteGuard(&'static RWLock);
-
-impl Drop for RWLockWriteGuard {
-    fn drop(&mut self) {
-        unsafe { self.0.write_unlock() }
-    }
-}
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index b8f43caec32..133ad3ea420 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -2,16 +2,38 @@ use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
+use crate::num::NonZeroUsize;
 use crate::ptr;
 use crate::sys::{os, stack_overflow};
 use crate::time::Duration;
 
-#[cfg(not(any(target_os = "l4re", target_os = "vxworks")))]
+#[cfg(any(target_os = "linux", target_os = "solaris", target_os = "illumos"))]
+use crate::sys::weak::weak;
+#[cfg(not(any(target_os = "l4re", target_os = "vxworks", target_os = "espidf")))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
 #[cfg(target_os = "l4re")]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
 #[cfg(target_os = "vxworks")]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 256 * 1024;
+#[cfg(target_os = "espidf")]
+pub const DEFAULT_MIN_STACK_SIZE: usize = 0; // 0 indicates that the stack size configured in the ESP-IDF menuconfig system should be used
+
+#[cfg(target_os = "fuchsia")]
+mod zircon {
+    type zx_handle_t = u32;
+    type zx_status_t = i32;
+    pub const ZX_PROP_NAME: u32 = 3;
+
+    extern "C" {
+        pub fn zx_object_set_property(
+            handle: zx_handle_t,
+            property: u32,
+            value: *const libc::c_void,
+            value_size: libc::size_t,
+        ) -> zx_status_t;
+        pub fn zx_thread_self() -> zx_handle_t;
+    }
+}
 
 pub struct Thread {
     id: libc::pthread_t,
@@ -30,22 +52,35 @@ impl Thread {
         let mut attr: libc::pthread_attr_t = mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
 
-        let stack_size = cmp::max(stack, min_stack_size(&attr));
-
-        match libc::pthread_attr_setstacksize(&mut attr, stack_size) {
-            0 => {}
-            n => {
-                assert_eq!(n, libc::EINVAL);
-                // EINVAL means |stack_size| is either too small or not a
-                // multiple of the system page size.  Because it's definitely
-                // >= PTHREAD_STACK_MIN, it must be an alignment issue.
-                // Round up to the nearest page and try again.
-                let page_size = os::page_size();
-                let stack_size =
-                    (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
-                assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
-            }
-        };
+        #[cfg(target_os = "espidf")]
+        if stack > 0 {
+            // Only set the stack if a non-zero value is passed
+            // 0 is used as an indication that the default stack size configured in the ESP-IDF menuconfig system should be used
+            assert_eq!(
+                libc::pthread_attr_setstacksize(&mut attr, cmp::max(stack, min_stack_size(&attr))),
+                0
+            );
+        }
+
+        #[cfg(not(target_os = "espidf"))]
+        {
+            let stack_size = cmp::max(stack, min_stack_size(&attr));
+
+            match libc::pthread_attr_setstacksize(&mut attr, stack_size) {
+                0 => {}
+                n => {
+                    assert_eq!(n, libc::EINVAL);
+                    // EINVAL means |stack_size| is either too small or not a
+                    // multiple of the system page size.  Because it's definitely
+                    // >= PTHREAD_STACK_MIN, it must be an alignment issue.
+                    // Round up to the nearest page and try again.
+                    let page_size = os::page_size();
+                    let stack_size =
+                        (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
+                    assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
+                }
+            };
+        }
 
         let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
         // Note: if the thread creation fails and this assert fails, then p will
@@ -131,22 +166,39 @@ impl Thread {
         }
     }
 
+    #[cfg(target_os = "fuchsia")]
+    pub fn set_name(name: &CStr) {
+        use self::zircon::*;
+        unsafe {
+            zx_object_set_property(
+                zx_thread_self(),
+                ZX_PROP_NAME,
+                name.as_ptr() as *const libc::c_void,
+                name.to_bytes().len(),
+            );
+        }
+    }
+
+    #[cfg(target_os = "haiku")]
+    pub fn set_name(name: &CStr) {
+        unsafe {
+            let thread_self = libc::find_thread(ptr::null_mut());
+            libc::rename_thread(thread_self, name.as_ptr());
+        }
+    }
+
     #[cfg(any(
         target_env = "newlib",
-        target_os = "haiku",
         target_os = "l4re",
         target_os = "emscripten",
         target_os = "redox",
         target_os = "vxworks"
     ))]
     pub fn set_name(_name: &CStr) {
-        // Newlib, Haiku, Emscripten, and VxWorks have no way to set a thread name.
-    }
-    #[cfg(target_os = "fuchsia")]
-    pub fn set_name(_name: &CStr) {
-        // FIXME: determine whether Fuchsia has a way to set a thread name.
+        // Newlib, Emscripten, and VxWorks have no way to set a thread name.
     }
 
+    #[cfg(not(target_os = "espidf"))]
     pub fn sleep(dur: Duration) {
         let mut secs = dur.as_secs();
         let mut nsecs = dur.subsec_nanos() as _;
@@ -172,6 +224,19 @@ impl Thread {
         }
     }
 
+    #[cfg(target_os = "espidf")]
+    pub fn sleep(dur: Duration) {
+        let mut micros = dur.as_micros();
+        unsafe {
+            while micros > 0 {
+                let st = if micros > u32::MAX as u128 { u32::MAX } else { micros as u32 };
+                libc::usleep(st);
+
+                micros -= st as u128;
+            }
+        }
+    }
+
     pub fn join(self) {
         unsafe {
             let ret = libc::pthread_join(self.id, ptr::null_mut());
@@ -198,6 +263,88 @@ impl Drop for Thread {
     }
 }
 
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    cfg_if::cfg_if! {
+        if #[cfg(any(
+            target_os = "android",
+            target_os = "emscripten",
+            target_os = "fuchsia",
+            target_os = "ios",
+            target_os = "linux",
+            target_os = "macos",
+            target_os = "solaris",
+            target_os = "illumos",
+        ))] {
+            match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
+                -1 => Err(io::Error::last_os_error()),
+                0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")),
+                cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }),
+            }
+        } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] {
+            use crate::ptr;
+
+            let mut cpus: libc::c_uint = 0;
+            let mut cpus_size = crate::mem::size_of_val(&cpus);
+
+            unsafe {
+                cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
+            }
+
+            // Fallback approach in case of errors or no hardware threads.
+            if cpus < 1 {
+                let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
+                let res = unsafe {
+                    libc::sysctl(
+                        mib.as_mut_ptr(),
+                        2,
+                        &mut cpus as *mut _ as *mut _,
+                        &mut cpus_size as *mut _ as *mut _,
+                        ptr::null_mut(),
+                        0,
+                    )
+                };
+
+                // Handle errors if any.
+                if res == -1 {
+                    return Err(io::Error::last_os_error());
+                } else if cpus == 0 {
+                    return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
+                }
+            }
+            Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
+        } else if #[cfg(target_os = "openbsd")] {
+            use crate::ptr;
+
+            let mut cpus: libc::c_uint = 0;
+            let mut cpus_size = crate::mem::size_of_val(&cpus);
+            let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
+
+            let res = unsafe {
+                libc::sysctl(
+                    mib.as_mut_ptr(),
+                    2,
+                    &mut cpus as *mut _ as *mut _,
+                    &mut cpus_size as *mut _ as *mut _,
+                    ptr::null_mut(),
+                    0,
+                )
+            };
+
+            // Handle errors if any.
+            if res == -1 {
+                return Err(io::Error::last_os_error());
+            } else if cpus == 0 {
+                return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
+            }
+
+            Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
+        } else {
+            // FIXME: implement on vxWorks, Redox, Haiku, l4re
+            Err(io::Error::new_const(io::ErrorKind::Unsupported, &"Getting the number of hardware threads is not supported on the target platform"))
+        }
+    }
+}
+
 #[cfg(all(
     not(target_os = "linux"),
     not(target_os = "freebsd"),
diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs
index 23a5c81c005..7dc09add27f 100644
--- a/library/std/src/sys/unix/time.rs
+++ b/library/std/src/sys/unix/time.rs
@@ -361,9 +361,9 @@ mod inner {
         }
     }
 
-    #[cfg(not(target_os = "dragonfly"))]
+    #[cfg(not(any(target_os = "dragonfly", target_os = "espidf")))]
     pub type clock_t = libc::c_int;
-    #[cfg(target_os = "dragonfly")]
+    #[cfg(any(target_os = "dragonfly", target_os = "espidf"))]
     pub type clock_t = libc::c_ulong;
 
     fn now(clock: clock_t) -> Timespec {
diff --git a/library/std/src/sys/unix/weak.rs b/library/std/src/sys/unix/weak.rs
index 432fe4c33bc..ba432ec5494 100644
--- a/library/std/src/sys/unix/weak.rs
+++ b/library/std/src/sys/unix/weak.rs
@@ -26,8 +26,9 @@ use crate::marker;
 use crate::mem;
 use crate::sync::atomic::{self, AtomicUsize, Ordering};
 
-macro_rules! weak {
+pub(crate) macro weak {
     (fn $name:ident($($t:ty),*) -> $ret:ty) => (
+        #[allow(non_upper_case_globals)]
         static $name: crate::sys::weak::Weak<unsafe extern "C" fn($($t),*) -> $ret> =
             crate::sys::weak::Weak::new(concat!(stringify!($name), '\0'));
     )
@@ -101,7 +102,7 @@ unsafe fn fetch(name: &str) -> usize {
 }
 
 #[cfg(not(any(target_os = "linux", target_os = "android")))]
-macro_rules! syscall {
+pub(crate) macro syscall {
     (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
         unsafe fn $name($($arg_name: $t),*) -> $ret {
             use super::os;
@@ -119,9 +120,10 @@ macro_rules! syscall {
 }
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
-macro_rules! syscall {
+pub(crate) macro syscall {
     (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => (
         unsafe fn $name($($arg_name:$t),*) -> $ret {
+            use weak;
             // This looks like a hack, but concat_idents only accepts idents
             // (not paths).
             use libc::*;
diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs
index 6e72a7c632e..a06b44e96a9 100644
--- a/library/std/src/sys/unsupported/common.rs
+++ b/library/std/src/sys/unsupported/common.rs
@@ -4,8 +4,6 @@ pub mod memchr {
     pub use core::slice::memchr::{memchr, memrchr};
 }
 
-pub use crate::sys_common::os_str_bytes as os_str;
-
 // This is not necessarily correct. May want to consider making it part of the
 // spec definition?
 use crate::os::raw::c_char;
@@ -30,7 +28,7 @@ pub fn unsupported_err() -> std_io::Error {
 }
 
 pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind {
-    crate::io::ErrorKind::Other
+    crate::io::ErrorKind::Uncategorized
 }
 
 pub fn abort_internal() -> ! {
diff --git a/library/std/src/sys/unsupported/mod.rs b/library/std/src/sys/unsupported/mod.rs
index 3ef4c6b8a8f..a1276193bda 100644
--- a/library/std/src/sys/unsupported/mod.rs
+++ b/library/std/src/sys/unsupported/mod.rs
@@ -11,6 +11,8 @@ pub mod io;
 pub mod mutex;
 pub mod net;
 pub mod os;
+#[path = "../unix/os_str.rs"]
+pub mod os_str;
 #[path = "../unix/path.rs"]
 pub mod path;
 pub mod pipe;
diff --git a/library/std/src/sys/unsupported/os.rs b/library/std/src/sys/unsupported/os.rs
index e30395a0b1d..2886ec1180e 100644
--- a/library/std/src/sys/unsupported/os.rs
+++ b/library/std/src/sys/unsupported/os.rs
@@ -76,8 +76,8 @@ pub fn env() -> Env {
     panic!("not supported on this platform")
 }
 
-pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
-    Ok(None)
+pub fn getenv(_: &OsStr) -> Option<OsString> {
+    None
 }
 
 pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
diff --git a/library/std/src/sys/unsupported/rwlock.rs b/library/std/src/sys/unsupported/rwlock.rs
index 6982b2b155f..8438adeb5b5 100644
--- a/library/std/src/sys/unsupported/rwlock.rs
+++ b/library/std/src/sys/unsupported/rwlock.rs
@@ -5,6 +5,8 @@ pub struct RWLock {
     mode: Cell<isize>,
 }
 
+pub type MovableRWLock = RWLock;
+
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {} // no threads on this platform
 
diff --git a/library/std/src/sys/unsupported/thread.rs b/library/std/src/sys/unsupported/thread.rs
index cda8510e1ba..dc75d4ee672 100644
--- a/library/std/src/sys/unsupported/thread.rs
+++ b/library/std/src/sys/unsupported/thread.rs
@@ -1,6 +1,7 @@
 use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
+use crate::num::NonZeroUsize;
 use crate::time::Duration;
 
 pub struct Thread(!);
@@ -30,6 +31,10 @@ impl Thread {
     }
 }
 
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    unsupported()
+}
+
 pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> {
diff --git a/library/std/src/sys/wasi/fd.rs b/library/std/src/sys/wasi/fd.rs
index ba66eba2ad3..1f6ea8d6e8d 100644
--- a/library/std/src/sys/wasi/fd.rs
+++ b/library/std/src/sys/wasi/fd.rs
@@ -5,10 +5,11 @@ use super::err2io;
 use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem;
 use crate::net::Shutdown;
+use crate::os::raw::c_int;
 
 #[derive(Debug)]
 pub struct WasiFd {
-    fd: wasi::Fd,
+    fd: c_int,
 }
 
 fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
@@ -26,38 +27,38 @@ fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
 }
 
 impl WasiFd {
-    pub unsafe fn from_raw(fd: wasi::Fd) -> WasiFd {
+    pub unsafe fn from_raw(fd: c_int) -> WasiFd {
         WasiFd { fd }
     }
 
-    pub fn into_raw(self) -> wasi::Fd {
+    pub fn into_raw(self) -> c_int {
         let ret = self.fd;
         mem::forget(self);
         ret
     }
 
-    pub fn as_raw(&self) -> wasi::Fd {
+    pub fn as_raw(&self) -> c_int {
         self.fd
     }
 
     pub fn datasync(&self) -> io::Result<()> {
-        unsafe { wasi::fd_datasync(self.fd).map_err(err2io) }
+        unsafe { wasi::fd_datasync(self.fd as wasi::Fd).map_err(err2io) }
     }
 
     pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) }
+        unsafe { wasi::fd_pread(self.fd as wasi::Fd, iovec(bufs), offset).map_err(err2io) }
     }
 
     pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) }
+        unsafe { wasi::fd_pwrite(self.fd as wasi::Fd, ciovec(bufs), offset).map_err(err2io) }
     }
 
     pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) }
+        unsafe { wasi::fd_read(self.fd as wasi::Fd, iovec(bufs)).map_err(err2io) }
     }
 
     pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) }
+        unsafe { wasi::fd_write(self.fd as wasi::Fd, ciovec(bufs)).map_err(err2io) }
     }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
@@ -66,37 +67,37 @@ impl WasiFd {
             SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
             SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
         };
-        unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) }
+        unsafe { wasi::fd_seek(self.fd as wasi::Fd, offset, whence).map_err(err2io) }
     }
 
     pub fn tell(&self) -> io::Result<u64> {
-        unsafe { wasi::fd_tell(self.fd).map_err(err2io) }
+        unsafe { wasi::fd_tell(self.fd as wasi::Fd).map_err(err2io) }
     }
 
     // FIXME: __wasi_fd_fdstat_get
 
     pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> {
-        unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
+        unsafe { wasi::fd_fdstat_set_flags(self.fd as wasi::Fd, flags).map_err(err2io) }
     }
 
     pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
-        unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) }
+        unsafe { wasi::fd_fdstat_set_rights(self.fd as wasi::Fd, base, inheriting).map_err(err2io) }
     }
 
     pub fn sync(&self) -> io::Result<()> {
-        unsafe { wasi::fd_sync(self.fd).map_err(err2io) }
+        unsafe { wasi::fd_sync(self.fd as wasi::Fd).map_err(err2io) }
     }
 
     pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
-        unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) }
+        unsafe { wasi::fd_advise(self.fd as wasi::Fd, offset, len, advice).map_err(err2io) }
     }
 
     pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
-        unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
+        unsafe { wasi::fd_allocate(self.fd as wasi::Fd, offset, len).map_err(err2io) }
     }
 
     pub fn create_directory(&self, path: &str) -> io::Result<()> {
-        unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
+        unsafe { wasi::path_create_directory(self.fd as wasi::Fd, path).map_err(err2io) }
     }
 
     pub fn link(
@@ -107,7 +108,14 @@ impl WasiFd {
         new_path: &str,
     ) -> io::Result<()> {
         unsafe {
-            wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path).map_err(err2io)
+            wasi::path_link(
+                self.fd as wasi::Fd,
+                old_flags,
+                old_path,
+                new_fd.fd as wasi::Fd,
+                new_path,
+            )
+            .map_err(err2io)
         }
     }
 
@@ -122,7 +130,7 @@ impl WasiFd {
     ) -> io::Result<WasiFd> {
         unsafe {
             wasi::path_open(
-                self.fd,
+                self.fd as wasi::Fd,
                 dirflags,
                 path,
                 oflags,
@@ -130,25 +138,34 @@ impl WasiFd {
                 fs_rights_inheriting,
                 fs_flags,
             )
-            .map(|fd| WasiFd::from_raw(fd))
+            .map(|fd| WasiFd::from_raw(fd as c_int))
             .map_err(err2io)
         }
     }
 
     pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result<usize> {
-        unsafe { wasi::fd_readdir(self.fd, buf.as_mut_ptr(), buf.len(), cookie).map_err(err2io) }
+        unsafe {
+            wasi::fd_readdir(self.fd as wasi::Fd, buf.as_mut_ptr(), buf.len(), cookie)
+                .map_err(err2io)
+        }
     }
 
     pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result<usize> {
-        unsafe { wasi::path_readlink(self.fd, path, buf.as_mut_ptr(), buf.len()).map_err(err2io) }
+        unsafe {
+            wasi::path_readlink(self.fd as wasi::Fd, path, buf.as_mut_ptr(), buf.len())
+                .map_err(err2io)
+        }
     }
 
     pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> {
-        unsafe { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) }
+        unsafe {
+            wasi::path_rename(self.fd as wasi::Fd, old_path, new_fd.fd as wasi::Fd, new_path)
+                .map_err(err2io)
+        }
     }
 
     pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
-        unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
+        unsafe { wasi::fd_filestat_get(self.fd as wasi::Fd).map_err(err2io) }
     }
 
     pub fn filestat_set_times(
@@ -157,11 +174,13 @@ impl WasiFd {
         mtim: wasi::Timestamp,
         fstflags: wasi::Fstflags,
     ) -> io::Result<()> {
-        unsafe { wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io) }
+        unsafe {
+            wasi::fd_filestat_set_times(self.fd as wasi::Fd, atim, mtim, fstflags).map_err(err2io)
+        }
     }
 
     pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
-        unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) }
+        unsafe { wasi::fd_filestat_set_size(self.fd as wasi::Fd, size).map_err(err2io) }
     }
 
     pub fn path_filestat_get(
@@ -169,7 +188,7 @@ impl WasiFd {
         flags: wasi::Lookupflags,
         path: &str,
     ) -> io::Result<wasi::Filestat> {
-        unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
+        unsafe { wasi::path_filestat_get(self.fd as wasi::Fd, flags, path).map_err(err2io) }
     }
 
     pub fn path_filestat_set_times(
@@ -181,21 +200,21 @@ impl WasiFd {
         fstflags: wasi::Fstflags,
     ) -> io::Result<()> {
         unsafe {
-            wasi::path_filestat_set_times(self.fd, flags, path, atim, mtim, fstflags)
+            wasi::path_filestat_set_times(self.fd as wasi::Fd, flags, path, atim, mtim, fstflags)
                 .map_err(err2io)
         }
     }
 
     pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> {
-        unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) }
+        unsafe { wasi::path_symlink(old_path, self.fd as wasi::Fd, new_path).map_err(err2io) }
     }
 
     pub fn unlink_file(&self, path: &str) -> io::Result<()> {
-        unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
+        unsafe { wasi::path_unlink_file(self.fd as wasi::Fd, path).map_err(err2io) }
     }
 
     pub fn remove_directory(&self, path: &str) -> io::Result<()> {
-        unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
+        unsafe { wasi::path_remove_directory(self.fd as wasi::Fd, path).map_err(err2io) }
     }
 
     pub fn sock_recv(
@@ -203,11 +222,11 @@ impl WasiFd {
         ri_data: &mut [IoSliceMut<'_>],
         ri_flags: wasi::Riflags,
     ) -> io::Result<(usize, wasi::Roflags)> {
-        unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) }
+        unsafe { wasi::sock_recv(self.fd as wasi::Fd, iovec(ri_data), ri_flags).map_err(err2io) }
     }
 
     pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result<usize> {
-        unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) }
+        unsafe { wasi::sock_send(self.fd as wasi::Fd, ciovec(si_data), si_flags).map_err(err2io) }
     }
 
     pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
@@ -216,7 +235,7 @@ impl WasiFd {
             Shutdown::Write => wasi::SDFLAGS_WR,
             Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD,
         };
-        unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
+        unsafe { wasi::sock_shutdown(self.fd as wasi::Fd, how).map_err(err2io) }
     }
 }
 
@@ -224,6 +243,6 @@ impl Drop for WasiFd {
     fn drop(&mut self) {
         // FIXME: can we handle the return code here even though we can't on
         // unix?
-        let _ = unsafe { wasi::fd_close(self.fd) };
+        let _ = unsafe { wasi::fd_close(self.fd as wasi::Fd) };
     }
 }
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 45e38f68b8c..55c9c652a8b 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -6,6 +6,7 @@ use crate::fmt;
 use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
 use crate::iter;
 use crate::mem::{self, ManuallyDrop};
+use crate::os::raw::c_int;
 use crate::os::wasi::ffi::{OsStrExt, OsStringExt};
 use crate::path::{Path, PathBuf};
 use crate::ptr;
@@ -454,8 +455,8 @@ impl File {
     }
 }
 
-impl FromInner<u32> for File {
-    fn from_inner(fd: u32) -> File {
+impl FromInner<c_int> for File {
+    fn from_inner(fd: c_int) -> File {
         unsafe { File { fd: WasiFd::from_raw(fd) } }
     }
 }
@@ -648,12 +649,12 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
                      through which {:?} could be opened",
                     p
                 );
-                return Err(io::Error::new(io::ErrorKind::Other, msg));
+                return Err(io::Error::new(io::ErrorKind::Uncategorized, msg));
             }
             let relative = CStr::from_ptr(relative_path).to_bytes().to_vec();
 
             return Ok((
-                ManuallyDrop::new(WasiFd::from_raw(fd as u32)),
+                ManuallyDrop::new(WasiFd::from_raw(fd as c_int)),
                 PathBuf::from(OsString::from_vec(relative)),
             ));
         }
@@ -670,7 +671,8 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
 }
 
 pub fn osstr2str(f: &OsStr) -> io::Result<&str> {
-    f.to_str().ok_or_else(|| io::Error::new_const(io::ErrorKind::Other, &"input must be utf-8"))
+    f.to_str()
+        .ok_or_else(|| io::Error::new_const(io::ErrorKind::Uncategorized, &"input must be utf-8"))
 }
 
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs
index 45a829c0cd2..8d62335aae5 100644
--- a/library/std/src/sys/wasi/mod.rs
+++ b/library/std/src/sys/wasi/mod.rs
@@ -32,7 +32,8 @@ pub mod io;
 pub mod mutex;
 pub mod net;
 pub mod os;
-pub use crate::sys_common::os_str_bytes as os_str;
+#[path = "../unix/os_str.rs"]
+pub mod os_str;
 #[path = "../unix/path.rs"]
 pub mod path;
 #[path = "../unsupported/pipe.rs"]
@@ -58,7 +59,7 @@ pub use common::*;
 pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
     use std_io::ErrorKind::*;
     if errno > u16::MAX as i32 || errno < 0 {
-        return Other;
+        return Uncategorized;
     }
     match errno as u16 {
         wasi::ERRNO_CONNREFUSED => ConnectionRefused,
@@ -77,7 +78,7 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
         wasi::ERRNO_AGAIN => WouldBlock,
         wasi::ERRNO_NOSYS => Unsupported,
         wasi::ERRNO_NOMEM => OutOfMemory,
-        _ => Other,
+        _ => Uncategorized,
     }
 }
 
diff --git a/library/std/src/sys/wasi/net.rs b/library/std/src/sys/wasi/net.rs
index 06860673d90..50b7352933e 100644
--- a/library/std/src/sys/wasi/net.rs
+++ b/library/std/src/sys/wasi/net.rs
@@ -5,6 +5,7 @@ use crate::convert::TryFrom;
 use crate::fmt;
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
+use crate::os::raw::c_int;
 use crate::sys::unsupported;
 use crate::sys_common::FromInner;
 use crate::time::Duration;
@@ -115,8 +116,8 @@ impl TcpStream {
     }
 }
 
-impl FromInner<u32> for TcpStream {
-    fn from_inner(fd: u32) -> TcpStream {
+impl FromInner<c_int> for TcpStream {
+    fn from_inner(fd: c_int) -> TcpStream {
         unsafe { TcpStream { fd: WasiFd::from_raw(fd) } }
     }
 }
@@ -181,8 +182,8 @@ impl TcpListener {
     }
 }
 
-impl FromInner<u32> for TcpListener {
-    fn from_inner(fd: u32) -> TcpListener {
+impl FromInner<c_int> for TcpListener {
+    fn from_inner(fd: c_int) -> TcpListener {
         unsafe { TcpListener { fd: WasiFd::from_raw(fd) } }
     }
 }
@@ -331,8 +332,8 @@ impl UdpSocket {
     }
 }
 
-impl FromInner<u32> for UdpSocket {
-    fn from_inner(fd: u32) -> UdpSocket {
+impl FromInner<c_int> for UdpSocket {
+    fn from_inner(fd: c_int) -> UdpSocket {
         unsafe { UdpSocket { fd: WasiFd::from_raw(fd) } }
     }
 }
diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs
index f129ee55a83..c5229a18834 100644
--- a/library/std/src/sys/wasi/os.rs
+++ b/library/std/src/sys/wasi/os.rs
@@ -175,17 +175,16 @@ pub fn env() -> Env {
     }
 }
 
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
-    let k = CString::new(k.as_bytes())?;
+pub fn getenv(k: &OsStr) -> Option<OsString> {
+    let k = CString::new(k.as_bytes()).ok()?;
     unsafe {
         let _guard = env_lock();
         let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
-        let ret = if s.is_null() {
+        if s.is_null() {
             None
         } else {
             Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
-        };
-        Ok(ret)
+        }
     }
 }
 
diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs
index 209d5b996e5..8782f333a1f 100644
--- a/library/std/src/sys/wasi/stdio.rs
+++ b/library/std/src/sys/wasi/stdio.rs
@@ -3,6 +3,7 @@
 use super::fd::WasiFd;
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
+use crate::os::raw;
 
 pub struct Stdin;
 pub struct Stdout;
@@ -14,7 +15,7 @@ impl Stdin {
     }
 
     #[inline]
-    pub fn as_raw_fd(&self) -> u32 {
+    pub fn as_raw_fd(&self) -> raw::c_int {
         0
     }
 }
@@ -40,7 +41,7 @@ impl Stdout {
     }
 
     #[inline]
-    pub fn as_raw_fd(&self) -> u32 {
+    pub fn as_raw_fd(&self) -> raw::c_int {
         1
     }
 }
@@ -69,7 +70,7 @@ impl Stderr {
     }
 
     #[inline]
-    pub fn as_raw_fd(&self) -> u32 {
+    pub fn as_raw_fd(&self) -> raw::c_int {
         2
     }
 }
diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs
index 74515553a82..9ec02bbec26 100644
--- a/library/std/src/sys/wasi/thread.rs
+++ b/library/std/src/sys/wasi/thread.rs
@@ -3,6 +3,7 @@
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
+use crate::num::NonZeroUsize;
 use crate::sys::unsupported;
 use crate::time::Duration;
 
@@ -63,6 +64,10 @@ impl Thread {
     }
 }
 
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    unsupported()
+}
+
 pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> {
diff --git a/library/std/src/sys/wasm/atomics/rwlock.rs b/library/std/src/sys/wasm/atomics/rwlock.rs
index 06442e925f4..64eaa2fc482 100644
--- a/library/std/src/sys/wasm/atomics/rwlock.rs
+++ b/library/std/src/sys/wasm/atomics/rwlock.rs
@@ -8,6 +8,8 @@ pub struct RWLock {
     state: UnsafeCell<State>,
 }
 
+pub type MovableRWLock = RWLock;
+
 enum State {
     Unlocked,
     Reading(usize),
diff --git a/library/std/src/sys/wasm/atomics/thread.rs b/library/std/src/sys/wasm/atomics/thread.rs
index 54bc877aa7d..a66ab083757 100644
--- a/library/std/src/sys/wasm/atomics/thread.rs
+++ b/library/std/src/sys/wasm/atomics/thread.rs
@@ -1,5 +1,6 @@
 use crate::ffi::CStr;
 use crate::io;
+use crate::num::NonZeroUsize;
 use crate::sys::unsupported;
 use crate::time::Duration;
 
@@ -39,6 +40,10 @@ impl Thread {
     pub fn join(self) {}
 }
 
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    unsupported()
+}
+
 pub mod guard {
     pub type Guard = !;
     pub unsafe fn current() -> Option<Guard> {
diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs
index cd701a333f8..c81d653a5e3 100644
--- a/library/std/src/sys/wasm/mod.rs
+++ b/library/std/src/sys/wasm/mod.rs
@@ -30,6 +30,8 @@ pub mod io;
 pub mod net;
 #[path = "../unsupported/os.rs"]
 pub mod os;
+#[path = "../unix/os_str.rs"]
+pub mod os_str;
 #[path = "../unix/path.rs"]
 pub mod path;
 #[path = "../unsupported/pipe.rs"]
@@ -45,8 +47,6 @@ pub mod thread_local_key;
 #[path = "../unsupported/time.rs"]
 pub mod time;
 
-pub use crate::sys_common::os_str_bytes as os_str;
-
 cfg_if::cfg_if! {
     if #[cfg(target_feature = "atomics")] {
         #[path = "atomics/condvar.rs"]
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index b7efc884473..63f9be7b7e3 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -10,9 +10,14 @@ use crate::ptr;
 
 use libc::{c_void, size_t, wchar_t};
 
+#[path = "c/errors.rs"] // c.rs is included from two places so we need to specify this
+mod errors;
+pub use errors::*;
+
 pub use self::EXCEPTION_DISPOSITION::*;
 pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
 
+pub type DWORD_PTR = ULONG_PTR;
 pub type DWORD = c_ulong;
 pub type NonZeroDWORD = NonZero_c_ulong;
 pub type HANDLE = LPVOID;
@@ -53,6 +58,7 @@ pub type LPWSADATA = *mut WSADATA;
 pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;
 pub type LPWSTR = *mut WCHAR;
 pub type LPFILETIME = *mut FILETIME;
+pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
 pub type LPWSABUF = *mut WSABUF;
 pub type LPWSAOVERLAPPED = *mut c_void;
 pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = *mut c_void;
@@ -68,6 +74,10 @@ pub type ADDRESS_FAMILY = USHORT;
 pub const TRUE: BOOL = 1;
 pub const FALSE: BOOL = 0;
 
+pub const CSTR_LESS_THAN: c_int = 1;
+pub const CSTR_EQUAL: c_int = 2;
+pub const CSTR_GREATER_THAN: c_int = 3;
+
 pub const FILE_ATTRIBUTE_READONLY: DWORD = 0x1;
 pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10;
 pub const FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;
@@ -132,19 +142,6 @@ pub const WSASYS_STATUS_LEN: usize = 128;
 pub const WSAPROTOCOL_LEN: DWORD = 255;
 pub const INVALID_SOCKET: SOCKET = !0;
 
-pub const WSAEACCES: c_int = 10013;
-pub const WSAEINVAL: c_int = 10022;
-pub const WSAEWOULDBLOCK: c_int = 10035;
-pub const WSAEPROTOTYPE: c_int = 10041;
-pub const WSAEADDRINUSE: c_int = 10048;
-pub const WSAEADDRNOTAVAIL: c_int = 10049;
-pub const WSAECONNABORTED: c_int = 10053;
-pub const WSAECONNRESET: c_int = 10054;
-pub const WSAENOTCONN: c_int = 10057;
-pub const WSAESHUTDOWN: c_int = 10058;
-pub const WSAETIMEDOUT: c_int = 10060;
-pub const WSAECONNREFUSED: c_int = 10061;
-
 pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
 
 pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
@@ -164,42 +161,6 @@ pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
 
 pub const PROGRESS_CONTINUE: DWORD = 0;
 
-// List of Windows system error codes with descriptions:
-// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes
-pub const ERROR_FILE_NOT_FOUND: DWORD = 2;
-pub const ERROR_PATH_NOT_FOUND: DWORD = 3;
-pub const ERROR_ACCESS_DENIED: DWORD = 5;
-pub const ERROR_INVALID_HANDLE: DWORD = 6;
-pub const ERROR_NOT_ENOUGH_MEMORY: DWORD = 8;
-pub const ERROR_OUTOFMEMORY: DWORD = 14;
-pub const ERROR_NO_MORE_FILES: DWORD = 18;
-pub const ERROR_SHARING_VIOLATION: u32 = 32;
-pub const ERROR_HANDLE_EOF: DWORD = 38;
-pub const ERROR_FILE_EXISTS: DWORD = 80;
-pub const ERROR_INVALID_PARAMETER: DWORD = 87;
-pub const ERROR_BROKEN_PIPE: DWORD = 109;
-pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
-pub const ERROR_SEM_TIMEOUT: DWORD = 121;
-pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
-pub const ERROR_ALREADY_EXISTS: DWORD = 183;
-pub const ERROR_ENVVAR_NOT_FOUND: DWORD = 203;
-pub const ERROR_NO_DATA: DWORD = 232;
-pub const ERROR_DRIVER_CANCEL_TIMEOUT: DWORD = 594;
-pub const ERROR_OPERATION_ABORTED: DWORD = 995;
-pub const ERROR_IO_PENDING: DWORD = 997;
-pub const ERROR_SERVICE_REQUEST_TIMEOUT: DWORD = 1053;
-pub const ERROR_COUNTER_TIMEOUT: DWORD = 1121;
-pub const ERROR_TIMEOUT: DWORD = 1460;
-pub const ERROR_RESOURCE_CALL_TIMED_OUT: DWORD = 5910;
-pub const ERROR_CTX_MODEM_RESPONSE_TIMEOUT: DWORD = 7012;
-pub const ERROR_CTX_CLIENT_QUERY_TIMEOUT: DWORD = 7040;
-pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: DWORD = 8014;
-pub const ERROR_DS_TIMELIMIT_EXCEEDED: DWORD = 8226;
-pub const DNS_ERROR_RECORD_TIMED_OUT: DWORD = 9705;
-pub const ERROR_IPSEC_IKE_TIMED_OUT: DWORD = 13805;
-pub const ERROR_RUNLEVEL_SWITCH_TIMEOUT: DWORD = 15402;
-pub const ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT: DWORD = 15403;
-
 pub const E_NOTIMPL: HRESULT = 0x80004001u32 as HRESULT;
 
 pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
@@ -234,6 +195,7 @@ pub const SD_RECEIVE: c_int = 0;
 pub const SD_SEND: c_int = 1;
 pub const SOCK_DGRAM: c_int = 2;
 pub const SOCK_STREAM: c_int = 1;
+pub const SOCKET_ERROR: c_int = -1;
 pub const SOL_SOCKET: c_int = 0xffff;
 pub const SO_RCVTIMEO: c_int = 0x1006;
 pub const SO_SNDTIMEO: c_int = 0x1005;
@@ -533,6 +495,21 @@ pub struct FILETIME {
 }
 
 #[repr(C)]
+pub struct SYSTEM_INFO {
+    pub wProcessorArchitecture: WORD,
+    pub wReserved: WORD,
+    pub dwPageSize: DWORD,
+    pub lpMinimumApplicationAddress: LPVOID,
+    pub lpMaximumApplicationAddress: LPVOID,
+    pub dwActiveProcessorMask: DWORD_PTR,
+    pub dwNumberOfProcessors: DWORD,
+    pub dwProcessorType: DWORD,
+    pub dwAllocationGranularity: DWORD,
+    pub wProcessorLevel: WORD,
+    pub wProcessorRevision: WORD,
+}
+
+#[repr(C)]
 pub struct OVERLAPPED {
     pub Internal: *mut c_ulong,
     pub InternalHigh: *mut c_ulong,
@@ -933,6 +910,7 @@ extern "system" {
     pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
 
     pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
+    pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO);
 
     pub fn CreateEventW(
         lpEventAttributes: LPSECURITY_ATTRIBUTES,
@@ -996,6 +974,14 @@ extern "system" {
     pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK);
     pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN;
     pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN;
+
+    pub fn CompareStringOrdinal(
+        lpString1: LPCWSTR,
+        cchCount1: c_int,
+        lpString2: LPCWSTR,
+        cchCount2: c_int,
+        bIgnoreCase: BOOL,
+    ) -> c_int;
 }
 
 #[link(name = "ws2_32")]
diff --git a/library/std/src/sys/windows/c/errors.rs b/library/std/src/sys/windows/c/errors.rs
new file mode 100644
index 00000000000..23dcc119db9
--- /dev/null
+++ b/library/std/src/sys/windows/c/errors.rs
@@ -0,0 +1,1883 @@
+// List of Windows system error codes with descriptions:
+// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes
+
+#![allow(dead_code)]
+
+use super::{c_int, DWORD};
+
+pub const ERROR_DIRECTORY_NOT_SUPPORTED: DWORD = 336;
+pub const ERROR_DRIVER_CANCEL_TIMEOUT: DWORD = 594;
+pub const ERROR_DISK_QUOTA_EXCEEDED: DWORD = 1295;
+pub const ERROR_RESOURCE_CALL_TIMED_OUT: DWORD = 5910;
+pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: DWORD = 8014;
+pub const DNS_ERROR_RECORD_TIMED_OUT: DWORD = 9705;
+
+// The followiung list was obtained from
+//   `/usr/x86_64-w64-mingw32/include/winerror.h`
+// in the Debian package
+//   mingw-w64_6.0.0-3_all.deb
+//
+// The header of that file says:
+//   * This file has no copyright assigned and is placed in the Public Domain.
+//   * This file is part of the mingw-w64 runtime package.
+//   * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+//
+// The text here is the result of the following rune:
+//   grep -P '#define ERROR' /usr/x86_64-w64-mingw32/include/winerror.h >>library/std/src/sys/windows/c/errors.rs
+//   grep -P '#define WSA' /usr/x86_64-w64-mingw32/include/winerror.h >>library/std/src/sys/windows/c/errors.rs
+// and then using some manually-invented but rather obvious editor search-and-replace
+// invocations, plus some straightforward manual fixups, to turn it into Rust syntax
+// and remove all the duplicates from the manual table above.
+
+pub const ERROR_SUCCESS: DWORD = 0;
+pub const ERROR_INVALID_FUNCTION: DWORD = 1;
+pub const ERROR_FILE_NOT_FOUND: DWORD = 2;
+pub const ERROR_PATH_NOT_FOUND: DWORD = 3;
+pub const ERROR_TOO_MANY_OPEN_FILES: DWORD = 4;
+pub const ERROR_ACCESS_DENIED: DWORD = 5;
+pub const ERROR_INVALID_HANDLE: DWORD = 6;
+pub const ERROR_ARENA_TRASHED: DWORD = 7;
+pub const ERROR_NOT_ENOUGH_MEMORY: DWORD = 8;
+pub const ERROR_INVALID_BLOCK: DWORD = 9;
+pub const ERROR_BAD_ENVIRONMENT: DWORD = 10;
+pub const ERROR_BAD_FORMAT: DWORD = 11;
+pub const ERROR_INVALID_ACCESS: DWORD = 12;
+pub const ERROR_INVALID_DATA: DWORD = 13;
+pub const ERROR_OUTOFMEMORY: DWORD = 14;
+pub const ERROR_INVALID_DRIVE: DWORD = 15;
+pub const ERROR_CURRENT_DIRECTORY: DWORD = 16;
+pub const ERROR_NOT_SAME_DEVICE: DWORD = 17;
+pub const ERROR_NO_MORE_FILES: DWORD = 18;
+pub const ERROR_WRITE_PROTECT: DWORD = 19;
+pub const ERROR_BAD_UNIT: DWORD = 20;
+pub const ERROR_NOT_READY: DWORD = 21;
+pub const ERROR_BAD_COMMAND: DWORD = 22;
+pub const ERROR_CRC: DWORD = 23;
+pub const ERROR_BAD_LENGTH: DWORD = 24;
+pub const ERROR_SEEK: DWORD = 25;
+pub const ERROR_NOT_DOS_DISK: DWORD = 26;
+pub const ERROR_SECTOR_NOT_FOUND: DWORD = 27;
+pub const ERROR_OUT_OF_PAPER: DWORD = 28;
+pub const ERROR_WRITE_FAULT: DWORD = 29;
+pub const ERROR_READ_FAULT: DWORD = 30;
+pub const ERROR_GEN_FAILURE: DWORD = 31;
+pub const ERROR_SHARING_VIOLATION: DWORD = 32;
+pub const ERROR_LOCK_VIOLATION: DWORD = 33;
+pub const ERROR_WRONG_DISK: DWORD = 34;
+pub const ERROR_SHARING_BUFFER_EXCEEDED: DWORD = 36;
+pub const ERROR_HANDLE_EOF: DWORD = 38;
+pub const ERROR_HANDLE_DISK_FULL: DWORD = 39;
+pub const ERROR_NOT_SUPPORTED: DWORD = 50;
+pub const ERROR_REM_NOT_LIST: DWORD = 51;
+pub const ERROR_DUP_NAME: DWORD = 52;
+pub const ERROR_BAD_NETPATH: DWORD = 53;
+pub const ERROR_NETWORK_BUSY: DWORD = 54;
+pub const ERROR_DEV_NOT_EXIST: DWORD = 55;
+pub const ERROR_TOO_MANY_CMDS: DWORD = 56;
+pub const ERROR_ADAP_HDW_ERR: DWORD = 57;
+pub const ERROR_BAD_NET_RESP: DWORD = 58;
+pub const ERROR_UNEXP_NET_ERR: DWORD = 59;
+pub const ERROR_BAD_REM_ADAP: DWORD = 60;
+pub const ERROR_PRINTQ_FULL: DWORD = 61;
+pub const ERROR_NO_SPOOL_SPACE: DWORD = 62;
+pub const ERROR_PRINT_CANCELLED: DWORD = 63;
+pub const ERROR_NETNAME_DELETED: DWORD = 64;
+pub const ERROR_NETWORK_ACCESS_DENIED: DWORD = 65;
+pub const ERROR_BAD_DEV_TYPE: DWORD = 66;
+pub const ERROR_BAD_NET_NAME: DWORD = 67;
+pub const ERROR_TOO_MANY_NAMES: DWORD = 68;
+pub const ERROR_TOO_MANY_SESS: DWORD = 69;
+pub const ERROR_SHARING_PAUSED: DWORD = 70;
+pub const ERROR_REQ_NOT_ACCEP: DWORD = 71;
+pub const ERROR_REDIR_PAUSED: DWORD = 72;
+pub const ERROR_FILE_EXISTS: DWORD = 80;
+pub const ERROR_CANNOT_MAKE: DWORD = 82;
+pub const ERROR_FAIL_I24: DWORD = 83;
+pub const ERROR_OUT_OF_STRUCTURES: DWORD = 84;
+pub const ERROR_ALREADY_ASSIGNED: DWORD = 85;
+pub const ERROR_INVALID_PASSWORD: DWORD = 86;
+pub const ERROR_INVALID_PARAMETER: DWORD = 87;
+pub const ERROR_NET_WRITE_FAULT: DWORD = 88;
+pub const ERROR_NO_PROC_SLOTS: DWORD = 89;
+pub const ERROR_TOO_MANY_SEMAPHORES: DWORD = 100;
+pub const ERROR_EXCL_SEM_ALREADY_OWNED: DWORD = 101;
+pub const ERROR_SEM_IS_SET: DWORD = 102;
+pub const ERROR_TOO_MANY_SEM_REQUESTS: DWORD = 103;
+pub const ERROR_INVALID_AT_INTERRUPT_TIME: DWORD = 104;
+pub const ERROR_SEM_OWNER_DIED: DWORD = 105;
+pub const ERROR_SEM_USER_LIMIT: DWORD = 106;
+pub const ERROR_DISK_CHANGE: DWORD = 107;
+pub const ERROR_DRIVE_LOCKED: DWORD = 108;
+pub const ERROR_BROKEN_PIPE: DWORD = 109;
+pub const ERROR_OPEN_FAILED: DWORD = 110;
+pub const ERROR_BUFFER_OVERFLOW: DWORD = 111;
+pub const ERROR_DISK_FULL: DWORD = 112;
+pub const ERROR_NO_MORE_SEARCH_HANDLES: DWORD = 113;
+pub const ERROR_INVALID_TARGET_HANDLE: DWORD = 114;
+pub const ERROR_INVALID_CATEGORY: DWORD = 117;
+pub const ERROR_INVALID_VERIFY_SWITCH: DWORD = 118;
+pub const ERROR_BAD_DRIVER_LEVEL: DWORD = 119;
+pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
+pub const ERROR_SEM_TIMEOUT: DWORD = 121;
+pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
+pub const ERROR_INVALID_NAME: DWORD = 123;
+pub const ERROR_INVALID_LEVEL: DWORD = 124;
+pub const ERROR_NO_VOLUME_LABEL: DWORD = 125;
+pub const ERROR_MOD_NOT_FOUND: DWORD = 126;
+pub const ERROR_PROC_NOT_FOUND: DWORD = 127;
+pub const ERROR_WAIT_NO_CHILDREN: DWORD = 128;
+pub const ERROR_CHILD_NOT_COMPLETE: DWORD = 129;
+pub const ERROR_DIRECT_ACCESS_HANDLE: DWORD = 130;
+pub const ERROR_NEGATIVE_SEEK: DWORD = 131;
+pub const ERROR_SEEK_ON_DEVICE: DWORD = 132;
+pub const ERROR_IS_JOIN_TARGET: DWORD = 133;
+pub const ERROR_IS_JOINED: DWORD = 134;
+pub const ERROR_IS_SUBSTED: DWORD = 135;
+pub const ERROR_NOT_JOINED: DWORD = 136;
+pub const ERROR_NOT_SUBSTED: DWORD = 137;
+pub const ERROR_JOIN_TO_JOIN: DWORD = 138;
+pub const ERROR_SUBST_TO_SUBST: DWORD = 139;
+pub const ERROR_JOIN_TO_SUBST: DWORD = 140;
+pub const ERROR_SUBST_TO_JOIN: DWORD = 141;
+pub const ERROR_BUSY_DRIVE: DWORD = 142;
+pub const ERROR_SAME_DRIVE: DWORD = 143;
+pub const ERROR_DIR_NOT_ROOT: DWORD = 144;
+pub const ERROR_DIR_NOT_EMPTY: DWORD = 145;
+pub const ERROR_IS_SUBST_PATH: DWORD = 146;
+pub const ERROR_IS_JOIN_PATH: DWORD = 147;
+pub const ERROR_PATH_BUSY: DWORD = 148;
+pub const ERROR_IS_SUBST_TARGET: DWORD = 149;
+pub const ERROR_SYSTEM_TRACE: DWORD = 150;
+pub const ERROR_INVALID_EVENT_COUNT: DWORD = 151;
+pub const ERROR_TOO_MANY_MUXWAITERS: DWORD = 152;
+pub const ERROR_INVALID_LIST_FORMAT: DWORD = 153;
+pub const ERROR_LABEL_TOO_LONG: DWORD = 154;
+pub const ERROR_TOO_MANY_TCBS: DWORD = 155;
+pub const ERROR_SIGNAL_REFUSED: DWORD = 156;
+pub const ERROR_DISCARDED: DWORD = 157;
+pub const ERROR_NOT_LOCKED: DWORD = 158;
+pub const ERROR_BAD_THREADID_ADDR: DWORD = 159;
+pub const ERROR_BAD_ARGUMENTS: DWORD = 160;
+pub const ERROR_BAD_PATHNAME: DWORD = 161;
+pub const ERROR_SIGNAL_PENDING: DWORD = 162;
+pub const ERROR_MAX_THRDS_REACHED: DWORD = 164;
+pub const ERROR_LOCK_FAILED: DWORD = 167;
+pub const ERROR_BUSY: DWORD = 170;
+pub const ERROR_CANCEL_VIOLATION: DWORD = 173;
+pub const ERROR_ATOMIC_LOCKS_NOT_SUPPORTED: DWORD = 174;
+pub const ERROR_INVALID_SEGMENT_NUMBER: DWORD = 180;
+pub const ERROR_INVALID_ORDINAL: DWORD = 182;
+pub const ERROR_ALREADY_EXISTS: DWORD = 183;
+pub const ERROR_INVALID_FLAG_NUMBER: DWORD = 186;
+pub const ERROR_SEM_NOT_FOUND: DWORD = 187;
+pub const ERROR_INVALID_STARTING_CODESEG: DWORD = 188;
+pub const ERROR_INVALID_STACKSEG: DWORD = 189;
+pub const ERROR_INVALID_MODULETYPE: DWORD = 190;
+pub const ERROR_INVALID_EXE_SIGNATURE: DWORD = 191;
+pub const ERROR_EXE_MARKED_INVALID: DWORD = 192;
+pub const ERROR_BAD_EXE_FORMAT: DWORD = 193;
+pub const ERROR_ITERATED_DATA_EXCEEDS_64k: DWORD = 194;
+pub const ERROR_INVALID_MINALLOCSIZE: DWORD = 195;
+pub const ERROR_DYNLINK_FROM_INVALID_RING: DWORD = 196;
+pub const ERROR_IOPL_NOT_ENABLED: DWORD = 197;
+pub const ERROR_INVALID_SEGDPL: DWORD = 198;
+pub const ERROR_AUTODATASEG_EXCEEDS_64k: DWORD = 199;
+pub const ERROR_RING2SEG_MUST_BE_MOVABLE: DWORD = 200;
+pub const ERROR_RELOC_CHAIN_XEEDS_SEGLIM: DWORD = 201;
+pub const ERROR_INFLOOP_IN_RELOC_CHAIN: DWORD = 202;
+pub const ERROR_ENVVAR_NOT_FOUND: DWORD = 203;
+pub const ERROR_NO_SIGNAL_SENT: DWORD = 205;
+pub const ERROR_FILENAME_EXCED_RANGE: DWORD = 206;
+pub const ERROR_RING2_STACK_IN_USE: DWORD = 207;
+pub const ERROR_META_EXPANSION_TOO_LONG: DWORD = 208;
+pub const ERROR_INVALID_SIGNAL_NUMBER: DWORD = 209;
+pub const ERROR_THREAD_1_INACTIVE: DWORD = 210;
+pub const ERROR_LOCKED: DWORD = 212;
+pub const ERROR_TOO_MANY_MODULES: DWORD = 214;
+pub const ERROR_NESTING_NOT_ALLOWED: DWORD = 215;
+pub const ERROR_EXE_MACHINE_TYPE_MISMATCH: DWORD = 216;
+pub const ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY: DWORD = 217;
+pub const ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY: DWORD = 218;
+pub const ERROR_FILE_CHECKED_OUT: DWORD = 220;
+pub const ERROR_CHECKOUT_REQUIRED: DWORD = 221;
+pub const ERROR_BAD_FILE_TYPE: DWORD = 222;
+pub const ERROR_FILE_TOO_LARGE: DWORD = 223;
+pub const ERROR_FORMS_AUTH_REQUIRED: DWORD = 224;
+pub const ERROR_PIPE_LOCAL: DWORD = 229;
+pub const ERROR_BAD_PIPE: DWORD = 230;
+pub const ERROR_PIPE_BUSY: DWORD = 231;
+pub const ERROR_NO_DATA: DWORD = 232;
+pub const ERROR_PIPE_NOT_CONNECTED: DWORD = 233;
+pub const ERROR_MORE_DATA: DWORD = 234;
+pub const ERROR_VC_DISCONNECTED: DWORD = 240;
+pub const ERROR_INVALID_EA_NAME: DWORD = 254;
+pub const ERROR_EA_LIST_INCONSISTENT: DWORD = 255;
+pub const ERROR_NO_MORE_ITEMS: DWORD = 259;
+pub const ERROR_CANNOT_COPY: DWORD = 266;
+pub const ERROR_DIRECTORY: DWORD = 267;
+pub const ERROR_EAS_DIDNT_FIT: DWORD = 275;
+pub const ERROR_EA_FILE_CORRUPT: DWORD = 276;
+pub const ERROR_EA_TABLE_FULL: DWORD = 277;
+pub const ERROR_INVALID_EA_HANDLE: DWORD = 278;
+pub const ERROR_EAS_NOT_SUPPORTED: DWORD = 282;
+pub const ERROR_NOT_OWNER: DWORD = 288;
+pub const ERROR_TOO_MANY_POSTS: DWORD = 298;
+pub const ERROR_PARTIAL_COPY: DWORD = 299;
+pub const ERROR_OPLOCK_NOT_GRANTED: DWORD = 300;
+pub const ERROR_INVALID_OPLOCK_PROTOCOL: DWORD = 301;
+pub const ERROR_DISK_TOO_FRAGMENTED: DWORD = 302;
+pub const ERROR_DELETE_PENDING: DWORD = 303;
+pub const ERROR_INVALID_TOKEN: DWORD = 315;
+pub const ERROR_MR_MID_NOT_FOUND: DWORD = 317;
+pub const ERROR_SCOPE_NOT_FOUND: DWORD = 318;
+pub const ERROR_INVALID_ADDRESS: DWORD = 487;
+pub const ERROR_ARITHMETIC_OVERFLOW: DWORD = 534;
+pub const ERROR_PIPE_CONNECTED: DWORD = 535;
+pub const ERROR_PIPE_LISTENING: DWORD = 536;
+pub const ERROR_WAKE_SYSTEM: DWORD = 730;
+pub const ERROR_WAIT_1: DWORD = 731;
+pub const ERROR_WAIT_2: DWORD = 732;
+pub const ERROR_WAIT_3: DWORD = 733;
+pub const ERROR_WAIT_63: DWORD = 734;
+pub const ERROR_ABANDONED_WAIT_0: DWORD = 735;
+pub const ERROR_ABANDONED_WAIT_63: DWORD = 736;
+pub const ERROR_USER_APC: DWORD = 737;
+pub const ERROR_KERNEL_APC: DWORD = 738;
+pub const ERROR_ALERTED: DWORD = 739;
+pub const ERROR_EA_ACCESS_DENIED: DWORD = 994;
+pub const ERROR_OPERATION_ABORTED: DWORD = 995;
+pub const ERROR_IO_INCOMPLETE: DWORD = 996;
+pub const ERROR_IO_PENDING: DWORD = 997;
+pub const ERROR_NOACCESS: DWORD = 998;
+pub const ERROR_SWAPERROR: DWORD = 999;
+pub const ERROR_STACK_OVERFLOW: DWORD = 1001;
+pub const ERROR_INVALID_MESSAGE: DWORD = 1002;
+pub const ERROR_CAN_NOT_COMPLETE: DWORD = 1003;
+pub const ERROR_INVALID_FLAGS: DWORD = 1004;
+pub const ERROR_UNRECOGNIZED_VOLUME: DWORD = 1005;
+pub const ERROR_FILE_INVALID: DWORD = 1006;
+pub const ERROR_FULLSCREEN_MODE: DWORD = 1007;
+pub const ERROR_NO_TOKEN: DWORD = 1008;
+pub const ERROR_BADDB: DWORD = 1009;
+pub const ERROR_BADKEY: DWORD = 1010;
+pub const ERROR_CANTOPEN: DWORD = 1011;
+pub const ERROR_CANTREAD: DWORD = 1012;
+pub const ERROR_CANTWRITE: DWORD = 1013;
+pub const ERROR_REGISTRY_RECOVERED: DWORD = 1014;
+pub const ERROR_REGISTRY_CORRUPT: DWORD = 1015;
+pub const ERROR_REGISTRY_IO_FAILED: DWORD = 1016;
+pub const ERROR_NOT_REGISTRY_FILE: DWORD = 1017;
+pub const ERROR_KEY_DELETED: DWORD = 1018;
+pub const ERROR_NO_LOG_SPACE: DWORD = 1019;
+pub const ERROR_KEY_HAS_CHILDREN: DWORD = 1020;
+pub const ERROR_CHILD_MUST_BE_VOLATILE: DWORD = 1021;
+pub const ERROR_NOTIFY_ENUM_DIR: DWORD = 1022;
+pub const ERROR_DEPENDENT_SERVICES_RUNNING: DWORD = 1051;
+pub const ERROR_INVALID_SERVICE_CONTROL: DWORD = 1052;
+pub const ERROR_SERVICE_REQUEST_TIMEOUT: DWORD = 1053;
+pub const ERROR_SERVICE_NO_THREAD: DWORD = 1054;
+pub const ERROR_SERVICE_DATABASE_LOCKED: DWORD = 1055;
+pub const ERROR_SERVICE_ALREADY_RUNNING: DWORD = 1056;
+pub const ERROR_INVALID_SERVICE_ACCOUNT: DWORD = 1057;
+pub const ERROR_SERVICE_DISABLED: DWORD = 1058;
+pub const ERROR_CIRCULAR_DEPENDENCY: DWORD = 1059;
+pub const ERROR_SERVICE_DOES_NOT_EXIST: DWORD = 1060;
+pub const ERROR_SERVICE_CANNOT_ACCEPT_CTRL: DWORD = 1061;
+pub const ERROR_SERVICE_NOT_ACTIVE: DWORD = 1062;
+pub const ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: DWORD = 1063;
+pub const ERROR_EXCEPTION_IN_SERVICE: DWORD = 1064;
+pub const ERROR_DATABASE_DOES_NOT_EXIST: DWORD = 1065;
+pub const ERROR_SERVICE_SPECIFIC_ERROR: DWORD = 1066;
+pub const ERROR_PROCESS_ABORTED: DWORD = 1067;
+pub const ERROR_SERVICE_DEPENDENCY_FAIL: DWORD = 1068;
+pub const ERROR_SERVICE_LOGON_FAILED: DWORD = 1069;
+pub const ERROR_SERVICE_START_HANG: DWORD = 1070;
+pub const ERROR_INVALID_SERVICE_LOCK: DWORD = 1071;
+pub const ERROR_SERVICE_MARKED_FOR_DELETE: DWORD = 1072;
+pub const ERROR_SERVICE_EXISTS: DWORD = 1073;
+pub const ERROR_ALREADY_RUNNING_LKG: DWORD = 1074;
+pub const ERROR_SERVICE_DEPENDENCY_DELETED: DWORD = 1075;
+pub const ERROR_BOOT_ALREADY_ACCEPTED: DWORD = 1076;
+pub const ERROR_SERVICE_NEVER_STARTED: DWORD = 1077;
+pub const ERROR_DUPLICATE_SERVICE_NAME: DWORD = 1078;
+pub const ERROR_DIFFERENT_SERVICE_ACCOUNT: DWORD = 1079;
+pub const ERROR_CANNOT_DETECT_DRIVER_FAILURE: DWORD = 1080;
+pub const ERROR_CANNOT_DETECT_PROCESS_ABORT: DWORD = 1081;
+pub const ERROR_NO_RECOVERY_PROGRAM: DWORD = 1082;
+pub const ERROR_SERVICE_NOT_IN_EXE: DWORD = 1083;
+pub const ERROR_NOT_SAFEBOOT_SERVICE: DWORD = 1084;
+pub const ERROR_END_OF_MEDIA: DWORD = 1100;
+pub const ERROR_FILEMARK_DETECTED: DWORD = 1101;
+pub const ERROR_BEGINNING_OF_MEDIA: DWORD = 1102;
+pub const ERROR_SETMARK_DETECTED: DWORD = 1103;
+pub const ERROR_NO_DATA_DETECTED: DWORD = 1104;
+pub const ERROR_PARTITION_FAILURE: DWORD = 1105;
+pub const ERROR_INVALID_BLOCK_LENGTH: DWORD = 1106;
+pub const ERROR_DEVICE_NOT_PARTITIONED: DWORD = 1107;
+pub const ERROR_UNABLE_TO_LOCK_MEDIA: DWORD = 1108;
+pub const ERROR_UNABLE_TO_UNLOAD_MEDIA: DWORD = 1109;
+pub const ERROR_MEDIA_CHANGED: DWORD = 1110;
+pub const ERROR_BUS_RESET: DWORD = 1111;
+pub const ERROR_NO_MEDIA_IN_DRIVE: DWORD = 1112;
+pub const ERROR_NO_UNICODE_TRANSLATION: DWORD = 1113;
+pub const ERROR_DLL_INIT_FAILED: DWORD = 1114;
+pub const ERROR_SHUTDOWN_IN_PROGRESS: DWORD = 1115;
+pub const ERROR_NO_SHUTDOWN_IN_PROGRESS: DWORD = 1116;
+pub const ERROR_IO_DEVICE: DWORD = 1117;
+pub const ERROR_SERIAL_NO_DEVICE: DWORD = 1118;
+pub const ERROR_IRQ_BUSY: DWORD = 1119;
+pub const ERROR_MORE_WRITES: DWORD = 1120;
+pub const ERROR_COUNTER_TIMEOUT: DWORD = 1121;
+pub const ERROR_FLOPPY_ID_MARK_NOT_FOUND: DWORD = 1122;
+pub const ERROR_FLOPPY_WRONG_CYLINDER: DWORD = 1123;
+pub const ERROR_FLOPPY_UNKNOWN_ERROR: DWORD = 1124;
+pub const ERROR_FLOPPY_BAD_REGISTERS: DWORD = 1125;
+pub const ERROR_DISK_RECALIBRATE_FAILED: DWORD = 1126;
+pub const ERROR_DISK_OPERATION_FAILED: DWORD = 1127;
+pub const ERROR_DISK_RESET_FAILED: DWORD = 1128;
+pub const ERROR_EOM_OVERFLOW: DWORD = 1129;
+pub const ERROR_NOT_ENOUGH_SERVER_MEMORY: DWORD = 1130;
+pub const ERROR_POSSIBLE_DEADLOCK: DWORD = 1131;
+pub const ERROR_MAPPED_ALIGNMENT: DWORD = 1132;
+pub const ERROR_SET_POWER_STATE_VETOED: DWORD = 1140;
+pub const ERROR_SET_POWER_STATE_FAILED: DWORD = 1141;
+pub const ERROR_TOO_MANY_LINKS: DWORD = 1142;
+pub const ERROR_OLD_WIN_VERSION: DWORD = 1150;
+pub const ERROR_APP_WRONG_OS: DWORD = 1151;
+pub const ERROR_SINGLE_INSTANCE_APP: DWORD = 1152;
+pub const ERROR_RMODE_APP: DWORD = 1153;
+pub const ERROR_INVALID_DLL: DWORD = 1154;
+pub const ERROR_NO_ASSOCIATION: DWORD = 1155;
+pub const ERROR_DDE_FAIL: DWORD = 1156;
+pub const ERROR_DLL_NOT_FOUND: DWORD = 1157;
+pub const ERROR_NO_MORE_USER_HANDLES: DWORD = 1158;
+pub const ERROR_MESSAGE_SYNC_ONLY: DWORD = 1159;
+pub const ERROR_SOURCE_ELEMENT_EMPTY: DWORD = 1160;
+pub const ERROR_DESTINATION_ELEMENT_FULL: DWORD = 1161;
+pub const ERROR_ILLEGAL_ELEMENT_ADDRESS: DWORD = 1162;
+pub const ERROR_MAGAZINE_NOT_PRESENT: DWORD = 1163;
+pub const ERROR_DEVICE_REINITIALIZATION_NEEDED: DWORD = 1164;
+pub const ERROR_DEVICE_REQUIRES_CLEANING: DWORD = 1165;
+pub const ERROR_DEVICE_DOOR_OPEN: DWORD = 1166;
+pub const ERROR_DEVICE_NOT_CONNECTED: DWORD = 1167;
+pub const ERROR_NOT_FOUND: DWORD = 1168;
+pub const ERROR_NO_MATCH: DWORD = 1169;
+pub const ERROR_SET_NOT_FOUND: DWORD = 1170;
+pub const ERROR_POINT_NOT_FOUND: DWORD = 1171;
+pub const ERROR_NO_TRACKING_SERVICE: DWORD = 1172;
+pub const ERROR_NO_VOLUME_ID: DWORD = 1173;
+pub const ERROR_UNABLE_TO_REMOVE_REPLACED: DWORD = 1175;
+pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT: DWORD = 1176;
+pub const ERROR_UNABLE_TO_MOVE_REPLACEMENT_2: DWORD = 1177;
+pub const ERROR_JOURNAL_DELETE_IN_PROGRESS: DWORD = 1178;
+pub const ERROR_JOURNAL_NOT_ACTIVE: DWORD = 1179;
+pub const ERROR_POTENTIAL_FILE_FOUND: DWORD = 1180;
+pub const ERROR_JOURNAL_ENTRY_DELETED: DWORD = 1181;
+pub const ERROR_BAD_DEVICE: DWORD = 1200;
+pub const ERROR_CONNECTION_UNAVAIL: DWORD = 1201;
+pub const ERROR_DEVICE_ALREADY_REMEMBERED: DWORD = 1202;
+pub const ERROR_NO_NET_OR_BAD_PATH: DWORD = 1203;
+pub const ERROR_BAD_PROVIDER: DWORD = 1204;
+pub const ERROR_CANNOT_OPEN_PROFILE: DWORD = 1205;
+pub const ERROR_BAD_PROFILE: DWORD = 1206;
+pub const ERROR_NOT_CONTAINER: DWORD = 1207;
+pub const ERROR_EXTENDED_ERROR: DWORD = 1208;
+pub const ERROR_INVALID_GROUPNAME: DWORD = 1209;
+pub const ERROR_INVALID_COMPUTERNAME: DWORD = 1210;
+pub const ERROR_INVALID_EVENTNAME: DWORD = 1211;
+pub const ERROR_INVALID_DOMAINNAME: DWORD = 1212;
+pub const ERROR_INVALID_SERVICENAME: DWORD = 1213;
+pub const ERROR_INVALID_NETNAME: DWORD = 1214;
+pub const ERROR_INVALID_SHARENAME: DWORD = 1215;
+pub const ERROR_INVALID_PASSWORDNAME: DWORD = 1216;
+pub const ERROR_INVALID_MESSAGENAME: DWORD = 1217;
+pub const ERROR_INVALID_MESSAGEDEST: DWORD = 1218;
+pub const ERROR_SESSION_CREDENTIAL_CONFLICT: DWORD = 1219;
+pub const ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: DWORD = 1220;
+pub const ERROR_DUP_DOMAINNAME: DWORD = 1221;
+pub const ERROR_NO_NETWORK: DWORD = 1222;
+pub const ERROR_CANCELLED: DWORD = 1223;
+pub const ERROR_USER_MAPPED_FILE: DWORD = 1224;
+pub const ERROR_CONNECTION_REFUSED: DWORD = 1225;
+pub const ERROR_GRACEFUL_DISCONNECT: DWORD = 1226;
+pub const ERROR_ADDRESS_ALREADY_ASSOCIATED: DWORD = 1227;
+pub const ERROR_ADDRESS_NOT_ASSOCIATED: DWORD = 1228;
+pub const ERROR_CONNECTION_INVALID: DWORD = 1229;
+pub const ERROR_CONNECTION_ACTIVE: DWORD = 1230;
+pub const ERROR_NETWORK_UNREACHABLE: DWORD = 1231;
+pub const ERROR_HOST_UNREACHABLE: DWORD = 1232;
+pub const ERROR_PROTOCOL_UNREACHABLE: DWORD = 1233;
+pub const ERROR_PORT_UNREACHABLE: DWORD = 1234;
+pub const ERROR_REQUEST_ABORTED: DWORD = 1235;
+pub const ERROR_CONNECTION_ABORTED: DWORD = 1236;
+pub const ERROR_RETRY: DWORD = 1237;
+pub const ERROR_CONNECTION_COUNT_LIMIT: DWORD = 1238;
+pub const ERROR_LOGIN_TIME_RESTRICTION: DWORD = 1239;
+pub const ERROR_LOGIN_WKSTA_RESTRICTION: DWORD = 1240;
+pub const ERROR_INCORRECT_ADDRESS: DWORD = 1241;
+pub const ERROR_ALREADY_REGISTERED: DWORD = 1242;
+pub const ERROR_SERVICE_NOT_FOUND: DWORD = 1243;
+pub const ERROR_NOT_AUTHENTICATED: DWORD = 1244;
+pub const ERROR_NOT_LOGGED_ON: DWORD = 1245;
+pub const ERROR_CONTINUE: DWORD = 1246;
+pub const ERROR_ALREADY_INITIALIZED: DWORD = 1247;
+pub const ERROR_NO_MORE_DEVICES: DWORD = 1248;
+pub const ERROR_NO_SUCH_SITE: DWORD = 1249;
+pub const ERROR_DOMAIN_CONTROLLER_EXISTS: DWORD = 1250;
+pub const ERROR_ONLY_IF_CONNECTED: DWORD = 1251;
+pub const ERROR_OVERRIDE_NOCHANGES: DWORD = 1252;
+pub const ERROR_BAD_USER_PROFILE: DWORD = 1253;
+pub const ERROR_NOT_SUPPORTED_ON_SBS: DWORD = 1254;
+pub const ERROR_SERVER_SHUTDOWN_IN_PROGRESS: DWORD = 1255;
+pub const ERROR_HOST_DOWN: DWORD = 1256;
+pub const ERROR_NON_ACCOUNT_SID: DWORD = 1257;
+pub const ERROR_NON_DOMAIN_SID: DWORD = 1258;
+pub const ERROR_APPHELP_BLOCK: DWORD = 1259;
+pub const ERROR_ACCESS_DISABLED_BY_POLICY: DWORD = 1260;
+pub const ERROR_REG_NAT_CONSUMPTION: DWORD = 1261;
+pub const ERROR_CSCSHARE_OFFLINE: DWORD = 1262;
+pub const ERROR_PKINIT_FAILURE: DWORD = 1263;
+pub const ERROR_SMARTCARD_SUBSYSTEM_FAILURE: DWORD = 1264;
+pub const ERROR_DOWNGRADE_DETECTED: DWORD = 1265;
+pub const ERROR_MACHINE_LOCKED: DWORD = 1271;
+pub const ERROR_CALLBACK_SUPPLIED_INVALID_DATA: DWORD = 1273;
+pub const ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED: DWORD = 1274;
+pub const ERROR_DRIVER_BLOCKED: DWORD = 1275;
+pub const ERROR_INVALID_IMPORT_OF_NON_DLL: DWORD = 1276;
+pub const ERROR_ACCESS_DISABLED_WEBBLADE: DWORD = 1277;
+pub const ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER: DWORD = 1278;
+pub const ERROR_RECOVERY_FAILURE: DWORD = 1279;
+pub const ERROR_ALREADY_FIBER: DWORD = 1280;
+pub const ERROR_ALREADY_THREAD: DWORD = 1281;
+pub const ERROR_STACK_BUFFER_OVERRUN: DWORD = 1282;
+pub const ERROR_PARAMETER_QUOTA_EXCEEDED: DWORD = 1283;
+pub const ERROR_DEBUGGER_INACTIVE: DWORD = 1284;
+pub const ERROR_DELAY_LOAD_FAILED: DWORD = 1285;
+pub const ERROR_VDM_DISALLOWED: DWORD = 1286;
+pub const ERROR_UNIDENTIFIED_ERROR: DWORD = 1287;
+pub const ERROR_NOT_ALL_ASSIGNED: DWORD = 1300;
+pub const ERROR_SOME_NOT_MAPPED: DWORD = 1301;
+pub const ERROR_NO_QUOTAS_FOR_ACCOUNT: DWORD = 1302;
+pub const ERROR_LOCAL_USER_SESSION_KEY: DWORD = 1303;
+pub const ERROR_NULL_LM_PASSWORD: DWORD = 1304;
+pub const ERROR_UNKNOWN_REVISION: DWORD = 1305;
+pub const ERROR_REVISION_MISMATCH: DWORD = 1306;
+pub const ERROR_INVALID_OWNER: DWORD = 1307;
+pub const ERROR_INVALID_PRIMARY_GROUP: DWORD = 1308;
+pub const ERROR_NO_IMPERSONATION_TOKEN: DWORD = 1309;
+pub const ERROR_CANT_DISABLE_MANDATORY: DWORD = 1310;
+pub const ERROR_NO_LOGON_SERVERS: DWORD = 1311;
+pub const ERROR_NO_SUCH_LOGON_SESSION: DWORD = 1312;
+pub const ERROR_NO_SUCH_PRIVILEGE: DWORD = 1313;
+pub const ERROR_PRIVILEGE_NOT_HELD: DWORD = 1314;
+pub const ERROR_INVALID_ACCOUNT_NAME: DWORD = 1315;
+pub const ERROR_USER_EXISTS: DWORD = 1316;
+pub const ERROR_NO_SUCH_USER: DWORD = 1317;
+pub const ERROR_GROUP_EXISTS: DWORD = 1318;
+pub const ERROR_NO_SUCH_GROUP: DWORD = 1319;
+pub const ERROR_MEMBER_IN_GROUP: DWORD = 1320;
+pub const ERROR_MEMBER_NOT_IN_GROUP: DWORD = 1321;
+pub const ERROR_LAST_ADMIN: DWORD = 1322;
+pub const ERROR_WRONG_PASSWORD: DWORD = 1323;
+pub const ERROR_ILL_FORMED_PASSWORD: DWORD = 1324;
+pub const ERROR_PASSWORD_RESTRICTION: DWORD = 1325;
+pub const ERROR_LOGON_FAILURE: DWORD = 1326;
+pub const ERROR_ACCOUNT_RESTRICTION: DWORD = 1327;
+pub const ERROR_INVALID_LOGON_HOURS: DWORD = 1328;
+pub const ERROR_INVALID_WORKSTATION: DWORD = 1329;
+pub const ERROR_PASSWORD_EXPIRED: DWORD = 1330;
+pub const ERROR_ACCOUNT_DISABLED: DWORD = 1331;
+pub const ERROR_NONE_MAPPED: DWORD = 1332;
+pub const ERROR_TOO_MANY_LUIDS_REQUESTED: DWORD = 1333;
+pub const ERROR_LUIDS_EXHAUSTED: DWORD = 1334;
+pub const ERROR_INVALID_SUB_AUTHORITY: DWORD = 1335;
+pub const ERROR_INVALID_ACL: DWORD = 1336;
+pub const ERROR_INVALID_SID: DWORD = 1337;
+pub const ERROR_INVALID_SECURITY_DESCR: DWORD = 1338;
+pub const ERROR_BAD_INHERITANCE_ACL: DWORD = 1340;
+pub const ERROR_SERVER_DISABLED: DWORD = 1341;
+pub const ERROR_SERVER_NOT_DISABLED: DWORD = 1342;
+pub const ERROR_INVALID_ID_AUTHORITY: DWORD = 1343;
+pub const ERROR_ALLOTTED_SPACE_EXCEEDED: DWORD = 1344;
+pub const ERROR_INVALID_GROUP_ATTRIBUTES: DWORD = 1345;
+pub const ERROR_BAD_IMPERSONATION_LEVEL: DWORD = 1346;
+pub const ERROR_CANT_OPEN_ANONYMOUS: DWORD = 1347;
+pub const ERROR_BAD_VALIDATION_CLASS: DWORD = 1348;
+pub const ERROR_BAD_TOKEN_TYPE: DWORD = 1349;
+pub const ERROR_NO_SECURITY_ON_OBJECT: DWORD = 1350;
+pub const ERROR_CANT_ACCESS_DOMAIN_INFO: DWORD = 1351;
+pub const ERROR_INVALID_SERVER_STATE: DWORD = 1352;
+pub const ERROR_INVALID_DOMAIN_STATE: DWORD = 1353;
+pub const ERROR_INVALID_DOMAIN_ROLE: DWORD = 1354;
+pub const ERROR_NO_SUCH_DOMAIN: DWORD = 1355;
+pub const ERROR_DOMAIN_EXISTS: DWORD = 1356;
+pub const ERROR_DOMAIN_LIMIT_EXCEEDED: DWORD = 1357;
+pub const ERROR_INTERNAL_DB_CORRUPTION: DWORD = 1358;
+pub const ERROR_INTERNAL_ERROR: DWORD = 1359;
+pub const ERROR_GENERIC_NOT_MAPPED: DWORD = 1360;
+pub const ERROR_BAD_DESCRIPTOR_FORMAT: DWORD = 1361;
+pub const ERROR_NOT_LOGON_PROCESS: DWORD = 1362;
+pub const ERROR_LOGON_SESSION_EXISTS: DWORD = 1363;
+pub const ERROR_NO_SUCH_PACKAGE: DWORD = 1364;
+pub const ERROR_BAD_LOGON_SESSION_STATE: DWORD = 1365;
+pub const ERROR_LOGON_SESSION_COLLISION: DWORD = 1366;
+pub const ERROR_INVALID_LOGON_TYPE: DWORD = 1367;
+pub const ERROR_CANNOT_IMPERSONATE: DWORD = 1368;
+pub const ERROR_RXACT_INVALID_STATE: DWORD = 1369;
+pub const ERROR_RXACT_COMMIT_FAILURE: DWORD = 1370;
+pub const ERROR_SPECIAL_ACCOUNT: DWORD = 1371;
+pub const ERROR_SPECIAL_GROUP: DWORD = 1372;
+pub const ERROR_SPECIAL_USER: DWORD = 1373;
+pub const ERROR_MEMBERS_PRIMARY_GROUP: DWORD = 1374;
+pub const ERROR_TOKEN_ALREADY_IN_USE: DWORD = 1375;
+pub const ERROR_NO_SUCH_ALIAS: DWORD = 1376;
+pub const ERROR_MEMBER_NOT_IN_ALIAS: DWORD = 1377;
+pub const ERROR_MEMBER_IN_ALIAS: DWORD = 1378;
+pub const ERROR_ALIAS_EXISTS: DWORD = 1379;
+pub const ERROR_LOGON_NOT_GRANTED: DWORD = 1380;
+pub const ERROR_TOO_MANY_SECRETS: DWORD = 1381;
+pub const ERROR_SECRET_TOO_LONG: DWORD = 1382;
+pub const ERROR_INTERNAL_DB_ERROR: DWORD = 1383;
+pub const ERROR_TOO_MANY_CONTEXT_IDS: DWORD = 1384;
+pub const ERROR_LOGON_TYPE_NOT_GRANTED: DWORD = 1385;
+pub const ERROR_NT_CROSS_ENCRYPTION_REQUIRED: DWORD = 1386;
+pub const ERROR_NO_SUCH_MEMBER: DWORD = 1387;
+pub const ERROR_INVALID_MEMBER: DWORD = 1388;
+pub const ERROR_TOO_MANY_SIDS: DWORD = 1389;
+pub const ERROR_LM_CROSS_ENCRYPTION_REQUIRED: DWORD = 1390;
+pub const ERROR_NO_INHERITANCE: DWORD = 1391;
+pub const ERROR_FILE_CORRUPT: DWORD = 1392;
+pub const ERROR_DISK_CORRUPT: DWORD = 1393;
+pub const ERROR_NO_USER_SESSION_KEY: DWORD = 1394;
+pub const ERROR_LICENSE_QUOTA_EXCEEDED: DWORD = 1395;
+pub const ERROR_WRONG_TARGET_NAME: DWORD = 1396;
+pub const ERROR_MUTUAL_AUTH_FAILED: DWORD = 1397;
+pub const ERROR_TIME_SKEW: DWORD = 1398;
+pub const ERROR_CURRENT_DOMAIN_NOT_ALLOWED: DWORD = 1399;
+pub const ERROR_INVALID_WINDOW_HANDLE: DWORD = 1400;
+pub const ERROR_INVALID_MENU_HANDLE: DWORD = 1401;
+pub const ERROR_INVALID_CURSOR_HANDLE: DWORD = 1402;
+pub const ERROR_INVALID_ACCEL_HANDLE: DWORD = 1403;
+pub const ERROR_INVALID_HOOK_HANDLE: DWORD = 1404;
+pub const ERROR_INVALID_DWP_HANDLE: DWORD = 1405;
+pub const ERROR_TLW_WITH_WSCHILD: DWORD = 1406;
+pub const ERROR_CANNOT_FIND_WND_CLASS: DWORD = 1407;
+pub const ERROR_WINDOW_OF_OTHER_THREAD: DWORD = 1408;
+pub const ERROR_HOTKEY_ALREADY_REGISTERED: DWORD = 1409;
+pub const ERROR_CLASS_ALREADY_EXISTS: DWORD = 1410;
+pub const ERROR_CLASS_DOES_NOT_EXIST: DWORD = 1411;
+pub const ERROR_CLASS_HAS_WINDOWS: DWORD = 1412;
+pub const ERROR_INVALID_INDEX: DWORD = 1413;
+pub const ERROR_INVALID_ICON_HANDLE: DWORD = 1414;
+pub const ERROR_PRIVATE_DIALOG_INDEX: DWORD = 1415;
+pub const ERROR_LISTBOX_ID_NOT_FOUND: DWORD = 1416;
+pub const ERROR_NO_WILDCARD_CHARACTERS: DWORD = 1417;
+pub const ERROR_CLIPBOARD_NOT_OPEN: DWORD = 1418;
+pub const ERROR_HOTKEY_NOT_REGISTERED: DWORD = 1419;
+pub const ERROR_WINDOW_NOT_DIALOG: DWORD = 1420;
+pub const ERROR_CONTROL_ID_NOT_FOUND: DWORD = 1421;
+pub const ERROR_INVALID_COMBOBOX_MESSAGE: DWORD = 1422;
+pub const ERROR_WINDOW_NOT_COMBOBOX: DWORD = 1423;
+pub const ERROR_INVALID_EDIT_HEIGHT: DWORD = 1424;
+pub const ERROR_DC_NOT_FOUND: DWORD = 1425;
+pub const ERROR_INVALID_HOOK_FILTER: DWORD = 1426;
+pub const ERROR_INVALID_FILTER_PROC: DWORD = 1427;
+pub const ERROR_HOOK_NEEDS_HMOD: DWORD = 1428;
+pub const ERROR_GLOBAL_ONLY_HOOK: DWORD = 1429;
+pub const ERROR_JOURNAL_HOOK_SET: DWORD = 1430;
+pub const ERROR_HOOK_NOT_INSTALLED: DWORD = 1431;
+pub const ERROR_INVALID_LB_MESSAGE: DWORD = 1432;
+pub const ERROR_SETCOUNT_ON_BAD_LB: DWORD = 1433;
+pub const ERROR_LB_WITHOUT_TABSTOPS: DWORD = 1434;
+pub const ERROR_DESTROY_OBJECT_OF_OTHER_THREAD: DWORD = 1435;
+pub const ERROR_CHILD_WINDOW_MENU: DWORD = 1436;
+pub const ERROR_NO_SYSTEM_MENU: DWORD = 1437;
+pub const ERROR_INVALID_MSGBOX_STYLE: DWORD = 1438;
+pub const ERROR_INVALID_SPI_VALUE: DWORD = 1439;
+pub const ERROR_SCREEN_ALREADY_LOCKED: DWORD = 1440;
+pub const ERROR_HWNDS_HAVE_DIFF_PARENT: DWORD = 1441;
+pub const ERROR_NOT_CHILD_WINDOW: DWORD = 1442;
+pub const ERROR_INVALID_GW_COMMAND: DWORD = 1443;
+pub const ERROR_INVALID_THREAD_ID: DWORD = 1444;
+pub const ERROR_NON_MDICHILD_WINDOW: DWORD = 1445;
+pub const ERROR_POPUP_ALREADY_ACTIVE: DWORD = 1446;
+pub const ERROR_NO_SCROLLBARS: DWORD = 1447;
+pub const ERROR_INVALID_SCROLLBAR_RANGE: DWORD = 1448;
+pub const ERROR_INVALID_SHOWWIN_COMMAND: DWORD = 1449;
+pub const ERROR_NO_SYSTEM_RESOURCES: DWORD = 1450;
+pub const ERROR_NONPAGED_SYSTEM_RESOURCES: DWORD = 1451;
+pub const ERROR_PAGED_SYSTEM_RESOURCES: DWORD = 1452;
+pub const ERROR_WORKING_SET_QUOTA: DWORD = 1453;
+pub const ERROR_PAGEFILE_QUOTA: DWORD = 1454;
+pub const ERROR_COMMITMENT_LIMIT: DWORD = 1455;
+pub const ERROR_MENU_ITEM_NOT_FOUND: DWORD = 1456;
+pub const ERROR_INVALID_KEYBOARD_HANDLE: DWORD = 1457;
+pub const ERROR_HOOK_TYPE_NOT_ALLOWED: DWORD = 1458;
+pub const ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION: DWORD = 1459;
+pub const ERROR_TIMEOUT: DWORD = 1460;
+pub const ERROR_INVALID_MONITOR_HANDLE: DWORD = 1461;
+pub const ERROR_INCORRECT_SIZE: DWORD = 1462;
+pub const ERROR_SYMLINK_CLASS_DISABLED: DWORD = 1463;
+pub const ERROR_SYMLINK_NOT_SUPPORTED: DWORD = 1464;
+pub const ERROR_XML_PARSE_ERROR: DWORD = 1465;
+pub const ERROR_XMLDSIG_ERROR: DWORD = 1466;
+pub const ERROR_RESTART_APPLICATION: DWORD = 1467;
+pub const ERROR_WRONG_COMPARTMENT: DWORD = 1468;
+pub const ERROR_AUTHIP_FAILURE: DWORD = 1469;
+pub const ERROR_NO_NVRAM_RESOURCES: DWORD = 1470;
+pub const ERROR_NOT_GUI_PROCESS: DWORD = 1471;
+pub const ERROR_EVENTLOG_FILE_CORRUPT: DWORD = 1500;
+pub const ERROR_EVENTLOG_CANT_START: DWORD = 1501;
+pub const ERROR_LOG_FILE_FULL: DWORD = 1502;
+pub const ERROR_EVENTLOG_FILE_CHANGED: DWORD = 1503;
+pub const ERROR_INSTALL_SERVICE_FAILURE: DWORD = 1601;
+pub const ERROR_INSTALL_USEREXIT: DWORD = 1602;
+pub const ERROR_INSTALL_FAILURE: DWORD = 1603;
+pub const ERROR_INSTALL_SUSPEND: DWORD = 1604;
+pub const ERROR_UNKNOWN_PRODUCT: DWORD = 1605;
+pub const ERROR_UNKNOWN_FEATURE: DWORD = 1606;
+pub const ERROR_UNKNOWN_COMPONENT: DWORD = 1607;
+pub const ERROR_UNKNOWN_PROPERTY: DWORD = 1608;
+pub const ERROR_INVALID_HANDLE_STATE: DWORD = 1609;
+pub const ERROR_BAD_CONFIGURATION: DWORD = 1610;
+pub const ERROR_INDEX_ABSENT: DWORD = 1611;
+pub const ERROR_INSTALL_SOURCE_ABSENT: DWORD = 1612;
+pub const ERROR_INSTALL_PACKAGE_VERSION: DWORD = 1613;
+pub const ERROR_PRODUCT_UNINSTALLED: DWORD = 1614;
+pub const ERROR_BAD_QUERY_SYNTAX: DWORD = 1615;
+pub const ERROR_INVALID_FIELD: DWORD = 1616;
+pub const ERROR_DEVICE_REMOVED: DWORD = 1617;
+pub const ERROR_INSTALL_ALREADY_RUNNING: DWORD = 1618;
+pub const ERROR_INSTALL_PACKAGE_OPEN_FAILED: DWORD = 1619;
+pub const ERROR_INSTALL_PACKAGE_INVALID: DWORD = 1620;
+pub const ERROR_INSTALL_UI_FAILURE: DWORD = 1621;
+pub const ERROR_INSTALL_LOG_FAILURE: DWORD = 1622;
+pub const ERROR_INSTALL_LANGUAGE_UNSUPPORTED: DWORD = 1623;
+pub const ERROR_INSTALL_TRANSFORM_FAILURE: DWORD = 1624;
+pub const ERROR_INSTALL_PACKAGE_REJECTED: DWORD = 1625;
+pub const ERROR_FUNCTION_NOT_CALLED: DWORD = 1626;
+pub const ERROR_FUNCTION_FAILED: DWORD = 1627;
+pub const ERROR_INVALID_TABLE: DWORD = 1628;
+pub const ERROR_DATATYPE_MISMATCH: DWORD = 1629;
+pub const ERROR_UNSUPPORTED_TYPE: DWORD = 1630;
+pub const ERROR_CREATE_FAILED: DWORD = 1631;
+pub const ERROR_INSTALL_TEMP_UNWRITABLE: DWORD = 1632;
+pub const ERROR_INSTALL_PLATFORM_UNSUPPORTED: DWORD = 1633;
+pub const ERROR_INSTALL_NOTUSED: DWORD = 1634;
+pub const ERROR_PATCH_PACKAGE_OPEN_FAILED: DWORD = 1635;
+pub const ERROR_PATCH_PACKAGE_INVALID: DWORD = 1636;
+pub const ERROR_PATCH_PACKAGE_UNSUPPORTED: DWORD = 1637;
+pub const ERROR_PRODUCT_VERSION: DWORD = 1638;
+pub const ERROR_INVALID_COMMAND_LINE: DWORD = 1639;
+pub const ERROR_INSTALL_REMOTE_DISALLOWED: DWORD = 1640;
+pub const ERROR_SUCCESS_REBOOT_INITIATED: DWORD = 1641;
+pub const ERROR_PATCH_TARGET_NOT_FOUND: DWORD = 1642;
+pub const ERROR_PATCH_PACKAGE_REJECTED: DWORD = 1643;
+pub const ERROR_INSTALL_TRANSFORM_REJECTED: DWORD = 1644;
+pub const ERROR_INSTALL_REMOTE_PROHIBITED: DWORD = 1645;
+pub const ERROR_INVALID_USER_BUFFER: DWORD = 1784;
+pub const ERROR_UNRECOGNIZED_MEDIA: DWORD = 1785;
+pub const ERROR_NO_TRUST_LSA_SECRET: DWORD = 1786;
+pub const ERROR_NO_TRUST_SAM_ACCOUNT: DWORD = 1787;
+pub const ERROR_TRUSTED_DOMAIN_FAILURE: DWORD = 1788;
+pub const ERROR_TRUSTED_RELATIONSHIP_FAILURE: DWORD = 1789;
+pub const ERROR_TRUST_FAILURE: DWORD = 1790;
+pub const ERROR_NETLOGON_NOT_STARTED: DWORD = 1792;
+pub const ERROR_ACCOUNT_EXPIRED: DWORD = 1793;
+pub const ERROR_REDIRECTOR_HAS_OPEN_HANDLES: DWORD = 1794;
+pub const ERROR_PRINTER_DRIVER_ALREADY_INSTALLED: DWORD = 1795;
+pub const ERROR_UNKNOWN_PORT: DWORD = 1796;
+pub const ERROR_UNKNOWN_PRINTER_DRIVER: DWORD = 1797;
+pub const ERROR_UNKNOWN_PRINTPROCESSOR: DWORD = 1798;
+pub const ERROR_INVALID_SEPARATOR_FILE: DWORD = 1799;
+pub const ERROR_INVALID_PRIORITY: DWORD = 1800;
+pub const ERROR_INVALID_PRINTER_NAME: DWORD = 1801;
+pub const ERROR_PRINTER_ALREADY_EXISTS: DWORD = 1802;
+pub const ERROR_INVALID_PRINTER_COMMAND: DWORD = 1803;
+pub const ERROR_INVALID_DATATYPE: DWORD = 1804;
+pub const ERROR_INVALID_ENVIRONMENT: DWORD = 1805;
+pub const ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT: DWORD = 1807;
+pub const ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT: DWORD = 1808;
+pub const ERROR_NOLOGON_SERVER_TRUST_ACCOUNT: DWORD = 1809;
+pub const ERROR_DOMAIN_TRUST_INCONSISTENT: DWORD = 1810;
+pub const ERROR_SERVER_HAS_OPEN_HANDLES: DWORD = 1811;
+pub const ERROR_RESOURCE_DATA_NOT_FOUND: DWORD = 1812;
+pub const ERROR_RESOURCE_TYPE_NOT_FOUND: DWORD = 1813;
+pub const ERROR_RESOURCE_NAME_NOT_FOUND: DWORD = 1814;
+pub const ERROR_RESOURCE_LANG_NOT_FOUND: DWORD = 1815;
+pub const ERROR_NOT_ENOUGH_QUOTA: DWORD = 1816;
+pub const ERROR_INVALID_TIME: DWORD = 1901;
+pub const ERROR_INVALID_FORM_NAME: DWORD = 1902;
+pub const ERROR_INVALID_FORM_SIZE: DWORD = 1903;
+pub const ERROR_ALREADY_WAITING: DWORD = 1904;
+pub const ERROR_PRINTER_DELETED: DWORD = 1905;
+pub const ERROR_INVALID_PRINTER_STATE: DWORD = 1906;
+pub const ERROR_PASSWORD_MUST_CHANGE: DWORD = 1907;
+pub const ERROR_DOMAIN_CONTROLLER_NOT_FOUND: DWORD = 1908;
+pub const ERROR_ACCOUNT_LOCKED_OUT: DWORD = 1909;
+pub const ERROR_NO_SITENAME: DWORD = 1919;
+pub const ERROR_CANT_ACCESS_FILE: DWORD = 1920;
+pub const ERROR_CANT_RESOLVE_FILENAME: DWORD = 1921;
+pub const ERROR_KM_DRIVER_BLOCKED: DWORD = 1930;
+pub const ERROR_CONTEXT_EXPIRED: DWORD = 1931;
+pub const ERROR_PER_USER_TRUST_QUOTA_EXCEEDED: DWORD = 1932;
+pub const ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED: DWORD = 1933;
+pub const ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED: DWORD = 1934;
+pub const ERROR_AUTHENTICATION_FIREWALL_FAILED: DWORD = 1935;
+pub const ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED: DWORD = 1936;
+pub const ERROR_INVALID_PIXEL_FORMAT: DWORD = 2000;
+pub const ERROR_BAD_DRIVER: DWORD = 2001;
+pub const ERROR_INVALID_WINDOW_STYLE: DWORD = 2002;
+pub const ERROR_METAFILE_NOT_SUPPORTED: DWORD = 2003;
+pub const ERROR_TRANSFORM_NOT_SUPPORTED: DWORD = 2004;
+pub const ERROR_CLIPPING_NOT_SUPPORTED: DWORD = 2005;
+pub const ERROR_INVALID_CMM: DWORD = 2010;
+pub const ERROR_INVALID_PROFILE: DWORD = 2011;
+pub const ERROR_TAG_NOT_FOUND: DWORD = 2012;
+pub const ERROR_TAG_NOT_PRESENT: DWORD = 2013;
+pub const ERROR_DUPLICATE_TAG: DWORD = 2014;
+pub const ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE: DWORD = 2015;
+pub const ERROR_PROFILE_NOT_FOUND: DWORD = 2016;
+pub const ERROR_INVALID_COLORSPACE: DWORD = 2017;
+pub const ERROR_ICM_NOT_ENABLED: DWORD = 2018;
+pub const ERROR_DELETING_ICM_XFORM: DWORD = 2019;
+pub const ERROR_INVALID_TRANSFORM: DWORD = 2020;
+pub const ERROR_COLORSPACE_MISMATCH: DWORD = 2021;
+pub const ERROR_INVALID_COLORINDEX: DWORD = 2022;
+pub const ERROR_CONNECTED_OTHER_PASSWORD: DWORD = 2108;
+pub const ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT: DWORD = 2109;
+pub const ERROR_BAD_USERNAME: DWORD = 2202;
+pub const ERROR_NOT_CONNECTED: DWORD = 2250;
+pub const ERROR_OPEN_FILES: DWORD = 2401;
+pub const ERROR_ACTIVE_CONNECTIONS: DWORD = 2402;
+pub const ERROR_DEVICE_IN_USE: DWORD = 2404;
+pub const ERROR_UNKNOWN_PRINT_MONITOR: DWORD = 3000;
+pub const ERROR_PRINTER_DRIVER_IN_USE: DWORD = 3001;
+pub const ERROR_SPOOL_FILE_NOT_FOUND: DWORD = 3002;
+pub const ERROR_SPL_NO_STARTDOC: DWORD = 3003;
+pub const ERROR_SPL_NO_ADDJOB: DWORD = 3004;
+pub const ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED: DWORD = 3005;
+pub const ERROR_PRINT_MONITOR_ALREADY_INSTALLED: DWORD = 3006;
+pub const ERROR_INVALID_PRINT_MONITOR: DWORD = 3007;
+pub const ERROR_PRINT_MONITOR_IN_USE: DWORD = 3008;
+pub const ERROR_PRINTER_HAS_JOBS_QUEUED: DWORD = 3009;
+pub const ERROR_SUCCESS_REBOOT_REQUIRED: DWORD = 3010;
+pub const ERROR_SUCCESS_RESTART_REQUIRED: DWORD = 3011;
+pub const ERROR_PRINTER_NOT_FOUND: DWORD = 3012;
+pub const ERROR_PRINTER_DRIVER_WARNED: DWORD = 3013;
+pub const ERROR_PRINTER_DRIVER_BLOCKED: DWORD = 3014;
+pub const ERROR_WINS_INTERNAL: DWORD = 4000;
+pub const ERROR_CAN_NOT_DEL_LOCAL_WINS: DWORD = 4001;
+pub const ERROR_STATIC_INIT: DWORD = 4002;
+pub const ERROR_INC_BACKUP: DWORD = 4003;
+pub const ERROR_FULL_BACKUP: DWORD = 4004;
+pub const ERROR_REC_NON_EXISTENT: DWORD = 4005;
+pub const ERROR_RPL_NOT_ALLOWED: DWORD = 4006;
+pub const ERROR_DHCP_ADDRESS_CONFLICT: DWORD = 4100;
+pub const ERROR_WMI_GUID_NOT_FOUND: DWORD = 4200;
+pub const ERROR_WMI_INSTANCE_NOT_FOUND: DWORD = 4201;
+pub const ERROR_WMI_ITEMID_NOT_FOUND: DWORD = 4202;
+pub const ERROR_WMI_TRY_AGAIN: DWORD = 4203;
+pub const ERROR_WMI_DP_NOT_FOUND: DWORD = 4204;
+pub const ERROR_WMI_UNRESOLVED_INSTANCE_REF: DWORD = 4205;
+pub const ERROR_WMI_ALREADY_ENABLED: DWORD = 4206;
+pub const ERROR_WMI_GUID_DISCONNECTED: DWORD = 4207;
+pub const ERROR_WMI_SERVER_UNAVAILABLE: DWORD = 4208;
+pub const ERROR_WMI_DP_FAILED: DWORD = 4209;
+pub const ERROR_WMI_INVALID_MOF: DWORD = 4210;
+pub const ERROR_WMI_INVALID_REGINFO: DWORD = 4211;
+pub const ERROR_WMI_ALREADY_DISABLED: DWORD = 4212;
+pub const ERROR_WMI_READ_ONLY: DWORD = 4213;
+pub const ERROR_WMI_SET_FAILURE: DWORD = 4214;
+pub const ERROR_INVALID_MEDIA: DWORD = 4300;
+pub const ERROR_INVALID_LIBRARY: DWORD = 4301;
+pub const ERROR_INVALID_MEDIA_POOL: DWORD = 4302;
+pub const ERROR_DRIVE_MEDIA_MISMATCH: DWORD = 4303;
+pub const ERROR_MEDIA_OFFLINE: DWORD = 4304;
+pub const ERROR_LIBRARY_OFFLINE: DWORD = 4305;
+pub const ERROR_EMPTY: DWORD = 4306;
+pub const ERROR_NOT_EMPTY: DWORD = 4307;
+pub const ERROR_MEDIA_UNAVAILABLE: DWORD = 4308;
+pub const ERROR_RESOURCE_DISABLED: DWORD = 4309;
+pub const ERROR_INVALID_CLEANER: DWORD = 4310;
+pub const ERROR_UNABLE_TO_CLEAN: DWORD = 4311;
+pub const ERROR_OBJECT_NOT_FOUND: DWORD = 4312;
+pub const ERROR_DATABASE_FAILURE: DWORD = 4313;
+pub const ERROR_DATABASE_FULL: DWORD = 4314;
+pub const ERROR_MEDIA_INCOMPATIBLE: DWORD = 4315;
+pub const ERROR_RESOURCE_NOT_PRESENT: DWORD = 4316;
+pub const ERROR_INVALID_OPERATION: DWORD = 4317;
+pub const ERROR_MEDIA_NOT_AVAILABLE: DWORD = 4318;
+pub const ERROR_DEVICE_NOT_AVAILABLE: DWORD = 4319;
+pub const ERROR_REQUEST_REFUSED: DWORD = 4320;
+pub const ERROR_INVALID_DRIVE_OBJECT: DWORD = 4321;
+pub const ERROR_LIBRARY_FULL: DWORD = 4322;
+pub const ERROR_MEDIUM_NOT_ACCESSIBLE: DWORD = 4323;
+pub const ERROR_UNABLE_TO_LOAD_MEDIUM: DWORD = 4324;
+pub const ERROR_UNABLE_TO_INVENTORY_DRIVE: DWORD = 4325;
+pub const ERROR_UNABLE_TO_INVENTORY_SLOT: DWORD = 4326;
+pub const ERROR_UNABLE_TO_INVENTORY_TRANSPORT: DWORD = 4327;
+pub const ERROR_TRANSPORT_FULL: DWORD = 4328;
+pub const ERROR_CONTROLLING_IEPORT: DWORD = 4329;
+pub const ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA: DWORD = 4330;
+pub const ERROR_CLEANER_SLOT_SET: DWORD = 4331;
+pub const ERROR_CLEANER_SLOT_NOT_SET: DWORD = 4332;
+pub const ERROR_CLEANER_CARTRIDGE_SPENT: DWORD = 4333;
+pub const ERROR_UNEXPECTED_OMID: DWORD = 4334;
+pub const ERROR_CANT_DELETE_LAST_ITEM: DWORD = 4335;
+pub const ERROR_MESSAGE_EXCEEDS_MAX_SIZE: DWORD = 4336;
+pub const ERROR_VOLUME_CONTAINS_SYS_FILES: DWORD = 4337;
+pub const ERROR_INDIGENOUS_TYPE: DWORD = 4338;
+pub const ERROR_NO_SUPPORTING_DRIVES: DWORD = 4339;
+pub const ERROR_CLEANER_CARTRIDGE_INSTALLED: DWORD = 4340;
+pub const ERROR_IEPORT_FULL: DWORD = 4341;
+pub const ERROR_FILE_OFFLINE: DWORD = 4350;
+pub const ERROR_REMOTE_STORAGE_NOT_ACTIVE: DWORD = 4351;
+pub const ERROR_REMOTE_STORAGE_MEDIA_ERROR: DWORD = 4352;
+pub const ERROR_NOT_A_REPARSE_POINT: DWORD = 4390;
+pub const ERROR_REPARSE_ATTRIBUTE_CONFLICT: DWORD = 4391;
+pub const ERROR_INVALID_REPARSE_DATA: DWORD = 4392;
+pub const ERROR_REPARSE_TAG_INVALID: DWORD = 4393;
+pub const ERROR_REPARSE_TAG_MISMATCH: DWORD = 4394;
+pub const ERROR_VOLUME_NOT_SIS_ENABLED: DWORD = 4500;
+pub const ERROR_DEPENDENT_RESOURCE_EXISTS: DWORD = 5001;
+pub const ERROR_DEPENDENCY_NOT_FOUND: DWORD = 5002;
+pub const ERROR_DEPENDENCY_ALREADY_EXISTS: DWORD = 5003;
+pub const ERROR_RESOURCE_NOT_ONLINE: DWORD = 5004;
+pub const ERROR_HOST_NODE_NOT_AVAILABLE: DWORD = 5005;
+pub const ERROR_RESOURCE_NOT_AVAILABLE: DWORD = 5006;
+pub const ERROR_RESOURCE_NOT_FOUND: DWORD = 5007;
+pub const ERROR_SHUTDOWN_CLUSTER: DWORD = 5008;
+pub const ERROR_CANT_EVICT_ACTIVE_NODE: DWORD = 5009;
+pub const ERROR_OBJECT_ALREADY_EXISTS: DWORD = 5010;
+pub const ERROR_OBJECT_IN_LIST: DWORD = 5011;
+pub const ERROR_GROUP_NOT_AVAILABLE: DWORD = 5012;
+pub const ERROR_GROUP_NOT_FOUND: DWORD = 5013;
+pub const ERROR_GROUP_NOT_ONLINE: DWORD = 5014;
+pub const ERROR_HOST_NODE_NOT_RESOURCE_OWNER: DWORD = 5015;
+pub const ERROR_HOST_NODE_NOT_GROUP_OWNER: DWORD = 5016;
+pub const ERROR_RESMON_CREATE_FAILED: DWORD = 5017;
+pub const ERROR_RESMON_ONLINE_FAILED: DWORD = 5018;
+pub const ERROR_RESOURCE_ONLINE: DWORD = 5019;
+pub const ERROR_QUORUM_RESOURCE: DWORD = 5020;
+pub const ERROR_NOT_QUORUM_CAPABLE: DWORD = 5021;
+pub const ERROR_CLUSTER_SHUTTING_DOWN: DWORD = 5022;
+pub const ERROR_INVALID_STATE: DWORD = 5023;
+pub const ERROR_RESOURCE_PROPERTIES_STORED: DWORD = 5024;
+pub const ERROR_NOT_QUORUM_CLASS: DWORD = 5025;
+pub const ERROR_CORE_RESOURCE: DWORD = 5026;
+pub const ERROR_QUORUM_RESOURCE_ONLINE_FAILED: DWORD = 5027;
+pub const ERROR_QUORUMLOG_OPEN_FAILED: DWORD = 5028;
+pub const ERROR_CLUSTERLOG_CORRUPT: DWORD = 5029;
+pub const ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE: DWORD = 5030;
+pub const ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE: DWORD = 5031;
+pub const ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND: DWORD = 5032;
+pub const ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE: DWORD = 5033;
+pub const ERROR_QUORUM_OWNER_ALIVE: DWORD = 5034;
+pub const ERROR_NETWORK_NOT_AVAILABLE: DWORD = 5035;
+pub const ERROR_NODE_NOT_AVAILABLE: DWORD = 5036;
+pub const ERROR_ALL_NODES_NOT_AVAILABLE: DWORD = 5037;
+pub const ERROR_RESOURCE_FAILED: DWORD = 5038;
+pub const ERROR_CLUSTER_INVALID_NODE: DWORD = 5039;
+pub const ERROR_CLUSTER_NODE_EXISTS: DWORD = 5040;
+pub const ERROR_CLUSTER_JOIN_IN_PROGRESS: DWORD = 5041;
+pub const ERROR_CLUSTER_NODE_NOT_FOUND: DWORD = 5042;
+pub const ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND: DWORD = 5043;
+pub const ERROR_CLUSTER_NETWORK_EXISTS: DWORD = 5044;
+pub const ERROR_CLUSTER_NETWORK_NOT_FOUND: DWORD = 5045;
+pub const ERROR_CLUSTER_NETINTERFACE_EXISTS: DWORD = 5046;
+pub const ERROR_CLUSTER_NETINTERFACE_NOT_FOUND: DWORD = 5047;
+pub const ERROR_CLUSTER_INVALID_REQUEST: DWORD = 5048;
+pub const ERROR_CLUSTER_INVALID_NETWORK_PROVIDER: DWORD = 5049;
+pub const ERROR_CLUSTER_NODE_DOWN: DWORD = 5050;
+pub const ERROR_CLUSTER_NODE_UNREACHABLE: DWORD = 5051;
+pub const ERROR_CLUSTER_NODE_NOT_MEMBER: DWORD = 5052;
+pub const ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS: DWORD = 5053;
+pub const ERROR_CLUSTER_INVALID_NETWORK: DWORD = 5054;
+pub const ERROR_CLUSTER_NODE_UP: DWORD = 5056;
+pub const ERROR_CLUSTER_IPADDR_IN_USE: DWORD = 5057;
+pub const ERROR_CLUSTER_NODE_NOT_PAUSED: DWORD = 5058;
+pub const ERROR_CLUSTER_NO_SECURITY_CONTEXT: DWORD = 5059;
+pub const ERROR_CLUSTER_NETWORK_NOT_INTERNAL: DWORD = 5060;
+pub const ERROR_CLUSTER_NODE_ALREADY_UP: DWORD = 5061;
+pub const ERROR_CLUSTER_NODE_ALREADY_DOWN: DWORD = 5062;
+pub const ERROR_CLUSTER_NETWORK_ALREADY_ONLINE: DWORD = 5063;
+pub const ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE: DWORD = 5064;
+pub const ERROR_CLUSTER_NODE_ALREADY_MEMBER: DWORD = 5065;
+pub const ERROR_CLUSTER_LAST_INTERNAL_NETWORK: DWORD = 5066;
+pub const ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS: DWORD = 5067;
+pub const ERROR_INVALID_OPERATION_ON_QUORUM: DWORD = 5068;
+pub const ERROR_DEPENDENCY_NOT_ALLOWED: DWORD = 5069;
+pub const ERROR_CLUSTER_NODE_PAUSED: DWORD = 5070;
+pub const ERROR_NODE_CANT_HOST_RESOURCE: DWORD = 5071;
+pub const ERROR_CLUSTER_NODE_NOT_READY: DWORD = 5072;
+pub const ERROR_CLUSTER_NODE_SHUTTING_DOWN: DWORD = 5073;
+pub const ERROR_CLUSTER_JOIN_ABORTED: DWORD = 5074;
+pub const ERROR_CLUSTER_INCOMPATIBLE_VERSIONS: DWORD = 5075;
+pub const ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED: DWORD = 5076;
+pub const ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED: DWORD = 5077;
+pub const ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND: DWORD = 5078;
+pub const ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED: DWORD = 5079;
+pub const ERROR_CLUSTER_RESNAME_NOT_FOUND: DWORD = 5080;
+pub const ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED: DWORD = 5081;
+pub const ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST: DWORD = 5082;
+pub const ERROR_CLUSTER_DATABASE_SEQMISMATCH: DWORD = 5083;
+pub const ERROR_RESMON_INVALID_STATE: DWORD = 5084;
+pub const ERROR_CLUSTER_GUM_NOT_LOCKER: DWORD = 5085;
+pub const ERROR_QUORUM_DISK_NOT_FOUND: DWORD = 5086;
+pub const ERROR_DATABASE_BACKUP_CORRUPT: DWORD = 5087;
+pub const ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT: DWORD = 5088;
+pub const ERROR_RESOURCE_PROPERTY_UNCHANGEABLE: DWORD = 5089;
+pub const ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE: DWORD = 5890;
+pub const ERROR_CLUSTER_QUORUMLOG_NOT_FOUND: DWORD = 5891;
+pub const ERROR_CLUSTER_MEMBERSHIP_HALT: DWORD = 5892;
+pub const ERROR_CLUSTER_INSTANCE_ID_MISMATCH: DWORD = 5893;
+pub const ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP: DWORD = 5894;
+pub const ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH: DWORD = 5895;
+pub const ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP: DWORD = 5896;
+pub const ERROR_CLUSTER_PARAMETER_MISMATCH: DWORD = 5897;
+pub const ERROR_NODE_CANNOT_BE_CLUSTERED: DWORD = 5898;
+pub const ERROR_CLUSTER_WRONG_OS_VERSION: DWORD = 5899;
+pub const ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME: DWORD = 5900;
+pub const ERROR_CLUSCFG_ALREADY_COMMITTED: DWORD = 5901;
+pub const ERROR_CLUSCFG_ROLLBACK_FAILED: DWORD = 5902;
+pub const ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT: DWORD = 5903;
+pub const ERROR_CLUSTER_OLD_VERSION: DWORD = 5904;
+pub const ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME: DWORD = 5905;
+pub const ERROR_ENCRYPTION_FAILED: DWORD = 6000;
+pub const ERROR_DECRYPTION_FAILED: DWORD = 6001;
+pub const ERROR_FILE_ENCRYPTED: DWORD = 6002;
+pub const ERROR_NO_RECOVERY_POLICY: DWORD = 6003;
+pub const ERROR_NO_EFS: DWORD = 6004;
+pub const ERROR_WRONG_EFS: DWORD = 6005;
+pub const ERROR_NO_USER_KEYS: DWORD = 6006;
+pub const ERROR_FILE_NOT_ENCRYPTED: DWORD = 6007;
+pub const ERROR_NOT_EXPORT_FORMAT: DWORD = 6008;
+pub const ERROR_FILE_READ_ONLY: DWORD = 6009;
+pub const ERROR_DIR_EFS_DISALLOWED: DWORD = 6010;
+pub const ERROR_EFS_SERVER_NOT_TRUSTED: DWORD = 6011;
+pub const ERROR_BAD_RECOVERY_POLICY: DWORD = 6012;
+pub const ERROR_EFS_ALG_BLOB_TOO_BIG: DWORD = 6013;
+pub const ERROR_VOLUME_NOT_SUPPORT_EFS: DWORD = 6014;
+pub const ERROR_EFS_DISABLED: DWORD = 6015;
+pub const ERROR_EFS_VERSION_NOT_SUPPORT: DWORD = 6016;
+pub const ERROR_NO_BROWSER_SERVERS_FOUND: DWORD = 6118;
+pub const ERROR_CTX_WINSTATION_NAME_INVALID: DWORD = 7001;
+pub const ERROR_CTX_INVALID_PD: DWORD = 7002;
+pub const ERROR_CTX_PD_NOT_FOUND: DWORD = 7003;
+pub const ERROR_CTX_WD_NOT_FOUND: DWORD = 7004;
+pub const ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY: DWORD = 7005;
+pub const ERROR_CTX_SERVICE_NAME_COLLISION: DWORD = 7006;
+pub const ERROR_CTX_CLOSE_PENDING: DWORD = 7007;
+pub const ERROR_CTX_NO_OUTBUF: DWORD = 7008;
+pub const ERROR_CTX_MODEM_INF_NOT_FOUND: DWORD = 7009;
+pub const ERROR_CTX_INVALID_MODEMNAME: DWORD = 7010;
+pub const ERROR_CTX_MODEM_RESPONSE_ERROR: DWORD = 7011;
+pub const ERROR_CTX_MODEM_RESPONSE_TIMEOUT: DWORD = 7012;
+pub const ERROR_CTX_MODEM_RESPONSE_NO_CARRIER: DWORD = 7013;
+pub const ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE: DWORD = 7014;
+pub const ERROR_CTX_MODEM_RESPONSE_BUSY: DWORD = 7015;
+pub const ERROR_CTX_MODEM_RESPONSE_VOICE: DWORD = 7016;
+pub const ERROR_CTX_TD_ERROR: DWORD = 7017;
+pub const ERROR_CTX_WINSTATION_NOT_FOUND: DWORD = 7022;
+pub const ERROR_CTX_WINSTATION_ALREADY_EXISTS: DWORD = 7023;
+pub const ERROR_CTX_WINSTATION_BUSY: DWORD = 7024;
+pub const ERROR_CTX_BAD_VIDEO_MODE: DWORD = 7025;
+pub const ERROR_CTX_GRAPHICS_INVALID: DWORD = 7035;
+pub const ERROR_CTX_LOGON_DISABLED: DWORD = 7037;
+pub const ERROR_CTX_NOT_CONSOLE: DWORD = 7038;
+pub const ERROR_CTX_CLIENT_QUERY_TIMEOUT: DWORD = 7040;
+pub const ERROR_CTX_CONSOLE_DISCONNECT: DWORD = 7041;
+pub const ERROR_CTX_CONSOLE_CONNECT: DWORD = 7042;
+pub const ERROR_CTX_SHADOW_DENIED: DWORD = 7044;
+pub const ERROR_CTX_WINSTATION_ACCESS_DENIED: DWORD = 7045;
+pub const ERROR_CTX_INVALID_WD: DWORD = 7049;
+pub const ERROR_CTX_SHADOW_INVALID: DWORD = 7050;
+pub const ERROR_CTX_SHADOW_DISABLED: DWORD = 7051;
+pub const ERROR_CTX_CLIENT_LICENSE_IN_USE: DWORD = 7052;
+pub const ERROR_CTX_CLIENT_LICENSE_NOT_SET: DWORD = 7053;
+pub const ERROR_CTX_LICENSE_NOT_AVAILABLE: DWORD = 7054;
+pub const ERROR_CTX_LICENSE_CLIENT_INVALID: DWORD = 7055;
+pub const ERROR_CTX_LICENSE_EXPIRED: DWORD = 7056;
+pub const ERROR_CTX_SHADOW_NOT_RUNNING: DWORD = 7057;
+pub const ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE: DWORD = 7058;
+pub const ERROR_ACTIVATION_COUNT_EXCEEDED: DWORD = 7059;
+pub const ERROR_DS_NOT_INSTALLED: DWORD = 8200;
+pub const ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY: DWORD = 8201;
+pub const ERROR_DS_NO_ATTRIBUTE_OR_VALUE: DWORD = 8202;
+pub const ERROR_DS_INVALID_ATTRIBUTE_SYNTAX: DWORD = 8203;
+pub const ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED: DWORD = 8204;
+pub const ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS: DWORD = 8205;
+pub const ERROR_DS_BUSY: DWORD = 8206;
+pub const ERROR_DS_UNAVAILABLE: DWORD = 8207;
+pub const ERROR_DS_NO_RIDS_ALLOCATED: DWORD = 8208;
+pub const ERROR_DS_NO_MORE_RIDS: DWORD = 8209;
+pub const ERROR_DS_INCORRECT_ROLE_OWNER: DWORD = 8210;
+pub const ERROR_DS_RIDMGR_INIT_ERROR: DWORD = 8211;
+pub const ERROR_DS_OBJ_CLASS_VIOLATION: DWORD = 8212;
+pub const ERROR_DS_CANT_ON_NON_LEAF: DWORD = 8213;
+pub const ERROR_DS_CANT_ON_RDN: DWORD = 8214;
+pub const ERROR_DS_CANT_MOD_OBJ_CLASS: DWORD = 8215;
+pub const ERROR_DS_CROSS_DOM_MOVE_ERROR: DWORD = 8216;
+pub const ERROR_DS_GC_NOT_AVAILABLE: DWORD = 8217;
+pub const ERROR_SHARED_POLICY: DWORD = 8218;
+pub const ERROR_POLICY_OBJECT_NOT_FOUND: DWORD = 8219;
+pub const ERROR_POLICY_ONLY_IN_DS: DWORD = 8220;
+pub const ERROR_PROMOTION_ACTIVE: DWORD = 8221;
+pub const ERROR_NO_PROMOTION_ACTIVE: DWORD = 8222;
+pub const ERROR_DS_OPERATIONS_ERROR: DWORD = 8224;
+pub const ERROR_DS_PROTOCOL_ERROR: DWORD = 8225;
+pub const ERROR_DS_TIMELIMIT_EXCEEDED: DWORD = 8226;
+pub const ERROR_DS_SIZELIMIT_EXCEEDED: DWORD = 8227;
+pub const ERROR_DS_ADMIN_LIMIT_EXCEEDED: DWORD = 8228;
+pub const ERROR_DS_COMPARE_FALSE: DWORD = 8229;
+pub const ERROR_DS_COMPARE_TRUE: DWORD = 8230;
+pub const ERROR_DS_AUTH_METHOD_NOT_SUPPORTED: DWORD = 8231;
+pub const ERROR_DS_STRONG_AUTH_REQUIRED: DWORD = 8232;
+pub const ERROR_DS_INAPPROPRIATE_AUTH: DWORD = 8233;
+pub const ERROR_DS_AUTH_UNKNOWN: DWORD = 8234;
+pub const ERROR_DS_REFERRAL: DWORD = 8235;
+pub const ERROR_DS_UNAVAILABLE_CRIT_EXTENSION: DWORD = 8236;
+pub const ERROR_DS_CONFIDENTIALITY_REQUIRED: DWORD = 8237;
+pub const ERROR_DS_INAPPROPRIATE_MATCHING: DWORD = 8238;
+pub const ERROR_DS_CONSTRAINT_VIOLATION: DWORD = 8239;
+pub const ERROR_DS_NO_SUCH_OBJECT: DWORD = 8240;
+pub const ERROR_DS_ALIAS_PROBLEM: DWORD = 8241;
+pub const ERROR_DS_INVALID_DN_SYNTAX: DWORD = 8242;
+pub const ERROR_DS_IS_LEAF: DWORD = 8243;
+pub const ERROR_DS_ALIAS_DEREF_PROBLEM: DWORD = 8244;
+pub const ERROR_DS_UNWILLING_TO_PERFORM: DWORD = 8245;
+pub const ERROR_DS_LOOP_DETECT: DWORD = 8246;
+pub const ERROR_DS_NAMING_VIOLATION: DWORD = 8247;
+pub const ERROR_DS_OBJECT_RESULTS_TOO_LARGE: DWORD = 8248;
+pub const ERROR_DS_AFFECTS_MULTIPLE_DSAS: DWORD = 8249;
+pub const ERROR_DS_SERVER_DOWN: DWORD = 8250;
+pub const ERROR_DS_LOCAL_ERROR: DWORD = 8251;
+pub const ERROR_DS_ENCODING_ERROR: DWORD = 8252;
+pub const ERROR_DS_DECODING_ERROR: DWORD = 8253;
+pub const ERROR_DS_FILTER_UNKNOWN: DWORD = 8254;
+pub const ERROR_DS_PARAM_ERROR: DWORD = 8255;
+pub const ERROR_DS_NOT_SUPPORTED: DWORD = 8256;
+pub const ERROR_DS_NO_RESULTS_RETURNED: DWORD = 8257;
+pub const ERROR_DS_CONTROL_NOT_FOUND: DWORD = 8258;
+pub const ERROR_DS_CLIENT_LOOP: DWORD = 8259;
+pub const ERROR_DS_REFERRAL_LIMIT_EXCEEDED: DWORD = 8260;
+pub const ERROR_DS_SORT_CONTROL_MISSING: DWORD = 8261;
+pub const ERROR_DS_OFFSET_RANGE_ERROR: DWORD = 8262;
+pub const ERROR_DS_ROOT_MUST_BE_NC: DWORD = 8301;
+pub const ERROR_DS_ADD_REPLICA_INHIBITED: DWORD = 8302;
+pub const ERROR_DS_ATT_NOT_DEF_IN_SCHEMA: DWORD = 8303;
+pub const ERROR_DS_MAX_OBJ_SIZE_EXCEEDED: DWORD = 8304;
+pub const ERROR_DS_OBJ_STRING_NAME_EXISTS: DWORD = 8305;
+pub const ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA: DWORD = 8306;
+pub const ERROR_DS_RDN_DOESNT_MATCH_SCHEMA: DWORD = 8307;
+pub const ERROR_DS_NO_REQUESTED_ATTS_FOUND: DWORD = 8308;
+pub const ERROR_DS_USER_BUFFER_TO_SMALL: DWORD = 8309;
+pub const ERROR_DS_ATT_IS_NOT_ON_OBJ: DWORD = 8310;
+pub const ERROR_DS_ILLEGAL_MOD_OPERATION: DWORD = 8311;
+pub const ERROR_DS_OBJ_TOO_LARGE: DWORD = 8312;
+pub const ERROR_DS_BAD_INSTANCE_TYPE: DWORD = 8313;
+pub const ERROR_DS_MASTERDSA_REQUIRED: DWORD = 8314;
+pub const ERROR_DS_OBJECT_CLASS_REQUIRED: DWORD = 8315;
+pub const ERROR_DS_MISSING_REQUIRED_ATT: DWORD = 8316;
+pub const ERROR_DS_ATT_NOT_DEF_FOR_CLASS: DWORD = 8317;
+pub const ERROR_DS_ATT_ALREADY_EXISTS: DWORD = 8318;
+pub const ERROR_DS_CANT_ADD_ATT_VALUES: DWORD = 8320;
+pub const ERROR_DS_SINGLE_VALUE_CONSTRAINT: DWORD = 8321;
+pub const ERROR_DS_RANGE_CONSTRAINT: DWORD = 8322;
+pub const ERROR_DS_ATT_VAL_ALREADY_EXISTS: DWORD = 8323;
+pub const ERROR_DS_CANT_REM_MISSING_ATT: DWORD = 8324;
+pub const ERROR_DS_CANT_REM_MISSING_ATT_VAL: DWORD = 8325;
+pub const ERROR_DS_ROOT_CANT_BE_SUBREF: DWORD = 8326;
+pub const ERROR_DS_NO_CHAINING: DWORD = 8327;
+pub const ERROR_DS_NO_CHAINED_EVAL: DWORD = 8328;
+pub const ERROR_DS_NO_PARENT_OBJECT: DWORD = 8329;
+pub const ERROR_DS_PARENT_IS_AN_ALIAS: DWORD = 8330;
+pub const ERROR_DS_CANT_MIX_MASTER_AND_REPS: DWORD = 8331;
+pub const ERROR_DS_CHILDREN_EXIST: DWORD = 8332;
+pub const ERROR_DS_OBJ_NOT_FOUND: DWORD = 8333;
+pub const ERROR_DS_ALIASED_OBJ_MISSING: DWORD = 8334;
+pub const ERROR_DS_BAD_NAME_SYNTAX: DWORD = 8335;
+pub const ERROR_DS_ALIAS_POINTS_TO_ALIAS: DWORD = 8336;
+pub const ERROR_DS_CANT_DEREF_ALIAS: DWORD = 8337;
+pub const ERROR_DS_OUT_OF_SCOPE: DWORD = 8338;
+pub const ERROR_DS_OBJECT_BEING_REMOVED: DWORD = 8339;
+pub const ERROR_DS_CANT_DELETE_DSA_OBJ: DWORD = 8340;
+pub const ERROR_DS_GENERIC_ERROR: DWORD = 8341;
+pub const ERROR_DS_DSA_MUST_BE_INT_MASTER: DWORD = 8342;
+pub const ERROR_DS_CLASS_NOT_DSA: DWORD = 8343;
+pub const ERROR_DS_INSUFF_ACCESS_RIGHTS: DWORD = 8344;
+pub const ERROR_DS_ILLEGAL_SUPERIOR: DWORD = 8345;
+pub const ERROR_DS_ATTRIBUTE_OWNED_BY_SAM: DWORD = 8346;
+pub const ERROR_DS_NAME_TOO_MANY_PARTS: DWORD = 8347;
+pub const ERROR_DS_NAME_TOO_LONG: DWORD = 8348;
+pub const ERROR_DS_NAME_VALUE_TOO_LONG: DWORD = 8349;
+pub const ERROR_DS_NAME_UNPARSEABLE: DWORD = 8350;
+pub const ERROR_DS_NAME_TYPE_UNKNOWN: DWORD = 8351;
+pub const ERROR_DS_NOT_AN_OBJECT: DWORD = 8352;
+pub const ERROR_DS_SEC_DESC_TOO_SHORT: DWORD = 8353;
+pub const ERROR_DS_SEC_DESC_INVALID: DWORD = 8354;
+pub const ERROR_DS_NO_DELETED_NAME: DWORD = 8355;
+pub const ERROR_DS_SUBREF_MUST_HAVE_PARENT: DWORD = 8356;
+pub const ERROR_DS_NCNAME_MUST_BE_NC: DWORD = 8357;
+pub const ERROR_DS_CANT_ADD_SYSTEM_ONLY: DWORD = 8358;
+pub const ERROR_DS_CLASS_MUST_BE_CONCRETE: DWORD = 8359;
+pub const ERROR_DS_INVALID_DMD: DWORD = 8360;
+pub const ERROR_DS_OBJ_GUID_EXISTS: DWORD = 8361;
+pub const ERROR_DS_NOT_ON_BACKLINK: DWORD = 8362;
+pub const ERROR_DS_NO_CROSSREF_FOR_NC: DWORD = 8363;
+pub const ERROR_DS_SHUTTING_DOWN: DWORD = 8364;
+pub const ERROR_DS_UNKNOWN_OPERATION: DWORD = 8365;
+pub const ERROR_DS_INVALID_ROLE_OWNER: DWORD = 8366;
+pub const ERROR_DS_COULDNT_CONTACT_FSMO: DWORD = 8367;
+pub const ERROR_DS_CROSS_NC_DN_RENAME: DWORD = 8368;
+pub const ERROR_DS_CANT_MOD_SYSTEM_ONLY: DWORD = 8369;
+pub const ERROR_DS_REPLICATOR_ONLY: DWORD = 8370;
+pub const ERROR_DS_OBJ_CLASS_NOT_DEFINED: DWORD = 8371;
+pub const ERROR_DS_OBJ_CLASS_NOT_SUBCLASS: DWORD = 8372;
+pub const ERROR_DS_NAME_REFERENCE_INVALID: DWORD = 8373;
+pub const ERROR_DS_CROSS_REF_EXISTS: DWORD = 8374;
+pub const ERROR_DS_CANT_DEL_MASTER_CROSSREF: DWORD = 8375;
+pub const ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD: DWORD = 8376;
+pub const ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX: DWORD = 8377;
+pub const ERROR_DS_DUP_RDN: DWORD = 8378;
+pub const ERROR_DS_DUP_OID: DWORD = 8379;
+pub const ERROR_DS_DUP_MAPI_ID: DWORD = 8380;
+pub const ERROR_DS_DUP_SCHEMA_ID_GUID: DWORD = 8381;
+pub const ERROR_DS_DUP_LDAP_DISPLAY_NAME: DWORD = 8382;
+pub const ERROR_DS_SEMANTIC_ATT_TEST: DWORD = 8383;
+pub const ERROR_DS_SYNTAX_MISMATCH: DWORD = 8384;
+pub const ERROR_DS_EXISTS_IN_MUST_HAVE: DWORD = 8385;
+pub const ERROR_DS_EXISTS_IN_MAY_HAVE: DWORD = 8386;
+pub const ERROR_DS_NONEXISTENT_MAY_HAVE: DWORD = 8387;
+pub const ERROR_DS_NONEXISTENT_MUST_HAVE: DWORD = 8388;
+pub const ERROR_DS_AUX_CLS_TEST_FAIL: DWORD = 8389;
+pub const ERROR_DS_NONEXISTENT_POSS_SUP: DWORD = 8390;
+pub const ERROR_DS_SUB_CLS_TEST_FAIL: DWORD = 8391;
+pub const ERROR_DS_BAD_RDN_ATT_ID_SYNTAX: DWORD = 8392;
+pub const ERROR_DS_EXISTS_IN_AUX_CLS: DWORD = 8393;
+pub const ERROR_DS_EXISTS_IN_SUB_CLS: DWORD = 8394;
+pub const ERROR_DS_EXISTS_IN_POSS_SUP: DWORD = 8395;
+pub const ERROR_DS_RECALCSCHEMA_FAILED: DWORD = 8396;
+pub const ERROR_DS_TREE_DELETE_NOT_FINISHED: DWORD = 8397;
+pub const ERROR_DS_CANT_DELETE: DWORD = 8398;
+pub const ERROR_DS_ATT_SCHEMA_REQ_ID: DWORD = 8399;
+pub const ERROR_DS_BAD_ATT_SCHEMA_SYNTAX: DWORD = 8400;
+pub const ERROR_DS_CANT_CACHE_ATT: DWORD = 8401;
+pub const ERROR_DS_CANT_CACHE_CLASS: DWORD = 8402;
+pub const ERROR_DS_CANT_REMOVE_ATT_CACHE: DWORD = 8403;
+pub const ERROR_DS_CANT_REMOVE_CLASS_CACHE: DWORD = 8404;
+pub const ERROR_DS_CANT_RETRIEVE_DN: DWORD = 8405;
+pub const ERROR_DS_MISSING_SUPREF: DWORD = 8406;
+pub const ERROR_DS_CANT_RETRIEVE_INSTANCE: DWORD = 8407;
+pub const ERROR_DS_CODE_INCONSISTENCY: DWORD = 8408;
+pub const ERROR_DS_DATABASE_ERROR: DWORD = 8409;
+pub const ERROR_DS_GOVERNSID_MISSING: DWORD = 8410;
+pub const ERROR_DS_MISSING_EXPECTED_ATT: DWORD = 8411;
+pub const ERROR_DS_NCNAME_MISSING_CR_REF: DWORD = 8412;
+pub const ERROR_DS_SECURITY_CHECKING_ERROR: DWORD = 8413;
+pub const ERROR_DS_SCHEMA_NOT_LOADED: DWORD = 8414;
+pub const ERROR_DS_SCHEMA_ALLOC_FAILED: DWORD = 8415;
+pub const ERROR_DS_ATT_SCHEMA_REQ_SYNTAX: DWORD = 8416;
+pub const ERROR_DS_GCVERIFY_ERROR: DWORD = 8417;
+pub const ERROR_DS_DRA_SCHEMA_MISMATCH: DWORD = 8418;
+pub const ERROR_DS_CANT_FIND_DSA_OBJ: DWORD = 8419;
+pub const ERROR_DS_CANT_FIND_EXPECTED_NC: DWORD = 8420;
+pub const ERROR_DS_CANT_FIND_NC_IN_CACHE: DWORD = 8421;
+pub const ERROR_DS_CANT_RETRIEVE_CHILD: DWORD = 8422;
+pub const ERROR_DS_SECURITY_ILLEGAL_MODIFY: DWORD = 8423;
+pub const ERROR_DS_CANT_REPLACE_HIDDEN_REC: DWORD = 8424;
+pub const ERROR_DS_BAD_HIERARCHY_FILE: DWORD = 8425;
+pub const ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED: DWORD = 8426;
+pub const ERROR_DS_CONFIG_PARAM_MISSING: DWORD = 8427;
+pub const ERROR_DS_COUNTING_AB_INDICES_FAILED: DWORD = 8428;
+pub const ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED: DWORD = 8429;
+pub const ERROR_DS_INTERNAL_FAILURE: DWORD = 8430;
+pub const ERROR_DS_UNKNOWN_ERROR: DWORD = 8431;
+pub const ERROR_DS_ROOT_REQUIRES_CLASS_TOP: DWORD = 8432;
+pub const ERROR_DS_REFUSING_FSMO_ROLES: DWORD = 8433;
+pub const ERROR_DS_MISSING_FSMO_SETTINGS: DWORD = 8434;
+pub const ERROR_DS_UNABLE_TO_SURRENDER_ROLES: DWORD = 8435;
+pub const ERROR_DS_DRA_GENERIC: DWORD = 8436;
+pub const ERROR_DS_DRA_INVALID_PARAMETER: DWORD = 8437;
+pub const ERROR_DS_DRA_BUSY: DWORD = 8438;
+pub const ERROR_DS_DRA_BAD_DN: DWORD = 8439;
+pub const ERROR_DS_DRA_BAD_NC: DWORD = 8440;
+pub const ERROR_DS_DRA_DN_EXISTS: DWORD = 8441;
+pub const ERROR_DS_DRA_INTERNAL_ERROR: DWORD = 8442;
+pub const ERROR_DS_DRA_INCONSISTENT_DIT: DWORD = 8443;
+pub const ERROR_DS_DRA_CONNECTION_FAILED: DWORD = 8444;
+pub const ERROR_DS_DRA_BAD_INSTANCE_TYPE: DWORD = 8445;
+pub const ERROR_DS_DRA_OUT_OF_MEM: DWORD = 8446;
+pub const ERROR_DS_DRA_MAIL_PROBLEM: DWORD = 8447;
+pub const ERROR_DS_DRA_REF_ALREADY_EXISTS: DWORD = 8448;
+pub const ERROR_DS_DRA_REF_NOT_FOUND: DWORD = 8449;
+pub const ERROR_DS_DRA_OBJ_IS_REP_SOURCE: DWORD = 8450;
+pub const ERROR_DS_DRA_DB_ERROR: DWORD = 8451;
+pub const ERROR_DS_DRA_NO_REPLICA: DWORD = 8452;
+pub const ERROR_DS_DRA_ACCESS_DENIED: DWORD = 8453;
+pub const ERROR_DS_DRA_NOT_SUPPORTED: DWORD = 8454;
+pub const ERROR_DS_DRA_RPC_CANCELLED: DWORD = 8455;
+pub const ERROR_DS_DRA_SOURCE_DISABLED: DWORD = 8456;
+pub const ERROR_DS_DRA_SINK_DISABLED: DWORD = 8457;
+pub const ERROR_DS_DRA_NAME_COLLISION: DWORD = 8458;
+pub const ERROR_DS_DRA_SOURCE_REINSTALLED: DWORD = 8459;
+pub const ERROR_DS_DRA_MISSING_PARENT: DWORD = 8460;
+pub const ERROR_DS_DRA_PREEMPTED: DWORD = 8461;
+pub const ERROR_DS_DRA_ABANDON_SYNC: DWORD = 8462;
+pub const ERROR_DS_DRA_SHUTDOWN: DWORD = 8463;
+pub const ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET: DWORD = 8464;
+pub const ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA: DWORD = 8465;
+pub const ERROR_DS_DRA_EXTN_CONNECTION_FAILED: DWORD = 8466;
+pub const ERROR_DS_INSTALL_SCHEMA_MISMATCH: DWORD = 8467;
+pub const ERROR_DS_DUP_LINK_ID: DWORD = 8468;
+pub const ERROR_DS_NAME_ERROR_RESOLVING: DWORD = 8469;
+pub const ERROR_DS_NAME_ERROR_NOT_FOUND: DWORD = 8470;
+pub const ERROR_DS_NAME_ERROR_NOT_UNIQUE: DWORD = 8471;
+pub const ERROR_DS_NAME_ERROR_NO_MAPPING: DWORD = 8472;
+pub const ERROR_DS_NAME_ERROR_DOMAIN_ONLY: DWORD = 8473;
+pub const ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING: DWORD = 8474;
+pub const ERROR_DS_CONSTRUCTED_ATT_MOD: DWORD = 8475;
+pub const ERROR_DS_WRONG_OM_OBJ_CLASS: DWORD = 8476;
+pub const ERROR_DS_DRA_REPL_PENDING: DWORD = 8477;
+pub const ERROR_DS_DS_REQUIRED: DWORD = 8478;
+pub const ERROR_DS_INVALID_LDAP_DISPLAY_NAME: DWORD = 8479;
+pub const ERROR_DS_NON_BASE_SEARCH: DWORD = 8480;
+pub const ERROR_DS_CANT_RETRIEVE_ATTS: DWORD = 8481;
+pub const ERROR_DS_BACKLINK_WITHOUT_LINK: DWORD = 8482;
+pub const ERROR_DS_EPOCH_MISMATCH: DWORD = 8483;
+pub const ERROR_DS_SRC_NAME_MISMATCH: DWORD = 8484;
+pub const ERROR_DS_SRC_AND_DST_NC_IDENTICAL: DWORD = 8485;
+pub const ERROR_DS_DST_NC_MISMATCH: DWORD = 8486;
+pub const ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC: DWORD = 8487;
+pub const ERROR_DS_SRC_GUID_MISMATCH: DWORD = 8488;
+pub const ERROR_DS_CANT_MOVE_DELETED_OBJECT: DWORD = 8489;
+pub const ERROR_DS_PDC_OPERATION_IN_PROGRESS: DWORD = 8490;
+pub const ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD: DWORD = 8491;
+pub const ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION: DWORD = 8492;
+pub const ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS: DWORD = 8493;
+pub const ERROR_DS_NC_MUST_HAVE_NC_PARENT: DWORD = 8494;
+pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE: DWORD = 8495;
+pub const ERROR_DS_DST_DOMAIN_NOT_NATIVE: DWORD = 8496;
+pub const ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER: DWORD = 8497;
+pub const ERROR_DS_CANT_MOVE_ACCOUNT_GROUP: DWORD = 8498;
+pub const ERROR_DS_CANT_MOVE_RESOURCE_GROUP: DWORD = 8499;
+pub const ERROR_DS_INVALID_SEARCH_FLAG: DWORD = 8500;
+pub const ERROR_DS_NO_TREE_DELETE_ABOVE_NC: DWORD = 8501;
+pub const ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE: DWORD = 8502;
+pub const ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE: DWORD = 8503;
+pub const ERROR_DS_SAM_INIT_FAILURE: DWORD = 8504;
+pub const ERROR_DS_SENSITIVE_GROUP_VIOLATION: DWORD = 8505;
+pub const ERROR_DS_CANT_MOD_PRIMARYGROUPID: DWORD = 8506;
+pub const ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD: DWORD = 8507;
+pub const ERROR_DS_NONSAFE_SCHEMA_CHANGE: DWORD = 8508;
+pub const ERROR_DS_SCHEMA_UPDATE_DISALLOWED: DWORD = 8509;
+pub const ERROR_DS_CANT_CREATE_UNDER_SCHEMA: DWORD = 8510;
+pub const ERROR_DS_INSTALL_NO_SRC_SCH_VERSION: DWORD = 8511;
+pub const ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE: DWORD = 8512;
+pub const ERROR_DS_INVALID_GROUP_TYPE: DWORD = 8513;
+pub const ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN: DWORD = 8514;
+pub const ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN: DWORD = 8515;
+pub const ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER: DWORD = 8516;
+pub const ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER: DWORD = 8517;
+pub const ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER: DWORD = 8518;
+pub const ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER: DWORD = 8519;
+pub const ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER: DWORD = 8520;
+pub const ERROR_DS_HAVE_PRIMARY_MEMBERS: DWORD = 8521;
+pub const ERROR_DS_STRING_SD_CONVERSION_FAILED: DWORD = 8522;
+pub const ERROR_DS_NAMING_MASTER_GC: DWORD = 8523;
+pub const ERROR_DS_DNS_LOOKUP_FAILURE: DWORD = 8524;
+pub const ERROR_DS_COULDNT_UPDATE_SPNS: DWORD = 8525;
+pub const ERROR_DS_CANT_RETRIEVE_SD: DWORD = 8526;
+pub const ERROR_DS_KEY_NOT_UNIQUE: DWORD = 8527;
+pub const ERROR_DS_WRONG_LINKED_ATT_SYNTAX: DWORD = 8528;
+pub const ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD: DWORD = 8529;
+pub const ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY: DWORD = 8530;
+pub const ERROR_DS_CANT_START: DWORD = 8531;
+pub const ERROR_DS_INIT_FAILURE: DWORD = 8532;
+pub const ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION: DWORD = 8533;
+pub const ERROR_DS_SOURCE_DOMAIN_IN_FOREST: DWORD = 8534;
+pub const ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST: DWORD = 8535;
+pub const ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED: DWORD = 8536;
+pub const ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN: DWORD = 8537;
+pub const ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER: DWORD = 8538;
+pub const ERROR_DS_SRC_SID_EXISTS_IN_FOREST: DWORD = 8539;
+pub const ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH: DWORD = 8540;
+pub const ERROR_SAM_INIT_FAILURE: DWORD = 8541;
+pub const ERROR_DS_DRA_SCHEMA_INFO_SHIP: DWORD = 8542;
+pub const ERROR_DS_DRA_SCHEMA_CONFLICT: DWORD = 8543;
+pub const ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT: DWORD = 8544;
+pub const ERROR_DS_DRA_OBJ_NC_MISMATCH: DWORD = 8545;
+pub const ERROR_DS_NC_STILL_HAS_DSAS: DWORD = 8546;
+pub const ERROR_DS_GC_REQUIRED: DWORD = 8547;
+pub const ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY: DWORD = 8548;
+pub const ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS: DWORD = 8549;
+pub const ERROR_DS_CANT_ADD_TO_GC: DWORD = 8550;
+pub const ERROR_DS_NO_CHECKPOINT_WITH_PDC: DWORD = 8551;
+pub const ERROR_DS_SOURCE_AUDITING_NOT_ENABLED: DWORD = 8552;
+pub const ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC: DWORD = 8553;
+pub const ERROR_DS_INVALID_NAME_FOR_SPN: DWORD = 8554;
+pub const ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS: DWORD = 8555;
+pub const ERROR_DS_UNICODEPWD_NOT_IN_QUOTES: DWORD = 8556;
+pub const ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED: DWORD = 8557;
+pub const ERROR_DS_MUST_BE_RUN_ON_DST_DC: DWORD = 8558;
+pub const ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER: DWORD = 8559;
+pub const ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ: DWORD = 8560;
+pub const ERROR_DS_INIT_FAILURE_CONSOLE: DWORD = 8561;
+pub const ERROR_DS_SAM_INIT_FAILURE_CONSOLE: DWORD = 8562;
+pub const ERROR_DS_FOREST_VERSION_TOO_HIGH: DWORD = 8563;
+pub const ERROR_DS_DOMAIN_VERSION_TOO_HIGH: DWORD = 8564;
+pub const ERROR_DS_FOREST_VERSION_TOO_LOW: DWORD = 8565;
+pub const ERROR_DS_DOMAIN_VERSION_TOO_LOW: DWORD = 8566;
+pub const ERROR_DS_INCOMPATIBLE_VERSION: DWORD = 8567;
+pub const ERROR_DS_LOW_DSA_VERSION: DWORD = 8568;
+pub const ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN: DWORD = 8569;
+pub const ERROR_DS_NOT_SUPPORTED_SORT_ORDER: DWORD = 8570;
+pub const ERROR_DS_NAME_NOT_UNIQUE: DWORD = 8571;
+pub const ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4: DWORD = 8572;
+pub const ERROR_DS_OUT_OF_VERSION_STORE: DWORD = 8573;
+pub const ERROR_DS_INCOMPATIBLE_CONTROLS_USED: DWORD = 8574;
+pub const ERROR_DS_NO_REF_DOMAIN: DWORD = 8575;
+pub const ERROR_DS_RESERVED_LINK_ID: DWORD = 8576;
+pub const ERROR_DS_LINK_ID_NOT_AVAILABLE: DWORD = 8577;
+pub const ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER: DWORD = 8578;
+pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE: DWORD = 8579;
+pub const ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC: DWORD = 8580;
+pub const ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG: DWORD = 8581;
+pub const ERROR_DS_MODIFYDN_WRONG_GRANDPARENT: DWORD = 8582;
+pub const ERROR_DS_NAME_ERROR_TRUST_REFERRAL: DWORD = 8583;
+pub const ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER: DWORD = 8584;
+pub const ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD: DWORD = 8585;
+pub const ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2: DWORD = 8586;
+pub const ERROR_DS_THREAD_LIMIT_EXCEEDED: DWORD = 8587;
+pub const ERROR_DS_NOT_CLOSEST: DWORD = 8588;
+pub const ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF: DWORD = 8589;
+pub const ERROR_DS_SINGLE_USER_MODE_FAILED: DWORD = 8590;
+pub const ERROR_DS_NTDSCRIPT_SYNTAX_ERROR: DWORD = 8591;
+pub const ERROR_DS_NTDSCRIPT_PROCESS_ERROR: DWORD = 8592;
+pub const ERROR_DS_DIFFERENT_REPL_EPOCHS: DWORD = 8593;
+pub const ERROR_DS_DRS_EXTENSIONS_CHANGED: DWORD = 8594;
+pub const ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR: DWORD = 8595;
+pub const ERROR_DS_NO_MSDS_INTID: DWORD = 8596;
+pub const ERROR_DS_DUP_MSDS_INTID: DWORD = 8597;
+pub const ERROR_DS_EXISTS_IN_RDNATTID: DWORD = 8598;
+pub const ERROR_DS_AUTHORIZATION_FAILED: DWORD = 8599;
+pub const ERROR_DS_INVALID_SCRIPT: DWORD = 8600;
+pub const ERROR_DS_REMOTE_CROSSREF_OP_FAILED: DWORD = 8601;
+pub const ERROR_DS_CROSS_REF_BUSY: DWORD = 8602;
+pub const ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN: DWORD = 8603;
+pub const ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC: DWORD = 8604;
+pub const ERROR_DS_DUPLICATE_ID_FOUND: DWORD = 8605;
+pub const ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT: DWORD = 8606;
+pub const ERROR_DS_GROUP_CONVERSION_ERROR: DWORD = 8607;
+pub const ERROR_DS_CANT_MOVE_APP_BASIC_GROUP: DWORD = 8608;
+pub const ERROR_DS_CANT_MOVE_APP_QUERY_GROUP: DWORD = 8609;
+pub const ERROR_DS_ROLE_NOT_VERIFIED: DWORD = 8610;
+pub const ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL: DWORD = 8611;
+pub const ERROR_DS_DOMAIN_RENAME_IN_PROGRESS: DWORD = 8612;
+pub const ERROR_DS_EXISTING_AD_CHILD_NC: DWORD = 8613;
+pub const ERROR_DS_REPL_LIFETIME_EXCEEDED: DWORD = 8614;
+pub const ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER: DWORD = 8615;
+pub const ERROR_DS_LDAP_SEND_QUEUE_FULL: DWORD = 8616;
+pub const ERROR_DS_DRA_OUT_SCHEDULE_WINDOW: DWORD = 8617;
+pub const ERROR_SXS_SECTION_NOT_FOUND: DWORD = 14000;
+pub const ERROR_SXS_CANT_GEN_ACTCTX: DWORD = 14001;
+pub const ERROR_SXS_INVALID_ACTCTXDATA_FORMAT: DWORD = 14002;
+pub const ERROR_SXS_ASSEMBLY_NOT_FOUND: DWORD = 14003;
+pub const ERROR_SXS_MANIFEST_FORMAT_ERROR: DWORD = 14004;
+pub const ERROR_SXS_MANIFEST_PARSE_ERROR: DWORD = 14005;
+pub const ERROR_SXS_ACTIVATION_CONTEXT_DISABLED: DWORD = 14006;
+pub const ERROR_SXS_KEY_NOT_FOUND: DWORD = 14007;
+pub const ERROR_SXS_VERSION_CONFLICT: DWORD = 14008;
+pub const ERROR_SXS_WRONG_SECTION_TYPE: DWORD = 14009;
+pub const ERROR_SXS_THREAD_QUERIES_DISABLED: DWORD = 14010;
+pub const ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET: DWORD = 14011;
+pub const ERROR_SXS_UNKNOWN_ENCODING_GROUP: DWORD = 14012;
+pub const ERROR_SXS_UNKNOWN_ENCODING: DWORD = 14013;
+pub const ERROR_SXS_INVALID_XML_NAMESPACE_URI: DWORD = 14014;
+pub const ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED: DWORD = 14015;
+pub const ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED: DWORD = 14016;
+pub const ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE: DWORD = 14017;
+pub const ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE: DWORD = 14018;
+pub const ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE: DWORD = 14019;
+pub const ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT: DWORD = 14020;
+pub const ERROR_SXS_DUPLICATE_DLL_NAME: DWORD = 14021;
+pub const ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME: DWORD = 14022;
+pub const ERROR_SXS_DUPLICATE_CLSID: DWORD = 14023;
+pub const ERROR_SXS_DUPLICATE_IID: DWORD = 14024;
+pub const ERROR_SXS_DUPLICATE_TLBID: DWORD = 14025;
+pub const ERROR_SXS_DUPLICATE_PROGID: DWORD = 14026;
+pub const ERROR_SXS_DUPLICATE_ASSEMBLY_NAME: DWORD = 14027;
+pub const ERROR_SXS_FILE_HASH_MISMATCH: DWORD = 14028;
+pub const ERROR_SXS_POLICY_PARSE_ERROR: DWORD = 14029;
+pub const ERROR_SXS_XML_E_MISSINGQUOTE: DWORD = 14030;
+pub const ERROR_SXS_XML_E_COMMENTSYNTAX: DWORD = 14031;
+pub const ERROR_SXS_XML_E_BADSTARTNAMECHAR: DWORD = 14032;
+pub const ERROR_SXS_XML_E_BADNAMECHAR: DWORD = 14033;
+pub const ERROR_SXS_XML_E_BADCHARINSTRING: DWORD = 14034;
+pub const ERROR_SXS_XML_E_XMLDECLSYNTAX: DWORD = 14035;
+pub const ERROR_SXS_XML_E_BADCHARDATA: DWORD = 14036;
+pub const ERROR_SXS_XML_E_MISSINGWHITESPACE: DWORD = 14037;
+pub const ERROR_SXS_XML_E_EXPECTINGTAGEND: DWORD = 14038;
+pub const ERROR_SXS_XML_E_MISSINGSEMICOLON: DWORD = 14039;
+pub const ERROR_SXS_XML_E_UNBALANCEDPAREN: DWORD = 14040;
+pub const ERROR_SXS_XML_E_INTERNALERROR: DWORD = 14041;
+pub const ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE: DWORD = 14042;
+pub const ERROR_SXS_XML_E_INCOMPLETE_ENCODING: DWORD = 14043;
+pub const ERROR_SXS_XML_E_MISSING_PAREN: DWORD = 14044;
+pub const ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE: DWORD = 14045;
+pub const ERROR_SXS_XML_E_MULTIPLE_COLONS: DWORD = 14046;
+pub const ERROR_SXS_XML_E_INVALID_DECIMAL: DWORD = 14047;
+pub const ERROR_SXS_XML_E_INVALID_HEXIDECIMAL: DWORD = 14048;
+pub const ERROR_SXS_XML_E_INVALID_UNICODE: DWORD = 14049;
+pub const ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK: DWORD = 14050;
+pub const ERROR_SXS_XML_E_UNEXPECTEDENDTAG: DWORD = 14051;
+pub const ERROR_SXS_XML_E_UNCLOSEDTAG: DWORD = 14052;
+pub const ERROR_SXS_XML_E_DUPLICATEATTRIBUTE: DWORD = 14053;
+pub const ERROR_SXS_XML_E_MULTIPLEROOTS: DWORD = 14054;
+pub const ERROR_SXS_XML_E_INVALIDATROOTLEVEL: DWORD = 14055;
+pub const ERROR_SXS_XML_E_BADXMLDECL: DWORD = 14056;
+pub const ERROR_SXS_XML_E_MISSINGROOT: DWORD = 14057;
+pub const ERROR_SXS_XML_E_UNEXPECTEDEOF: DWORD = 14058;
+pub const ERROR_SXS_XML_E_BADPEREFINSUBSET: DWORD = 14059;
+pub const ERROR_SXS_XML_E_UNCLOSEDSTARTTAG: DWORD = 14060;
+pub const ERROR_SXS_XML_E_UNCLOSEDENDTAG: DWORD = 14061;
+pub const ERROR_SXS_XML_E_UNCLOSEDSTRING: DWORD = 14062;
+pub const ERROR_SXS_XML_E_UNCLOSEDCOMMENT: DWORD = 14063;
+pub const ERROR_SXS_XML_E_UNCLOSEDDECL: DWORD = 14064;
+pub const ERROR_SXS_XML_E_UNCLOSEDCDATA: DWORD = 14065;
+pub const ERROR_SXS_XML_E_RESERVEDNAMESPACE: DWORD = 14066;
+pub const ERROR_SXS_XML_E_INVALIDENCODING: DWORD = 14067;
+pub const ERROR_SXS_XML_E_INVALIDSWITCH: DWORD = 14068;
+pub const ERROR_SXS_XML_E_BADXMLCASE: DWORD = 14069;
+pub const ERROR_SXS_XML_E_INVALID_STANDALONE: DWORD = 14070;
+pub const ERROR_SXS_XML_E_UNEXPECTED_STANDALONE: DWORD = 14071;
+pub const ERROR_SXS_XML_E_INVALID_VERSION: DWORD = 14072;
+pub const ERROR_SXS_XML_E_MISSINGEQUALS: DWORD = 14073;
+pub const ERROR_SXS_PROTECTION_RECOVERY_FAILED: DWORD = 14074;
+pub const ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT: DWORD = 14075;
+pub const ERROR_SXS_PROTECTION_CATALOG_NOT_VALID: DWORD = 14076;
+pub const ERROR_SXS_UNTRANSLATABLE_HRESULT: DWORD = 14077;
+pub const ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING: DWORD = 14078;
+pub const ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE: DWORD = 14079;
+pub const ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME: DWORD = 14080;
+pub const ERROR_SXS_ASSEMBLY_MISSING: DWORD = 14081;
+pub const ERROR_SXS_CORRUPT_ACTIVATION_STACK: DWORD = 14082;
+pub const ERROR_SXS_CORRUPTION: DWORD = 14083;
+pub const ERROR_SXS_EARLY_DEACTIVATION: DWORD = 14084;
+pub const ERROR_SXS_INVALID_DEACTIVATION: DWORD = 14085;
+pub const ERROR_SXS_MULTIPLE_DEACTIVATION: DWORD = 14086;
+pub const ERROR_SXS_PROCESS_TERMINATION_REQUESTED: DWORD = 14087;
+pub const ERROR_SXS_RELEASE_ACTIVATION_CONTEXT: DWORD = 14088;
+pub const ERROR_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY: DWORD = 14089;
+pub const ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE: DWORD = 14090;
+pub const ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME: DWORD = 14091;
+pub const ERROR_SXS_IDENTITY_DUPLICATE_ATTRIBUTE: DWORD = 14092;
+pub const ERROR_SXS_IDENTITY_PARSE_ERROR: DWORD = 14093;
+pub const ERROR_MALFORMED_SUBSTITUTION_STRING: DWORD = 14094;
+pub const ERROR_SXS_INCORRECT_PUBLIC_KEY_TOKEN: DWORD = 14095;
+pub const ERROR_UNMAPPED_SUBSTITUTION_STRING: DWORD = 14096;
+pub const ERROR_SXS_ASSEMBLY_NOT_LOCKED: DWORD = 14097;
+pub const ERROR_SXS_COMPONENT_STORE_CORRUPT: DWORD = 14098;
+pub const ERROR_ADVANCED_INSTALLER_FAILED: DWORD = 14099;
+pub const ERROR_XML_ENCODING_MISMATCH: DWORD = 14100;
+pub const ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT: DWORD = 14101;
+pub const ERROR_SXS_IDENTITIES_DIFFERENT: DWORD = 14102;
+pub const ERROR_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT: DWORD = 14103;
+pub const ERROR_SXS_FILE_NOT_PART_OF_ASSEMBLY: DWORD = 14104;
+pub const ERROR_SXS_MANIFEST_TOO_BIG: DWORD = 14105;
+pub const ERROR_SXS_SETTING_NOT_REGISTERED: DWORD = 14106;
+pub const ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE: DWORD = 14107;
+pub const ERROR_SMI_PRIMITIVE_INSTALLER_FAILED: DWORD = 14108;
+pub const ERROR_GENERIC_COMMAND_FAILED: DWORD = 14109;
+pub const ERROR_SXS_FILE_HASH_MISSING: DWORD = 14110;
+pub const ERROR_IPSEC_QM_POLICY_EXISTS: DWORD = 13000;
+pub const ERROR_IPSEC_QM_POLICY_NOT_FOUND: DWORD = 13001;
+pub const ERROR_IPSEC_QM_POLICY_IN_USE: DWORD = 13002;
+pub const ERROR_IPSEC_MM_POLICY_EXISTS: DWORD = 13003;
+pub const ERROR_IPSEC_MM_POLICY_NOT_FOUND: DWORD = 13004;
+pub const ERROR_IPSEC_MM_POLICY_IN_USE: DWORD = 13005;
+pub const ERROR_IPSEC_MM_FILTER_EXISTS: DWORD = 13006;
+pub const ERROR_IPSEC_MM_FILTER_NOT_FOUND: DWORD = 13007;
+pub const ERROR_IPSEC_TRANSPORT_FILTER_EXISTS: DWORD = 13008;
+pub const ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND: DWORD = 13009;
+pub const ERROR_IPSEC_MM_AUTH_EXISTS: DWORD = 13010;
+pub const ERROR_IPSEC_MM_AUTH_NOT_FOUND: DWORD = 13011;
+pub const ERROR_IPSEC_MM_AUTH_IN_USE: DWORD = 13012;
+pub const ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND: DWORD = 13013;
+pub const ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND: DWORD = 13014;
+pub const ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND: DWORD = 13015;
+pub const ERROR_IPSEC_TUNNEL_FILTER_EXISTS: DWORD = 13016;
+pub const ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND: DWORD = 13017;
+pub const ERROR_IPSEC_MM_FILTER_PENDING_DELETION: DWORD = 13018;
+pub const ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION: DWORD = 13019;
+pub const ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION: DWORD = 13020;
+pub const ERROR_IPSEC_MM_POLICY_PENDING_DELETION: DWORD = 13021;
+pub const ERROR_IPSEC_MM_AUTH_PENDING_DELETION: DWORD = 13022;
+pub const ERROR_IPSEC_QM_POLICY_PENDING_DELETION: DWORD = 13023;
+pub const ERROR_IPSEC_IKE_NEG_STATUS_BEGIN: DWORD = 13800;
+pub const ERROR_IPSEC_IKE_AUTH_FAIL: DWORD = 13801;
+pub const ERROR_IPSEC_IKE_ATTRIB_FAIL: DWORD = 13802;
+pub const ERROR_IPSEC_IKE_NEGOTIATION_PENDING: DWORD = 13803;
+pub const ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR: DWORD = 13804;
+pub const ERROR_IPSEC_IKE_TIMED_OUT: DWORD = 13805;
+pub const ERROR_IPSEC_IKE_NO_CERT: DWORD = 13806;
+pub const ERROR_IPSEC_IKE_SA_DELETED: DWORD = 13807;
+pub const ERROR_IPSEC_IKE_SA_REAPED: DWORD = 13808;
+pub const ERROR_IPSEC_IKE_MM_ACQUIRE_DROP: DWORD = 13809;
+pub const ERROR_IPSEC_IKE_QM_ACQUIRE_DROP: DWORD = 13810;
+pub const ERROR_IPSEC_IKE_QUEUE_DROP_MM: DWORD = 13811;
+pub const ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM: DWORD = 13812;
+pub const ERROR_IPSEC_IKE_DROP_NO_RESPONSE: DWORD = 13813;
+pub const ERROR_IPSEC_IKE_MM_DELAY_DROP: DWORD = 13814;
+pub const ERROR_IPSEC_IKE_QM_DELAY_DROP: DWORD = 13815;
+pub const ERROR_IPSEC_IKE_ERROR: DWORD = 13816;
+pub const ERROR_IPSEC_IKE_CRL_FAILED: DWORD = 13817;
+pub const ERROR_IPSEC_IKE_INVALID_KEY_USAGE: DWORD = 13818;
+pub const ERROR_IPSEC_IKE_INVALID_CERT_TYPE: DWORD = 13819;
+pub const ERROR_IPSEC_IKE_NO_PRIVATE_KEY: DWORD = 13820;
+pub const ERROR_IPSEC_IKE_DH_FAIL: DWORD = 13822;
+pub const ERROR_IPSEC_IKE_INVALID_HEADER: DWORD = 13824;
+pub const ERROR_IPSEC_IKE_NO_POLICY: DWORD = 13825;
+pub const ERROR_IPSEC_IKE_INVALID_SIGNATURE: DWORD = 13826;
+pub const ERROR_IPSEC_IKE_KERBEROS_ERROR: DWORD = 13827;
+pub const ERROR_IPSEC_IKE_NO_PUBLIC_KEY: DWORD = 13828;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR: DWORD = 13829;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_SA: DWORD = 13830;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_PROP: DWORD = 13831;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_TRANS: DWORD = 13832;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_KE: DWORD = 13833;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_ID: DWORD = 13834;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_CERT: DWORD = 13835;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ: DWORD = 13836;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_HASH: DWORD = 13837;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_SIG: DWORD = 13838;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_NONCE: DWORD = 13839;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY: DWORD = 13840;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_DELETE: DWORD = 13841;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR: DWORD = 13842;
+pub const ERROR_IPSEC_IKE_INVALID_PAYLOAD: DWORD = 13843;
+pub const ERROR_IPSEC_IKE_LOAD_SOFT_SA: DWORD = 13844;
+pub const ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN: DWORD = 13845;
+pub const ERROR_IPSEC_IKE_INVALID_COOKIE: DWORD = 13846;
+pub const ERROR_IPSEC_IKE_NO_PEER_CERT: DWORD = 13847;
+pub const ERROR_IPSEC_IKE_PEER_CRL_FAILED: DWORD = 13848;
+pub const ERROR_IPSEC_IKE_POLICY_CHANGE: DWORD = 13849;
+pub const ERROR_IPSEC_IKE_NO_MM_POLICY: DWORD = 13850;
+pub const ERROR_IPSEC_IKE_NOTCBPRIV: DWORD = 13851;
+pub const ERROR_IPSEC_IKE_SECLOADFAIL: DWORD = 13852;
+pub const ERROR_IPSEC_IKE_FAILSSPINIT: DWORD = 13853;
+pub const ERROR_IPSEC_IKE_FAILQUERYSSP: DWORD = 13854;
+pub const ERROR_IPSEC_IKE_SRVACQFAIL: DWORD = 13855;
+pub const ERROR_IPSEC_IKE_SRVQUERYCRED: DWORD = 13856;
+pub const ERROR_IPSEC_IKE_GETSPIFAIL: DWORD = 13857;
+pub const ERROR_IPSEC_IKE_INVALID_FILTER: DWORD = 13858;
+pub const ERROR_IPSEC_IKE_OUT_OF_MEMORY: DWORD = 13859;
+pub const ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED: DWORD = 13860;
+pub const ERROR_IPSEC_IKE_INVALID_POLICY: DWORD = 13861;
+pub const ERROR_IPSEC_IKE_UNKNOWN_DOI: DWORD = 13862;
+pub const ERROR_IPSEC_IKE_INVALID_SITUATION: DWORD = 13863;
+pub const ERROR_IPSEC_IKE_DH_FAILURE: DWORD = 13864;
+pub const ERROR_IPSEC_IKE_INVALID_GROUP: DWORD = 13865;
+pub const ERROR_IPSEC_IKE_ENCRYPT: DWORD = 13866;
+pub const ERROR_IPSEC_IKE_DECRYPT: DWORD = 13867;
+pub const ERROR_IPSEC_IKE_POLICY_MATCH: DWORD = 13868;
+pub const ERROR_IPSEC_IKE_UNSUPPORTED_ID: DWORD = 13869;
+pub const ERROR_IPSEC_IKE_INVALID_HASH: DWORD = 13870;
+pub const ERROR_IPSEC_IKE_INVALID_HASH_ALG: DWORD = 13871;
+pub const ERROR_IPSEC_IKE_INVALID_HASH_SIZE: DWORD = 13872;
+pub const ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG: DWORD = 13873;
+pub const ERROR_IPSEC_IKE_INVALID_AUTH_ALG: DWORD = 13874;
+pub const ERROR_IPSEC_IKE_INVALID_SIG: DWORD = 13875;
+pub const ERROR_IPSEC_IKE_LOAD_FAILED: DWORD = 13876;
+pub const ERROR_IPSEC_IKE_RPC_DELETE: DWORD = 13877;
+pub const ERROR_IPSEC_IKE_BENIGN_REINIT: DWORD = 13878;
+pub const ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY: DWORD = 13879;
+pub const ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN: DWORD = 13881;
+pub const ERROR_IPSEC_IKE_MM_LIMIT: DWORD = 13882;
+pub const ERROR_IPSEC_IKE_NEGOTIATION_DISABLED: DWORD = 13883;
+/*pub const ERROR_IPSEC_IKE_NEG_STATUS_END: DWORD = 13884)*/
+pub const ERROR_IPSEC_IKE_QM_LIMIT: DWORD = 13884;
+pub const ERROR_IPSEC_IKE_MM_EXPIRED: DWORD = 13885;
+pub const ERROR_IPSEC_IKE_PEER_MM_ASSUMED_INVALID: DWORD = 13886;
+pub const ERROR_IPSEC_IKE_CERT_CHAIN_POLICY_MISMATCH: DWORD = 13887;
+pub const ERROR_IPSEC_IKE_UNEXPECTED_MESSAGE_ID: DWORD = 13888;
+pub const ERROR_IPSEC_IKE_INVALID_AUTH_PAYLOAD: DWORD = 13889;
+pub const ERROR_IPSEC_IKE_DOS_COOKIE_SENT: DWORD = 13890;
+pub const ERROR_IPSEC_IKE_SHUTTING_DOWN: DWORD = 13891;
+pub const ERROR_IPSEC_IKE_CGA_AUTH_FAILED: DWORD = 13892;
+pub const ERROR_IPSEC_IKE_PROCESS_ERR_NATOA: DWORD = 13893;
+pub const ERROR_IPSEC_IKE_INVALID_MM_FOR_QM: DWORD = 13894;
+pub const ERROR_IPSEC_IKE_QM_EXPIRED: DWORD = 13895;
+pub const ERROR_IPSEC_IKE_TOO_MANY_FILTERS: DWORD = 13896;
+pub const ERROR_IPSEC_IKE_NEG_STATUS_END: DWORD = 13897;
+pub const ERROR_IPSEC_IKE_KILL_DUMMY_NAP_TUNNEL: DWORD = 13898;
+pub const ERROR_IPSEC_IKE_INNER_IP_ASSIGNMENT_FAILURE: DWORD = 13899;
+pub const ERROR_IPSEC_IKE_REQUIRE_CP_PAYLOAD_MISSING: DWORD = 13900;
+pub const ERROR_IPSEC_KEY_MODULE_IMPERSONATION_NEGOTIATION_PENDING: DWORD = 13901;
+pub const ERROR_IPSEC_IKE_COEXISTENCE_SUPPRESS: DWORD = 13902;
+pub const ERROR_IPSEC_IKE_RATELIMIT_DROP: DWORD = 13903;
+pub const ERROR_IPSEC_IKE_PEER_DOESNT_SUPPORT_MOBIKE: DWORD = 13904;
+pub const ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE: DWORD = 13905;
+pub const ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_FAILURE: DWORD = 13906;
+pub const ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE_WITH_OPTIONAL_RETRY: DWORD = 13907;
+pub const ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_AND_CERTMAP_FAILURE: DWORD = 13908;
+pub const ERROR_IPSEC_IKE_NEG_STATUS_EXTENDED_END: DWORD = 13909;
+pub const ERROR_IPSEC_BAD_SPI: DWORD = 13910;
+pub const ERROR_IPSEC_SA_LIFETIME_EXPIRED: DWORD = 13911;
+pub const ERROR_IPSEC_WRONG_SA: DWORD = 13912;
+pub const ERROR_IPSEC_REPLAY_CHECK_FAILED: DWORD = 13913;
+pub const ERROR_IPSEC_INVALID_PACKET: DWORD = 13914;
+pub const ERROR_IPSEC_INTEGRITY_CHECK_FAILED: DWORD = 13915;
+pub const ERROR_IPSEC_CLEAR_TEXT_DROP: DWORD = 13916;
+pub const ERROR_IPSEC_AUTH_FIREWALL_DROP: DWORD = 13917;
+pub const ERROR_IPSEC_THROTTLE_DROP: DWORD = 13918;
+pub const ERROR_IPSEC_DOSP_BLOCK: DWORD = 13925;
+pub const ERROR_IPSEC_DOSP_RECEIVED_MULTICAST: DWORD = 13926;
+pub const ERROR_IPSEC_DOSP_INVALID_PACKET: DWORD = 13927;
+pub const ERROR_IPSEC_DOSP_STATE_LOOKUP_FAILED: DWORD = 13928;
+pub const ERROR_IPSEC_DOSP_MAX_ENTRIES: DWORD = 13929;
+pub const ERROR_IPSEC_DOSP_KEYMOD_NOT_ALLOWED: DWORD = 13930;
+pub const ERROR_IPSEC_DOSP_NOT_INSTALLED: DWORD = 13931;
+pub const ERROR_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES: DWORD = 13932;
+pub const ERROR_EVT_INVALID_CHANNEL_PATH: DWORD = 15000;
+pub const ERROR_EVT_INVALID_QUERY: DWORD = 15001;
+pub const ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND: DWORD = 15002;
+pub const ERROR_EVT_EVENT_TEMPLATE_NOT_FOUND: DWORD = 15003;
+pub const ERROR_EVT_INVALID_PUBLISHER_NAME: DWORD = 15004;
+pub const ERROR_EVT_INVALID_EVENT_DATA: DWORD = 15005;
+pub const ERROR_EVT_CHANNEL_NOT_FOUND: DWORD = 15007;
+pub const ERROR_EVT_MALFORMED_XML_TEXT: DWORD = 15008;
+pub const ERROR_EVT_SUBSCRIPTION_TO_DIRECT_CHANNEL: DWORD = 15009;
+pub const ERROR_EVT_CONFIGURATION_ERROR: DWORD = 15010;
+pub const ERROR_EVT_QUERY_RESULT_STALE: DWORD = 15011;
+pub const ERROR_EVT_QUERY_RESULT_INVALID_POSITION: DWORD = 15012;
+pub const ERROR_EVT_NON_VALIDATING_MSXML: DWORD = 15013;
+pub const ERROR_EVT_FILTER_ALREADYSCOPED: DWORD = 15014;
+pub const ERROR_EVT_FILTER_NOTELTSET: DWORD = 15015;
+pub const ERROR_EVT_FILTER_INVARG: DWORD = 15016;
+pub const ERROR_EVT_FILTER_INVTEST: DWORD = 15017;
+pub const ERROR_EVT_FILTER_INVTYPE: DWORD = 15018;
+pub const ERROR_EVT_FILTER_PARSEERR: DWORD = 15019;
+pub const ERROR_EVT_FILTER_UNSUPPORTEDOP: DWORD = 15020;
+pub const ERROR_EVT_FILTER_UNEXPECTEDTOKEN: DWORD = 15021;
+pub const ERROR_EVT_INVALID_OPERATION_OVER_ENABLED_DIRECT_CHANNEL: DWORD = 15022;
+pub const ERROR_EVT_INVALID_CHANNEL_PROPERTY_VALUE: DWORD = 15023;
+pub const ERROR_EVT_INVALID_PUBLISHER_PROPERTY_VALUE: DWORD = 15024;
+pub const ERROR_EVT_CHANNEL_CANNOT_ACTIVATE: DWORD = 15025;
+pub const ERROR_EVT_FILTER_TOO_COMPLEX: DWORD = 15026;
+pub const ERROR_EVT_MESSAGE_NOT_FOUND: DWORD = 15027;
+pub const ERROR_EVT_MESSAGE_ID_NOT_FOUND: DWORD = 15028;
+pub const ERROR_EVT_UNRESOLVED_VALUE_INSERT: DWORD = 15029;
+pub const ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: DWORD = 15030;
+pub const ERROR_EVT_MAX_INSERTS_REACHED: DWORD = 15031;
+pub const ERROR_EVT_EVENT_DEFINITION_NOT_FOUND: DWORD = 15032;
+pub const ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: DWORD = 15033;
+pub const ERROR_EVT_VERSION_TOO_OLD: DWORD = 15034;
+pub const ERROR_EVT_VERSION_TOO_NEW: DWORD = 15035;
+pub const ERROR_EVT_CANNOT_OPEN_CHANNEL_OF_QUERY: DWORD = 15036;
+pub const ERROR_EVT_PUBLISHER_DISABLED: DWORD = 15037;
+pub const ERROR_EVT_FILTER_OUT_OF_RANGE: DWORD = 15038;
+pub const ERROR_EC_SUBSCRIPTION_CANNOT_ACTIVATE: DWORD = 15080;
+pub const ERROR_EC_LOG_DISABLED: DWORD = 15081;
+pub const ERROR_EC_CIRCULAR_FORWARDING: DWORD = 15082;
+pub const ERROR_EC_CREDSTORE_FULL: DWORD = 15083;
+pub const ERROR_EC_CRED_NOT_FOUND: DWORD = 15084;
+pub const ERROR_EC_NO_ACTIVE_CHANNEL: DWORD = 15085;
+pub const ERROR_MUI_FILE_NOT_FOUND: DWORD = 15100;
+pub const ERROR_MUI_INVALID_FILE: DWORD = 15101;
+pub const ERROR_MUI_INVALID_RC_CONFIG: DWORD = 15102;
+pub const ERROR_MUI_INVALID_LOCALE_NAME: DWORD = 15103;
+pub const ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME: DWORD = 15104;
+pub const ERROR_MUI_FILE_NOT_LOADED: DWORD = 15105;
+pub const ERROR_RESOURCE_ENUM_USER_STOP: DWORD = 15106;
+pub const ERROR_MUI_INTLSETTINGS_UILANG_NOT_INSTALLED: DWORD = 15107;
+pub const ERROR_MUI_INTLSETTINGS_INVALID_LOCALE_NAME: DWORD = 15108;
+pub const ERROR_MRM_RUNTIME_NO_DEFAULT_OR_NEUTRAL_RESOURCE: DWORD = 15110;
+pub const ERROR_MRM_INVALID_PRICONFIG: DWORD = 15111;
+pub const ERROR_MRM_INVALID_FILE_TYPE: DWORD = 15112;
+pub const ERROR_MRM_UNKNOWN_QUALIFIER: DWORD = 15113;
+pub const ERROR_MRM_INVALID_QUALIFIER_VALUE: DWORD = 15114;
+pub const ERROR_MRM_NO_CANDIDATE: DWORD = 15115;
+pub const ERROR_MRM_NO_MATCH_OR_DEFAULT_CANDIDATE: DWORD = 15116;
+pub const ERROR_MRM_RESOURCE_TYPE_MISMATCH: DWORD = 15117;
+pub const ERROR_MRM_DUPLICATE_MAP_NAME: DWORD = 15118;
+pub const ERROR_MRM_DUPLICATE_ENTRY: DWORD = 15119;
+pub const ERROR_MRM_INVALID_RESOURCE_IDENTIFIER: DWORD = 15120;
+pub const ERROR_MRM_FILEPATH_TOO_LONG: DWORD = 15121;
+pub const ERROR_MRM_UNSUPPORTED_DIRECTORY_TYPE: DWORD = 15122;
+pub const ERROR_MRM_INVALID_PRI_FILE: DWORD = 15126;
+pub const ERROR_MRM_NAMED_RESOURCE_NOT_FOUND: DWORD = 15127;
+pub const ERROR_MRM_MAP_NOT_FOUND: DWORD = 15135;
+pub const ERROR_MRM_UNSUPPORTED_PROFILE_TYPE: DWORD = 15136;
+pub const ERROR_MRM_INVALID_QUALIFIER_OPERATOR: DWORD = 15137;
+pub const ERROR_MRM_INDETERMINATE_QUALIFIER_VALUE: DWORD = 15138;
+pub const ERROR_MRM_AUTOMERGE_ENABLED: DWORD = 15139;
+pub const ERROR_MRM_TOO_MANY_RESOURCES: DWORD = 15140;
+pub const ERROR_MCA_INVALID_CAPABILITIES_STRING: DWORD = 15200;
+pub const ERROR_MCA_INVALID_VCP_VERSION: DWORD = 15201;
+pub const ERROR_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION: DWORD = 15202;
+pub const ERROR_MCA_MCCS_VERSION_MISMATCH: DWORD = 15203;
+pub const ERROR_MCA_UNSUPPORTED_MCCS_VERSION: DWORD = 15204;
+pub const ERROR_MCA_INTERNAL_ERROR: DWORD = 15205;
+pub const ERROR_MCA_INVALID_TECHNOLOGY_TYPE_RETURNED: DWORD = 15206;
+pub const ERROR_MCA_UNSUPPORTED_COLOR_TEMPERATURE: DWORD = 15207;
+pub const ERROR_AMBIGUOUS_SYSTEM_DEVICE: DWORD = 15250;
+pub const ERROR_SYSTEM_DEVICE_NOT_FOUND: DWORD = 15299;
+pub const ERROR_HASH_NOT_SUPPORTED: DWORD = 15300;
+pub const ERROR_HASH_NOT_PRESENT: DWORD = 15301;
+pub const ERROR_SECONDARY_IC_PROVIDER_NOT_REGISTERED: DWORD = 15321;
+pub const ERROR_GPIO_CLIENT_INFORMATION_INVALID: DWORD = 15322;
+pub const ERROR_GPIO_VERSION_NOT_SUPPORTED: DWORD = 15323;
+pub const ERROR_GPIO_INVALID_REGISTRATION_PACKET: DWORD = 15324;
+pub const ERROR_GPIO_OPERATION_DENIED: DWORD = 15325;
+pub const ERROR_GPIO_INCOMPATIBLE_CONNECT_MODE: DWORD = 15326;
+pub const ERROR_GPIO_INTERRUPT_ALREADY_UNMASKED: DWORD = 15327;
+pub const ERROR_CANNOT_SWITCH_RUNLEVEL: DWORD = 15400;
+pub const ERROR_INVALID_RUNLEVEL_SETTING: DWORD = 15401;
+pub const ERROR_RUNLEVEL_SWITCH_TIMEOUT: DWORD = 15402;
+pub const ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT: DWORD = 15403;
+pub const ERROR_RUNLEVEL_SWITCH_IN_PROGRESS: DWORD = 15404;
+pub const ERROR_SERVICES_FAILED_AUTOSTART: DWORD = 15405;
+pub const ERROR_COM_TASK_STOP_PENDING: DWORD = 15501;
+pub const ERROR_INSTALL_OPEN_PACKAGE_FAILED: DWORD = 15600;
+pub const ERROR_INSTALL_PACKAGE_NOT_FOUND: DWORD = 15601;
+pub const ERROR_INSTALL_INVALID_PACKAGE: DWORD = 15602;
+pub const ERROR_INSTALL_RESOLVE_DEPENDENCY_FAILED: DWORD = 15603;
+pub const ERROR_INSTALL_OUT_OF_DISK_SPACE: DWORD = 15604;
+pub const ERROR_INSTALL_NETWORK_FAILURE: DWORD = 15605;
+pub const ERROR_INSTALL_REGISTRATION_FAILURE: DWORD = 15606;
+pub const ERROR_INSTALL_DEREGISTRATION_FAILURE: DWORD = 15607;
+pub const ERROR_INSTALL_CANCEL: DWORD = 15608;
+pub const ERROR_INSTALL_FAILED: DWORD = 15609;
+pub const ERROR_REMOVE_FAILED: DWORD = 15610;
+pub const ERROR_PACKAGE_ALREADY_EXISTS: DWORD = 15611;
+pub const ERROR_NEEDS_REMEDIATION: DWORD = 15612;
+pub const ERROR_INSTALL_PREREQUISITE_FAILED: DWORD = 15613;
+pub const ERROR_PACKAGE_REPOSITORY_CORRUPTED: DWORD = 15614;
+pub const ERROR_INSTALL_POLICY_FAILURE: DWORD = 15615;
+pub const ERROR_PACKAGE_UPDATING: DWORD = 15616;
+pub const ERROR_DEPLOYMENT_BLOCKED_BY_POLICY: DWORD = 15617;
+pub const ERROR_PACKAGES_IN_USE: DWORD = 15618;
+pub const ERROR_RECOVERY_FILE_CORRUPT: DWORD = 15619;
+pub const ERROR_INVALID_STAGED_SIGNATURE: DWORD = 15620;
+pub const ERROR_DELETING_EXISTING_APPLICATIONDATA_STORE_FAILED: DWORD = 15621;
+pub const ERROR_INSTALL_PACKAGE_DOWNGRADE: DWORD = 15622;
+pub const ERROR_SYSTEM_NEEDS_REMEDIATION: DWORD = 15623;
+pub const ERROR_APPX_INTEGRITY_FAILURE_CLR_NGEN: DWORD = 15624;
+pub const ERROR_RESILIENCY_FILE_CORRUPT: DWORD = 15625;
+pub const ERROR_INSTALL_FIREWALL_SERVICE_NOT_RUNNING: DWORD = 15626;
+pub const ERROR_STATE_LOAD_STORE_FAILED: DWORD = 15800;
+pub const ERROR_STATE_GET_VERSION_FAILED: DWORD = 15801;
+pub const ERROR_STATE_SET_VERSION_FAILED: DWORD = 15802;
+pub const ERROR_STATE_STRUCTURED_RESET_FAILED: DWORD = 15803;
+pub const ERROR_STATE_OPEN_CONTAINER_FAILED: DWORD = 15804;
+pub const ERROR_STATE_CREATE_CONTAINER_FAILED: DWORD = 15805;
+pub const ERROR_STATE_DELETE_CONTAINER_FAILED: DWORD = 15806;
+pub const ERROR_STATE_READ_SETTING_FAILED: DWORD = 15807;
+pub const ERROR_STATE_WRITE_SETTING_FAILED: DWORD = 15808;
+pub const ERROR_STATE_DELETE_SETTING_FAILED: DWORD = 15809;
+pub const ERROR_STATE_QUERY_SETTING_FAILED: DWORD = 15810;
+pub const ERROR_STATE_READ_COMPOSITE_SETTING_FAILED: DWORD = 15811;
+pub const ERROR_STATE_WRITE_COMPOSITE_SETTING_FAILED: DWORD = 15812;
+pub const ERROR_STATE_ENUMERATE_CONTAINER_FAILED: DWORD = 15813;
+pub const ERROR_STATE_ENUMERATE_SETTINGS_FAILED: DWORD = 15814;
+pub const ERROR_STATE_COMPOSITE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED: DWORD = 15815;
+pub const ERROR_STATE_SETTING_VALUE_SIZE_LIMIT_EXCEEDED: DWORD = 15816;
+pub const ERROR_STATE_SETTING_NAME_SIZE_LIMIT_EXCEEDED: DWORD = 15817;
+pub const ERROR_STATE_CONTAINER_NAME_SIZE_LIMIT_EXCEEDED: DWORD = 15818;
+pub const ERROR_API_UNAVAILABLE: DWORD = 15841;
+pub const ERROR_AUDITING_DISABLED: DWORD = 0xC0090001;
+pub const ERROR_ALL_SIDS_FILTERED: DWORD = 0xC0090002;
+
+pub const WSABASEERR: c_int = 10000;
+pub const WSAEINTR: c_int = WSABASEERR + 4;
+pub const WSAEBADF: c_int = WSABASEERR + 9;
+pub const WSAEACCES: c_int = WSABASEERR + 13;
+pub const WSAEFAULT: c_int = WSABASEERR + 14;
+pub const WSAEINVAL: c_int = WSABASEERR + 22;
+pub const WSAEMFILE: c_int = WSABASEERR + 24;
+pub const WSAEWOULDBLOCK: c_int = WSABASEERR + 35;
+pub const WSAEINPROGRESS: c_int = WSABASEERR + 36;
+pub const WSAEALREADY: c_int = WSABASEERR + 37;
+pub const WSAENOTSOCK: c_int = WSABASEERR + 38;
+pub const WSAEDESTADDRREQ: c_int = WSABASEERR + 39;
+pub const WSAEMSGSIZE: c_int = WSABASEERR + 40;
+pub const WSAEPROTOTYPE: c_int = WSABASEERR + 41;
+pub const WSAENOPROTOOPT: c_int = WSABASEERR + 42;
+pub const WSAEPROTONOSUPPORT: c_int = WSABASEERR + 43;
+pub const WSAESOCKTNOSUPPORT: c_int = WSABASEERR + 44;
+pub const WSAEOPNOTSUPP: c_int = WSABASEERR + 45;
+pub const WSAEPFNOSUPPORT: c_int = WSABASEERR + 46;
+pub const WSAEAFNOSUPPORT: c_int = WSABASEERR + 47;
+pub const WSAEADDRINUSE: c_int = WSABASEERR + 48;
+pub const WSAEADDRNOTAVAIL: c_int = WSABASEERR + 49;
+pub const WSAENETDOWN: c_int = WSABASEERR + 50;
+pub const WSAENETUNREACH: c_int = WSABASEERR + 51;
+pub const WSAENETRESET: c_int = WSABASEERR + 52;
+pub const WSAECONNABORTED: c_int = WSABASEERR + 53;
+pub const WSAECONNRESET: c_int = WSABASEERR + 54;
+pub const WSAENOBUFS: c_int = WSABASEERR + 55;
+pub const WSAEISCONN: c_int = WSABASEERR + 56;
+pub const WSAENOTCONN: c_int = WSABASEERR + 57;
+pub const WSAESHUTDOWN: c_int = WSABASEERR + 58;
+pub const WSAETOOMANYREFS: c_int = WSABASEERR + 59;
+pub const WSAETIMEDOUT: c_int = WSABASEERR + 60;
+pub const WSAECONNREFUSED: c_int = WSABASEERR + 61;
+pub const WSAELOOP: c_int = WSABASEERR + 62;
+pub const WSAENAMETOOLONG: c_int = WSABASEERR + 63;
+pub const WSAEHOSTDOWN: c_int = WSABASEERR + 64;
+pub const WSAEHOSTUNREACH: c_int = WSABASEERR + 65;
+pub const WSAENOTEMPTY: c_int = WSABASEERR + 66;
+pub const WSAEPROCLIM: c_int = WSABASEERR + 67;
+pub const WSAEUSERS: c_int = WSABASEERR + 68;
+pub const WSAEDQUOT: c_int = WSABASEERR + 69;
+pub const WSAESTALE: c_int = WSABASEERR + 70;
+pub const WSAEREMOTE: c_int = WSABASEERR + 71;
+pub const WSASYSNOTREADY: c_int = WSABASEERR + 91;
+pub const WSAVERNOTSUPPORTED: c_int = WSABASEERR + 92;
+pub const WSANOTINITIALISED: c_int = WSABASEERR + 93;
+pub const WSAEDISCON: c_int = WSABASEERR + 101;
+pub const WSAENOMORE: c_int = WSABASEERR + 102;
+pub const WSAECANCELLED: c_int = WSABASEERR + 103;
+pub const WSAEINVALIDPROCTABLE: c_int = WSABASEERR + 104;
+pub const WSAEINVALIDPROVIDER: c_int = WSABASEERR + 105;
+pub const WSAEPROVIDERFAILEDINIT: c_int = WSABASEERR + 106;
+pub const WSASYSCALLFAILURE: c_int = WSABASEERR + 107;
+pub const WSASERVICE_NOT_FOUND: c_int = WSABASEERR + 108;
+pub const WSATYPE_NOT_FOUND: c_int = WSABASEERR + 109;
+pub const WSA_E_NO_MORE: c_int = WSABASEERR + 110;
+pub const WSA_E_CANCELLED: c_int = WSABASEERR + 111;
+pub const WSAEREFUSED: c_int = WSABASEERR + 112;
+pub const WSAHOST_NOT_FOUND: c_int = WSABASEERR + 1001;
+pub const WSATRY_AGAIN: c_int = WSABASEERR + 1002;
+pub const WSANO_RECOVERY: c_int = WSABASEERR + 1003;
+pub const WSANO_DATA: c_int = WSABASEERR + 1004;
+pub const WSA_QOS_RECEIVERS: c_int = WSABASEERR + 1005;
+pub const WSA_QOS_SENDERS: c_int = WSABASEERR + 1006;
+pub const WSA_QOS_NO_SENDERS: c_int = WSABASEERR + 1007;
+pub const WSA_QOS_NO_RECEIVERS: c_int = WSABASEERR + 1008;
+pub const WSA_QOS_REQUEST_CONFIRMED: c_int = WSABASEERR + 1009;
+pub const WSA_QOS_ADMISSION_FAILURE: c_int = WSABASEERR + 1010;
+pub const WSA_QOS_POLICY_FAILURE: c_int = WSABASEERR + 1011;
+pub const WSA_QOS_BAD_STYLE: c_int = WSABASEERR + 1012;
+pub const WSA_QOS_BAD_OBJECT: c_int = WSABASEERR + 1013;
+pub const WSA_QOS_TRAFFIC_CTRL_ERROR: c_int = WSABASEERR + 1014;
+pub const WSA_QOS_GENERIC_ERROR: c_int = WSABASEERR + 1015;
+pub const WSA_QOS_ESERVICETYPE: c_int = WSABASEERR + 1016;
+pub const WSA_QOS_EFLOWSPEC: c_int = WSABASEERR + 1017;
+pub const WSA_QOS_EPROVSPECBUF: c_int = WSABASEERR + 1018;
+pub const WSA_QOS_EFILTERSTYLE: c_int = WSABASEERR + 1019;
+pub const WSA_QOS_EFILTERTYPE: c_int = WSABASEERR + 1020;
+pub const WSA_QOS_EFILTERCOUNT: c_int = WSABASEERR + 1021;
+pub const WSA_QOS_EOBJLENGTH: c_int = WSABASEERR + 1022;
+pub const WSA_QOS_EFLOWCOUNT: c_int = WSABASEERR + 1023;
+pub const WSA_QOS_EUNKNOWNPSOBJ: c_int = WSABASEERR + 1024;
+pub const WSA_QOS_EUNKOWNPSOBJ: c_int = WSA_QOS_EUNKNOWNPSOBJ;
+pub const WSA_QOS_EPOLICYOBJ: c_int = WSABASEERR + 1025;
+pub const WSA_QOS_EFLOWDESC: c_int = WSABASEERR + 1026;
+pub const WSA_QOS_EPSFLOWSPEC: c_int = WSABASEERR + 1027;
+pub const WSA_QOS_EPSFILTERSPEC: c_int = WSABASEERR + 1028;
+pub const WSA_QOS_ESDMODEOBJ: c_int = WSABASEERR + 1029;
+pub const WSA_QOS_ESHAPERATEOBJ: c_int = WSABASEERR + 1030;
+pub const WSA_QOS_RESERVED_PETYPE: c_int = WSABASEERR + 1031;
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index 2b6143de960..c677adae688 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -514,7 +514,7 @@ impl File {
                 }
                 _ => {
                     return Err(io::Error::new_const(
-                        io::ErrorKind::Other,
+                        io::ErrorKind::Uncategorized,
                         &"Unsupported reparse point type",
                     ));
                 }
@@ -961,9 +961,8 @@ pub fn try_exists(path: &Path) -> io::Result<bool> {
             // `ERROR_SHARING_VIOLATION` means that the file has been locked by
             // another process. This is often temporary so we simply report it
             // as the file existing.
-            io::ErrorKind::Other if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => {
-                Ok(true)
-            }
+            _ if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => Ok(true),
+
             // Other errors such as `ERROR_ACCESS_DENIED` may indicate that the
             // file exists. However, these types of errors are usually more
             // permanent so we report them here.
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index f23e874f249..28fec817f86 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -61,16 +61,18 @@ pub unsafe fn cleanup() {
 }
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
+    use ErrorKind::*;
+
     match errno as c::DWORD {
-        c::ERROR_ACCESS_DENIED => return ErrorKind::PermissionDenied,
-        c::ERROR_ALREADY_EXISTS => return ErrorKind::AlreadyExists,
-        c::ERROR_FILE_EXISTS => return ErrorKind::AlreadyExists,
-        c::ERROR_BROKEN_PIPE => return ErrorKind::BrokenPipe,
-        c::ERROR_FILE_NOT_FOUND => return ErrorKind::NotFound,
-        c::ERROR_PATH_NOT_FOUND => return ErrorKind::NotFound,
-        c::ERROR_NO_DATA => return ErrorKind::BrokenPipe,
-        c::ERROR_INVALID_PARAMETER => return ErrorKind::InvalidInput,
-        c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return ErrorKind::OutOfMemory,
+        c::ERROR_ACCESS_DENIED => return PermissionDenied,
+        c::ERROR_ALREADY_EXISTS => return AlreadyExists,
+        c::ERROR_FILE_EXISTS => return AlreadyExists,
+        c::ERROR_BROKEN_PIPE => return BrokenPipe,
+        c::ERROR_FILE_NOT_FOUND => return NotFound,
+        c::ERROR_PATH_NOT_FOUND => return NotFound,
+        c::ERROR_NO_DATA => return BrokenPipe,
+        c::ERROR_INVALID_PARAMETER => return InvalidInput,
+        c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory,
         c::ERROR_SEM_TIMEOUT
         | c::WAIT_TIMEOUT
         | c::ERROR_DRIVER_CANCEL_TIMEOUT
@@ -86,24 +88,42 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         | c::DNS_ERROR_RECORD_TIMED_OUT
         | c::ERROR_IPSEC_IKE_TIMED_OUT
         | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
-        | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return ErrorKind::TimedOut,
-        c::ERROR_CALL_NOT_IMPLEMENTED => return ErrorKind::Unsupported,
+        | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return TimedOut,
+        c::ERROR_CALL_NOT_IMPLEMENTED => return Unsupported,
+        c::ERROR_HOST_UNREACHABLE => return HostUnreachable,
+        c::ERROR_NETWORK_UNREACHABLE => return NetworkUnreachable,
+        c::ERROR_DIRECTORY => return NotADirectory,
+        c::ERROR_DIRECTORY_NOT_SUPPORTED => return IsADirectory,
+        c::ERROR_DIR_NOT_EMPTY => return DirectoryNotEmpty,
+        c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem,
+        c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull,
+        c::ERROR_SEEK_ON_DEVICE => return NotSeekable,
+        c::ERROR_DISK_QUOTA_EXCEEDED => return FilesystemQuotaExceeded,
+        c::ERROR_FILE_TOO_LARGE => return FileTooLarge,
+        c::ERROR_BUSY => return ResourceBusy,
+        c::ERROR_POSSIBLE_DEADLOCK => return Deadlock,
+        c::ERROR_NOT_SAME_DEVICE => return CrossesDevices,
+        c::ERROR_TOO_MANY_LINKS => return TooManyLinks,
+        c::ERROR_FILENAME_EXCED_RANGE => return FilenameTooLong,
         _ => {}
     }
 
     match errno {
-        c::WSAEACCES => ErrorKind::PermissionDenied,
-        c::WSAEADDRINUSE => ErrorKind::AddrInUse,
-        c::WSAEADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
-        c::WSAECONNABORTED => ErrorKind::ConnectionAborted,
-        c::WSAECONNREFUSED => ErrorKind::ConnectionRefused,
-        c::WSAECONNRESET => ErrorKind::ConnectionReset,
-        c::WSAEINVAL => ErrorKind::InvalidInput,
-        c::WSAENOTCONN => ErrorKind::NotConnected,
-        c::WSAEWOULDBLOCK => ErrorKind::WouldBlock,
-        c::WSAETIMEDOUT => ErrorKind::TimedOut,
+        c::WSAEACCES => PermissionDenied,
+        c::WSAEADDRINUSE => AddrInUse,
+        c::WSAEADDRNOTAVAIL => AddrNotAvailable,
+        c::WSAECONNABORTED => ConnectionAborted,
+        c::WSAECONNREFUSED => ConnectionRefused,
+        c::WSAECONNRESET => ConnectionReset,
+        c::WSAEINVAL => InvalidInput,
+        c::WSAENOTCONN => NotConnected,
+        c::WSAEWOULDBLOCK => WouldBlock,
+        c::WSAETIMEDOUT => TimedOut,
+        c::WSAEHOSTUNREACH => HostUnreachable,
+        c::WSAENETDOWN => NetworkDown,
+        c::WSAENETUNREACH => NetworkUnreachable,
 
-        _ => ErrorKind::Other,
+        _ => Uncategorized,
     }
 }
 
diff --git a/library/std/src/sys/windows/mutex.rs b/library/std/src/sys/windows/mutex.rs
index 12c5ea741f9..56f91ebe582 100644
--- a/library/std/src/sys/windows/mutex.rs
+++ b/library/std/src/sys/windows/mutex.rs
@@ -1,6 +1,6 @@
 //! System Mutexes
 //!
-//! The Windows implementation of mutexes is a little odd and it may not be
+//! The Windows implementation of mutexes is a little odd and it might not be
 //! immediately obvious what's going on. The primary oddness is that SRWLock is
 //! used instead of CriticalSection, and this is done because:
 //!
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index 1ad13254c08..9cea5c5e63a 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -12,7 +12,7 @@ use crate::sys_common::net;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::Duration;
 
-use libc::{c_int, c_long, c_ulong, c_void};
+use libc::{c_int, c_long, c_ulong};
 
 pub type wrlen_t = i32;
 
@@ -93,153 +93,177 @@ where
 
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match *addr {
+        let family = match *addr {
             SocketAddr::V4(..) => c::AF_INET,
             SocketAddr::V6(..) => c::AF_INET6,
         };
         let socket = unsafe {
-            match c::WSASocketW(
-                fam,
+            c::WSASocketW(
+                family,
                 ty,
                 0,
                 ptr::null_mut(),
                 0,
                 c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT,
-            ) {
-                c::INVALID_SOCKET => match c::WSAGetLastError() {
-                    c::WSAEPROTOTYPE | c::WSAEINVAL => {
-                        match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0, c::WSA_FLAG_OVERLAPPED)
-                        {
-                            c::INVALID_SOCKET => Err(last_error()),
-                            n => {
-                                let s = Socket(n);
-                                s.set_no_inherit()?;
-                                Ok(s)
-                            }
-                        }
-                    }
-                    n => Err(io::Error::from_raw_os_error(n)),
-                },
-                n => Ok(Socket(n)),
+            )
+        };
+
+        if socket != c::INVALID_SOCKET {
+            Ok(Self(socket))
+        } else {
+            let error = unsafe { c::WSAGetLastError() };
+
+            if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL {
+                return Err(io::Error::from_raw_os_error(error));
+            }
+
+            let socket =
+                unsafe { c::WSASocketW(family, ty, 0, ptr::null_mut(), 0, c::WSA_FLAG_OVERLAPPED) };
+
+            if socket == c::INVALID_SOCKET {
+                return Err(last_error());
             }
-        }?;
-        Ok(socket)
+
+            let socket = Self(socket);
+            socket.set_no_inherit()?;
+            Ok(socket)
+        }
     }
 
     pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
         self.set_nonblocking(true)?;
-        let r = unsafe {
+        let result = {
             let (addrp, len) = addr.into_inner();
-            cvt(c::connect(self.0, addrp, len))
+            let result = unsafe { c::connect(self.0, addrp, len) };
+            cvt(result).map(drop)
         };
         self.set_nonblocking(false)?;
 
-        match r {
-            Ok(_) => return Ok(()),
-            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
-            Err(e) => return Err(e),
-        }
-
-        if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
-            return Err(io::Error::new_const(
-                io::ErrorKind::InvalidInput,
-                &"cannot set a 0 duration timeout",
-            ));
-        }
-
-        let mut timeout = c::timeval {
-            tv_sec: timeout.as_secs() as c_long,
-            tv_usec: (timeout.subsec_nanos() / 1000) as c_long,
-        };
-        if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
-            timeout.tv_usec = 1;
-        }
+        match result {
+            Err(ref error) if error.kind() == io::ErrorKind::WouldBlock => {
+                if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
+                    return Err(io::Error::new_const(
+                        io::ErrorKind::InvalidInput,
+                        &"cannot set a 0 duration timeout",
+                    ));
+                }
 
-        let fds = unsafe {
-            let mut fds = mem::zeroed::<c::fd_set>();
-            fds.fd_count = 1;
-            fds.fd_array[0] = self.0;
-            fds
-        };
+                let mut timeout = c::timeval {
+                    tv_sec: timeout.as_secs() as c_long,
+                    tv_usec: (timeout.subsec_nanos() / 1000) as c_long,
+                };
 
-        let mut writefds = fds;
-        let mut errorfds = fds;
+                if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
+                    timeout.tv_usec = 1;
+                }
 
-        let n =
-            unsafe { cvt(c::select(1, ptr::null_mut(), &mut writefds, &mut errorfds, &timeout))? };
+                let fds = {
+                    let mut fds = unsafe { mem::zeroed::<c::fd_set>() };
+                    fds.fd_count = 1;
+                    fds.fd_array[0] = self.0;
+                    fds
+                };
+
+                let mut writefds = fds;
+                let mut errorfds = fds;
+
+                let count = {
+                    let result = unsafe {
+                        c::select(1, ptr::null_mut(), &mut writefds, &mut errorfds, &timeout)
+                    };
+                    cvt(result)?
+                };
+
+                match count {
+                    0 => {
+                        Err(io::Error::new_const(io::ErrorKind::TimedOut, &"connection timed out"))
+                    }
+                    _ => {
+                        if writefds.fd_count != 1 {
+                            if let Some(e) = self.take_error()? {
+                                return Err(e);
+                            }
+                        }
 
-        match n {
-            0 => Err(io::Error::new_const(io::ErrorKind::TimedOut, &"connection timed out")),
-            _ => {
-                if writefds.fd_count != 1 {
-                    if let Some(e) = self.take_error()? {
-                        return Err(e);
+                        Ok(())
                     }
                 }
-                Ok(())
             }
+            _ => result,
         }
     }
 
     pub fn accept(&self, storage: *mut c::SOCKADDR, len: *mut c_int) -> io::Result<Socket> {
-        let socket = unsafe {
-            match c::accept(self.0, storage, len) {
-                c::INVALID_SOCKET => Err(last_error()),
-                n => Ok(Socket(n)),
-            }
-        }?;
-        Ok(socket)
+        let socket = unsafe { c::accept(self.0, storage, len) };
+
+        match socket {
+            c::INVALID_SOCKET => Err(last_error()),
+            _ => Ok(Self(socket)),
+        }
     }
 
     pub fn duplicate(&self) -> io::Result<Socket> {
+        let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
+        let result = unsafe { c::WSADuplicateSocketW(self.0, c::GetCurrentProcessId(), &mut info) };
+        cvt(result)?;
         let socket = unsafe {
-            let mut info: c::WSAPROTOCOL_INFO = mem::zeroed();
-            cvt(c::WSADuplicateSocketW(self.0, c::GetCurrentProcessId(), &mut info))?;
-
-            match c::WSASocketW(
+            c::WSASocketW(
                 info.iAddressFamily,
                 info.iSocketType,
                 info.iProtocol,
                 &mut info,
                 0,
                 c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT,
-            ) {
-                c::INVALID_SOCKET => match c::WSAGetLastError() {
-                    c::WSAEPROTOTYPE | c::WSAEINVAL => {
-                        match c::WSASocketW(
-                            info.iAddressFamily,
-                            info.iSocketType,
-                            info.iProtocol,
-                            &mut info,
-                            0,
-                            c::WSA_FLAG_OVERLAPPED,
-                        ) {
-                            c::INVALID_SOCKET => Err(last_error()),
-                            n => {
-                                let s = Socket(n);
-                                s.set_no_inherit()?;
-                                Ok(s)
-                            }
-                        }
-                    }
-                    n => Err(io::Error::from_raw_os_error(n)),
-                },
-                n => Ok(Socket(n)),
+            )
+        };
+
+        if socket != c::INVALID_SOCKET {
+            Ok(Self(socket))
+        } else {
+            let error = unsafe { c::WSAGetLastError() };
+
+            if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL {
+                return Err(io::Error::from_raw_os_error(error));
+            }
+
+            let socket = unsafe {
+                c::WSASocketW(
+                    info.iAddressFamily,
+                    info.iSocketType,
+                    info.iProtocol,
+                    &mut info,
+                    0,
+                    c::WSA_FLAG_OVERLAPPED,
+                )
+            };
+
+            if socket == c::INVALID_SOCKET {
+                return Err(last_error());
             }
-        }?;
-        Ok(socket)
+
+            let socket = Self(socket);
+            socket.set_no_inherit()?;
+            Ok(socket)
+        }
     }
 
     fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
         // On unix when a socket is shut down all further reads return 0, so we
         // do the same on windows to map a shut down socket to returning EOF.
-        let len = cmp::min(buf.len(), i32::MAX as usize) as i32;
-        unsafe {
-            match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, flags) {
-                -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
-                -1 => Err(last_error()),
-                n => Ok(n as usize),
+        let length = cmp::min(buf.len(), i32::MAX as usize) as i32;
+        let result = unsafe { c::recv(self.0, buf.as_mut_ptr() as *mut _, length, flags) };
+
+        match result {
+            c::SOCKET_ERROR => {
+                let error = unsafe { c::WSAGetLastError() };
+
+                if error == c::WSAESHUTDOWN {
+                    Ok(0)
+                } else {
+                    Err(io::Error::from_raw_os_error(error))
+                }
             }
+            _ => Ok(result as usize),
         }
     }
 
@@ -250,23 +274,31 @@ impl Socket {
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         // On unix when a socket is shut down all further reads return 0, so we
         // do the same on windows to map a shut down socket to returning EOF.
-        let len = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD;
+        let length = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD;
         let mut nread = 0;
         let mut flags = 0;
-        unsafe {
-            let ret = c::WSARecv(
+        let result = unsafe {
+            c::WSARecv(
                 self.0,
                 bufs.as_mut_ptr() as *mut c::WSABUF,
-                len,
+                length,
                 &mut nread,
                 &mut flags,
                 ptr::null_mut(),
                 ptr::null_mut(),
-            );
-            match ret {
-                0 => Ok(nread as usize),
-                _ if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
-                _ => Err(last_error()),
+            )
+        };
+
+        match result {
+            0 => Ok(nread as usize),
+            _ => {
+                let error = unsafe { c::WSAGetLastError() };
+
+                if error == c::WSAESHUTDOWN {
+                    Ok(0)
+                } else {
+                    Err(io::Error::from_raw_os_error(error))
+                }
             }
         }
     }
@@ -285,27 +317,34 @@ impl Socket {
         buf: &mut [u8],
         flags: c_int,
     ) -> io::Result<(usize, SocketAddr)> {
-        let mut storage: c::SOCKADDR_STORAGE_LH = unsafe { mem::zeroed() };
+        let mut storage = unsafe { mem::zeroed::<c::SOCKADDR_STORAGE_LH>() };
         let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
-        let len = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
+        let length = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
 
         // On unix when a socket is shut down all further reads return 0, so we
         // do the same on windows to map a shut down socket to returning EOF.
-        unsafe {
-            match c::recvfrom(
+        let result = unsafe {
+            c::recvfrom(
                 self.0,
-                buf.as_mut_ptr() as *mut c_void,
-                len,
+                buf.as_mut_ptr() as *mut _,
+                length,
                 flags,
                 &mut storage as *mut _ as *mut _,
                 &mut addrlen,
-            ) {
-                -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => {
+            )
+        };
+
+        match result {
+            c::SOCKET_ERROR => {
+                let error = unsafe { c::WSAGetLastError() };
+
+                if error == c::WSAESHUTDOWN {
                     Ok((0, net::sockaddr_to_addr(&storage, addrlen as usize)?))
+                } else {
+                    Err(io::Error::from_raw_os_error(error))
                 }
-                -1 => Err(last_error()),
-                n => Ok((n as usize, net::sockaddr_to_addr(&storage, addrlen as usize)?)),
             }
+            _ => Ok((result as usize, net::sockaddr_to_addr(&storage, addrlen as usize)?)),
         }
     }
 
@@ -318,20 +357,20 @@ impl Socket {
     }
 
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        let len = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD;
+        let length = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD;
         let mut nwritten = 0;
-        unsafe {
-            cvt(c::WSASend(
+        let result = unsafe {
+            c::WSASend(
                 self.0,
-                bufs.as_ptr() as *const c::WSABUF as *mut c::WSABUF,
-                len,
+                bufs.as_ptr() as *const c::WSABUF as *mut _,
+                length,
                 &mut nwritten,
                 0,
                 ptr::null_mut(),
                 ptr::null_mut(),
-            ))?;
-        }
-        Ok(nwritten as usize)
+            )
+        };
+        cvt(result).map(|_| nwritten as usize)
     }
 
     #[inline]
@@ -384,14 +423,14 @@ impl Socket {
             Shutdown::Read => c::SD_RECEIVE,
             Shutdown::Both => c::SD_BOTH,
         };
-        cvt(unsafe { c::shutdown(self.0, how) })?;
-        Ok(())
+        let result = unsafe { c::shutdown(self.0, how) };
+        cvt(result).map(drop)
     }
 
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         let mut nonblocking = nonblocking as c_ulong;
-        let r = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) };
-        if r == 0 { Ok(()) } else { Err(io::Error::last_os_error()) }
+        let result = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) };
+        cvt(result).map(drop)
     }
 
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs
index 77c378a66af..8db97ba50a8 100644
--- a/library/std/src/sys/windows/os.rs
+++ b/library/std/src/sys/windows/os.rs
@@ -253,22 +253,13 @@ pub fn chdir(p: &path::Path) -> io::Result<()> {
     cvt(unsafe { c::SetCurrentDirectoryW(p.as_ptr()) }).map(drop)
 }
 
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
-    let k = to_u16s(k)?;
-    let res = super::fill_utf16_buf(
+pub fn getenv(k: &OsStr) -> Option<OsString> {
+    let k = to_u16s(k).ok()?;
+    super::fill_utf16_buf(
         |buf, sz| unsafe { c::GetEnvironmentVariableW(k.as_ptr(), buf, sz) },
         |buf| OsStringExt::from_wide(buf),
-    );
-    match res {
-        Ok(value) => Ok(Some(value)),
-        Err(e) => {
-            if e.raw_os_error() == Some(c::ERROR_ENVVAR_NOT_FOUND as i32) {
-                Ok(None)
-            } else {
-                Err(e)
-            }
-        }
-    }
+    )
+    .ok()
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index 81dbea4a067..ae193b82e91 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -3,7 +3,7 @@
 #[cfg(test)]
 mod tests;
 
-use crate::borrow::Borrow;
+use crate::cmp;
 use crate::collections::BTreeMap;
 use crate::convert::{TryFrom, TryInto};
 use crate::env;
@@ -34,32 +34,115 @@ use libc::{c_void, EXIT_FAILURE, EXIT_SUCCESS};
 // Command
 ////////////////////////////////////////////////////////////////////////////////
 
-#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
+#[derive(Clone, Debug, Eq)]
 #[doc(hidden)]
-pub struct EnvKey(OsString);
+pub struct EnvKey {
+    os_string: OsString,
+    // This stores a UTF-16 encoded string to workaround the mismatch between
+    // Rust's OsString (WTF-8) and the Windows API string type (UTF-16).
+    // Normally converting on every API call is acceptable but here
+    // `c::CompareStringOrdinal` will be called for every use of `==`.
+    utf16: Vec<u16>,
+}
+
+impl EnvKey {
+    fn new<T: Into<OsString>>(key: T) -> Self {
+        EnvKey::from(key.into())
+    }
+}
+
+// Comparing Windows environment variable keys[1] are behaviourally the
+// composition of two operations[2]:
+//
+// 1. Case-fold both strings. This is done using a language-independent
+// uppercase mapping that's unique to Windows (albeit based on data from an
+// older Unicode spec). It only operates on individual UTF-16 code units so
+// surrogates are left unchanged. This uppercase mapping can potentially change
+// between Windows versions.
+//
+// 2. Perform an ordinal comparison of the strings. A comparison using ordinal
+// is just a comparison based on the numerical value of each UTF-16 code unit[3].
+//
+// Because the case-folding mapping is unique to Windows and not guaranteed to
+// be stable, we ask the OS to compare the strings for us. This is done by
+// calling `CompareStringOrdinal`[4] with `bIgnoreCase` set to `TRUE`.
+//
+// [1] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#choosing-a-stringcomparison-member-for-your-method-call
+// [2] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#stringtoupper-and-stringtolower
+// [3] https://docs.microsoft.com/en-us/dotnet/api/system.stringcomparison?view=net-5.0#System_StringComparison_Ordinal
+// [4] https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal
+impl Ord for EnvKey {
+    fn cmp(&self, other: &Self) -> cmp::Ordering {
+        unsafe {
+            let result = c::CompareStringOrdinal(
+                self.utf16.as_ptr(),
+                self.utf16.len() as _,
+                other.utf16.as_ptr(),
+                other.utf16.len() as _,
+                c::TRUE,
+            );
+            match result {
+                c::CSTR_LESS_THAN => cmp::Ordering::Less,
+                c::CSTR_EQUAL => cmp::Ordering::Equal,
+                c::CSTR_GREATER_THAN => cmp::Ordering::Greater,
+                // `CompareStringOrdinal` should never fail so long as the parameters are correct.
+                _ => panic!("comparing environment keys failed: {}", Error::last_os_error()),
+            }
+        }
+    }
+}
+impl PartialOrd for EnvKey {
+    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+impl PartialEq for EnvKey {
+    fn eq(&self, other: &Self) -> bool {
+        if self.utf16.len() != other.utf16.len() {
+            false
+        } else {
+            self.cmp(other) == cmp::Ordering::Equal
+        }
+    }
+}
+impl PartialOrd<str> for EnvKey {
+    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
+        Some(self.cmp(&EnvKey::new(other)))
+    }
+}
+impl PartialEq<str> for EnvKey {
+    fn eq(&self, other: &str) -> bool {
+        if self.os_string.len() != other.len() {
+            false
+        } else {
+            self.cmp(&EnvKey::new(other)) == cmp::Ordering::Equal
+        }
+    }
+}
 
+// Environment variable keys should preserve their original case even though
+// they are compared using a caseless string mapping.
 impl From<OsString> for EnvKey {
-    fn from(mut k: OsString) -> Self {
-        k.make_ascii_uppercase();
-        EnvKey(k)
+    fn from(k: OsString) -> Self {
+        EnvKey { utf16: k.encode_wide().collect(), os_string: k }
     }
 }
 
 impl From<EnvKey> for OsString {
     fn from(k: EnvKey) -> Self {
-        k.0
+        k.os_string
     }
 }
 
-impl Borrow<OsStr> for EnvKey {
-    fn borrow(&self) -> &OsStr {
-        &self.0
+impl From<&OsStr> for EnvKey {
+    fn from(k: &OsStr) -> Self {
+        Self::from(k.to_os_string())
     }
 }
 
 impl AsRef<OsStr> for EnvKey {
     fn as_ref(&self) -> &OsStr {
-        &self.0
+        &self.os_string
     }
 }
 
@@ -73,7 +156,7 @@ fn ensure_no_nuls<T: AsRef<OsStr>>(str: T) -> io::Result<T> {
 
 pub struct Command {
     program: OsString,
-    args: Vec<OsString>,
+    args: Vec<Arg>,
     env: CommandEnv,
     cwd: Option<OsString>,
     flags: u32,
@@ -97,6 +180,14 @@ pub struct StdioPipes {
     pub stderr: Option<AnonPipe>,
 }
 
+#[derive(Debug)]
+enum Arg {
+    /// Add quotes (if needed)
+    Regular(OsString),
+    /// Append raw string without quoting
+    Raw(OsString),
+}
+
 impl Command {
     pub fn new(program: &OsStr) -> Command {
         Command {
@@ -114,7 +205,7 @@ impl Command {
     }
 
     pub fn arg(&mut self, arg: &OsStr) {
-        self.args.push(arg.to_os_string())
+        self.args.push(Arg::Regular(arg.to_os_string()))
     }
     pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
@@ -139,6 +230,10 @@ impl Command {
         self.force_quotes_enabled = enabled;
     }
 
+    pub fn raw_arg(&mut self, command_str_to_append: &OsStr) {
+        self.args.push(Arg::Raw(command_str_to_append.to_os_string()))
+    }
+
     pub fn get_program(&self) -> &OsStr {
         &self.program
     }
@@ -166,7 +261,7 @@ impl Command {
         // to read the *child's* PATH if one is provided. See #15149 for more
         // details.
         let program = maybe_env.as_ref().and_then(|env| {
-            if let Some(v) = env.get(OsStr::new("PATH")) {
+            if let Some(v) = env.get(&EnvKey::new("PATH")) {
                 // Split the value and test each path to see if the
                 // program exists.
                 for path in split_paths(&v) {
@@ -207,7 +302,7 @@ impl Command {
         // the remaining portion of this spawn in a mutex.
         //
         // For more information, msdn also has an article about this race:
-        // http://support.microsoft.com/kb/315939
+        // https://support.microsoft.com/kb/315939
         static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
 
         let _guard = unsafe { CREATE_PROCESS_LOCK.lock() };
@@ -251,9 +346,13 @@ impl Command {
 
 impl fmt::Debug for Command {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}", self.program)?;
+        self.program.fmt(f)?;
         for arg in &self.args {
-            write!(f, " {:?}", arg)?;
+            f.write_str(" ")?;
+            match arg {
+                Arg::Regular(s) => s.fmt(f),
+                Arg::Raw(s) => f.write_str(&s.to_string_lossy()),
+            }?;
         }
         Ok(())
     }
@@ -472,44 +571,63 @@ fn zeroed_process_information() -> c::PROCESS_INFORMATION {
     }
 }
 
+enum Quote {
+    // Every arg is quoted
+    Always,
+    // Whitespace and empty args are quoted
+    Auto,
+    // Arg appended without any changes (#29494)
+    Never,
+}
+
 // Produces a wide string *without terminating null*; returns an error if
 // `prog` or any of the `args` contain a nul.
-fn make_command_line(prog: &OsStr, args: &[OsString], force_quotes: bool) -> io::Result<Vec<u16>> {
+fn make_command_line(prog: &OsStr, args: &[Arg], force_quotes: bool) -> io::Result<Vec<u16>> {
     // Encode the command and arguments in a command line string such
     // that the spawned process may recover them using CommandLineToArgvW.
     let mut cmd: Vec<u16> = Vec::new();
     // Always quote the program name so CreateProcess doesn't interpret args as
     // part of the name if the binary wasn't found first time.
-    append_arg(&mut cmd, prog, true)?;
+    append_arg(&mut cmd, prog, Quote::Always)?;
     for arg in args {
         cmd.push(' ' as u16);
-        append_arg(&mut cmd, arg, force_quotes)?;
+        let (arg, quote) = match arg {
+            Arg::Regular(arg) => (arg, if force_quotes { Quote::Always } else { Quote::Auto }),
+            Arg::Raw(arg) => (arg, Quote::Never),
+        };
+        append_arg(&mut cmd, arg, quote)?;
     }
     return Ok(cmd);
 
-    fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, force_quotes: bool) -> io::Result<()> {
+    fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, quote: Quote) -> io::Result<()> {
         // If an argument has 0 characters then we need to quote it to ensure
         // that it actually gets passed through on the command line or otherwise
         // it will be dropped entirely when parsed on the other end.
         ensure_no_nuls(arg)?;
         let arg_bytes = &arg.as_inner().inner.as_inner();
-        let quote = force_quotes
-            || arg_bytes.iter().any(|c| *c == b' ' || *c == b'\t')
-            || arg_bytes.is_empty();
+        let (quote, escape) = match quote {
+            Quote::Always => (true, true),
+            Quote::Auto => {
+                (arg_bytes.iter().any(|c| *c == b' ' || *c == b'\t') || arg_bytes.is_empty(), true)
+            }
+            Quote::Never => (false, false),
+        };
         if quote {
             cmd.push('"' as u16);
         }
 
         let mut backslashes: usize = 0;
         for x in arg.encode_wide() {
-            if x == '\\' as u16 {
-                backslashes += 1;
-            } else {
-                if x == '"' as u16 {
-                    // Add n+1 backslashes to total 2n+1 before internal '"'.
-                    cmd.extend((0..=backslashes).map(|_| '\\' as u16));
+            if escape {
+                if x == '\\' as u16 {
+                    backslashes += 1;
+                } else {
+                    if x == '"' as u16 {
+                        // Add n+1 backslashes to total 2n+1 before internal '"'.
+                        cmd.extend((0..=backslashes).map(|_| '\\' as u16));
+                    }
+                    backslashes = 0;
                 }
-                backslashes = 0;
             }
             cmd.push(x);
         }
@@ -530,8 +648,15 @@ fn make_envp(maybe_env: Option<BTreeMap<EnvKey, OsString>>) -> io::Result<(*mut
     if let Some(env) = maybe_env {
         let mut blk = Vec::new();
 
+        // If there are no environment variables to set then signal this by
+        // pushing a null.
+        if env.is_empty() {
+            blk.push(0);
+        }
+
         for (k, v) in env {
-            blk.extend(ensure_no_nuls(k.0)?.encode_wide());
+            ensure_no_nuls(k.os_string)?;
+            blk.extend(k.utf16);
             blk.push('=' as u16);
             blk.extend(ensure_no_nuls(v)?.encode_wide());
             blk.push(0);
@@ -555,13 +680,15 @@ fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> {
 }
 
 pub struct CommandArgs<'a> {
-    iter: crate::slice::Iter<'a, OsString>,
+    iter: crate::slice::Iter<'a, Arg>,
 }
 
 impl<'a> Iterator for CommandArgs<'a> {
     type Item = &'a OsStr;
     fn next(&mut self) -> Option<&'a OsStr> {
-        self.iter.next().map(|s| s.as_ref())
+        self.iter.next().map(|arg| match arg {
+            Arg::Regular(s) | Arg::Raw(s) => s.as_ref(),
+        })
     }
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
diff --git a/library/std/src/sys/windows/process/tests.rs b/library/std/src/sys/windows/process/tests.rs
index 8830ae049c6..3b65856dcac 100644
--- a/library/std/src/sys/windows/process/tests.rs
+++ b/library/std/src/sys/windows/process/tests.rs
@@ -1,12 +1,35 @@
 use super::make_command_line;
+use super::Arg;
+use crate::env;
 use crate::ffi::{OsStr, OsString};
+use crate::process::Command;
+
+#[test]
+fn test_raw_args() {
+    let command_line = &make_command_line(
+        OsStr::new("quoted exe"),
+        &[
+            Arg::Regular(OsString::from("quote me")),
+            Arg::Raw(OsString::from("quote me *not*")),
+            Arg::Raw(OsString::from("\t\\")),
+            Arg::Raw(OsString::from("internal \\\"backslash-\"quote")),
+            Arg::Regular(OsString::from("optional-quotes")),
+        ],
+        false,
+    )
+    .unwrap();
+    assert_eq!(
+        String::from_utf16(command_line).unwrap(),
+        "\"quoted exe\" \"quote me\" quote me *not* \t\\ internal \\\"backslash-\"quote optional-quotes"
+    );
+}
 
 #[test]
 fn test_make_command_line() {
     fn test_wrapper(prog: &str, args: &[&str], force_quotes: bool) -> String {
         let command_line = &make_command_line(
             OsStr::new(prog),
-            &args.iter().map(|a| OsString::from(a)).collect::<Vec<OsString>>(),
+            &args.iter().map(|a| Arg::Regular(OsString::from(a))).collect::<Vec<_>>(),
             force_quotes,
         )
         .unwrap();
@@ -15,6 +38,11 @@ fn test_make_command_line() {
 
     assert_eq!(test_wrapper("prog", &["aaa", "bbb", "ccc"], false), "\"prog\" aaa bbb ccc");
 
+    assert_eq!(test_wrapper("prog", &[r"C:\"], false), r#""prog" C:\"#);
+    assert_eq!(test_wrapper("prog", &[r"2slashes\\"], false), r#""prog" 2slashes\\"#);
+    assert_eq!(test_wrapper("prog", &[r" C:\"], false), r#""prog" " C:\\""#);
+    assert_eq!(test_wrapper("prog", &[r" 2slashes\\"], false), r#""prog" " 2slashes\\\\""#);
+
     assert_eq!(
         test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"], false),
         "\"C:\\Program Files\\blah\\blah.exe\" aaa"
@@ -41,3 +69,62 @@ fn test_make_command_line() {
         "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\""
     );
 }
+
+// On Windows, environment args are case preserving but comparisons are case-insensitive.
+// See: #85242
+#[test]
+fn windows_env_unicode_case() {
+    let test_cases = [
+        ("ä", "Ä"),
+        ("ß", "SS"),
+        ("Ä", "Ö"),
+        ("Ä", "Ö"),
+        ("I", "İ"),
+        ("I", "i"),
+        ("I", "ı"),
+        ("i", "I"),
+        ("i", "İ"),
+        ("i", "ı"),
+        ("İ", "I"),
+        ("İ", "i"),
+        ("İ", "ı"),
+        ("ı", "I"),
+        ("ı", "i"),
+        ("ı", "İ"),
+        ("ä", "Ä"),
+        ("ß", "SS"),
+        ("Ä", "Ö"),
+        ("Ä", "Ö"),
+        ("I", "İ"),
+        ("I", "i"),
+        ("I", "ı"),
+        ("i", "I"),
+        ("i", "İ"),
+        ("i", "ı"),
+        ("İ", "I"),
+        ("İ", "i"),
+        ("İ", "ı"),
+        ("ı", "I"),
+        ("ı", "i"),
+        ("ı", "İ"),
+    ];
+    // Test that `cmd.env` matches `env::set_var` when setting two strings that
+    // may (or may not) be case-folded when compared.
+    for (a, b) in test_cases.iter() {
+        let mut cmd = Command::new("cmd");
+        cmd.env(a, "1");
+        cmd.env(b, "2");
+        env::set_var(a, "1");
+        env::set_var(b, "2");
+
+        for (key, value) in cmd.get_envs() {
+            assert_eq!(
+                env::var(key).ok(),
+                value.map(|s| s.to_string_lossy().into_owned()),
+                "command environment mismatch: {} {}",
+                a,
+                b
+            );
+        }
+    }
+}
diff --git a/library/std/src/sys/windows/rwlock.rs b/library/std/src/sys/windows/rwlock.rs
index a769326352c..b7a5b1e7acc 100644
--- a/library/std/src/sys/windows/rwlock.rs
+++ b/library/std/src/sys/windows/rwlock.rs
@@ -5,6 +5,8 @@ pub struct RWLock {
     inner: UnsafeCell<c::SRWLOCK>,
 }
 
+pub type MovableRWLock = RWLock;
+
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs
index be3141e46a1..2973951fe90 100644
--- a/library/std/src/sys/windows/stdio.rs
+++ b/library/std/src/sys/windows/stdio.rs
@@ -169,7 +169,7 @@ impl io::Read for Stdin {
 
 // We assume that if the last `u16` is an unpaired surrogate they got sliced apart by our
 // buffer size, and keep it around for the next read hoping to put them together.
-// This is a best effort, and may not work if we are not the only reader on Stdin.
+// This is a best effort, and might not work if we are not the only reader on Stdin.
 fn read_u16s_fixup_surrogates(
     handle: c::HANDLE,
     buf: &mut [u16],
diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs
index 38839ea5e90..ef7a9733fd8 100644
--- a/library/std/src/sys/windows/thread.rs
+++ b/library/std/src/sys/windows/thread.rs
@@ -1,5 +1,6 @@
 use crate::ffi::CStr;
 use crate::io;
+use crate::num::NonZeroUsize;
 use crate::ptr;
 use crate::sys::c;
 use crate::sys::handle::Handle;
@@ -98,6 +99,21 @@ impl Thread {
     }
 }
 
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    let res = unsafe {
+        let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed();
+        c::GetSystemInfo(&mut sysinfo);
+        sysinfo.dwNumberOfProcessors as usize
+    };
+    match res {
+        0 => Err(io::Error::new_const(
+            io::ErrorKind::NotFound,
+            &"The number of hardware threads is not known for the target platform",
+        )),
+        cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }),
+    }
+}
+
 #[cfg_attr(test, allow(dead_code))]
 pub mod guard {
     pub type Guard = !;
diff --git a/library/std/src/sys/windows/thread_local_key.rs b/library/std/src/sys/windows/thread_local_key.rs
index 065365e5572..0bc51114665 100644
--- a/library/std/src/sys/windows/thread_local_key.rs
+++ b/library/std/src/sys/windows/thread_local_key.rs
@@ -35,7 +35,7 @@ pub type Dtor = unsafe extern "C" fn(*mut u8);
 //
 // For more details and nitty-gritty, see the code sections below!
 //
-// [1]: http://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
+// [1]: https://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
 // [2]: https://github.com/ChromiumWebApps/chromium/blob/master/base
 //                        /threading/thread_local_storage_win.cc#L42
 
diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs
index a549770d8b3..e6a099f0e81 100644
--- a/library/std/src/sys_common/backtrace.rs
+++ b/library/std/src/sys_common/backtrace.rs
@@ -75,7 +75,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
             hit = true;
             if print_fmt == PrintFmt::Short {
                 if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
-                    if sym.contains("__rust_begin_short_backtrace") {
+                    if start && sym.contains("__rust_begin_short_backtrace") {
                         stop = true;
                         return;
                     }
diff --git a/library/std/src/sys_common/bytestring.rs b/library/std/src/sys_common/bytestring.rs
deleted file mode 100644
index 97fba60c271..00000000000
--- a/library/std/src/sys_common/bytestring.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#![allow(dead_code)]
-
-#[cfg(test)]
-mod tests;
-
-use crate::fmt::{Formatter, Result, Write};
-use core::str::lossy::{Utf8Lossy, Utf8LossyChunk};
-
-pub fn debug_fmt_bytestring(slice: &[u8], f: &mut Formatter<'_>) -> Result {
-    // Writes out a valid unicode string with the correct escape sequences
-    fn write_str_escaped(f: &mut Formatter<'_>, s: &str) -> Result {
-        for c in s.chars().flat_map(|c| c.escape_debug()) {
-            f.write_char(c)?
-        }
-        Ok(())
-    }
-
-    f.write_str("\"")?;
-    for Utf8LossyChunk { valid, broken } in Utf8Lossy::from_bytes(slice).chunks() {
-        write_str_escaped(f, valid)?;
-        for b in broken {
-            write!(f, "\\x{:02X}", b)?;
-        }
-    }
-    f.write_str("\"")
-}
diff --git a/library/std/src/sys_common/bytestring/tests.rs b/library/std/src/sys_common/bytestring/tests.rs
deleted file mode 100644
index 1685f087d18..00000000000
--- a/library/std/src/sys_common/bytestring/tests.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use super::*;
-use crate::fmt::{Debug, Formatter, Result};
-
-#[test]
-fn smoke() {
-    struct Helper<'a>(&'a [u8]);
-
-    impl Debug for Helper<'_> {
-        fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-            debug_fmt_bytestring(self.0, f)
-        }
-    }
-
-    let input = b"\xF0hello,\tworld";
-    let expected = r#""\xF0hello,\tworld""#;
-    let output = format!("{:?}", Helper(input));
-
-    assert!(output == expected);
-}
diff --git a/library/std/src/sys_common/io.rs b/library/std/src/sys_common/io.rs
index 7c1d98a5abd..ea9108f1713 100644
--- a/library/std/src/sys_common/io.rs
+++ b/library/std/src/sys_common/io.rs
@@ -1,4 +1,6 @@
-pub const DEFAULT_BUF_SIZE: usize = 8 * 1024;
+// Bare metal platforms usually have very small amounts of RAM
+// (in the order of hundreds of KB)
+pub const DEFAULT_BUF_SIZE: usize = if cfg!(target_os = "espidf") { 512 } else { 8 * 1024 };
 
 #[cfg(test)]
 #[allow(dead_code)] // not used on emscripten
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 1a9caa22c92..894440564b7 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -21,16 +21,11 @@
 mod tests;
 
 pub mod backtrace;
-pub mod bytestring;
 pub mod condvar;
 pub mod fs;
 pub mod io;
 pub mod memchr;
 pub mod mutex;
-// `doc` is required because `sys/mod.rs` imports `unix/ext/mod.rs` on Windows
-// when generating documentation.
-#[cfg(any(doc, not(windows)))]
-pub mod os_str_bytes;
 pub mod process;
 pub mod remutex;
 #[macro_use]
diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys_common/process.rs
index fe89b11043c..38007d5c414 100644
--- a/library/std/src/sys_common/process.rs
+++ b/library/std/src/sys_common/process.rs
@@ -65,16 +65,18 @@ impl CommandEnv {
 
     // The following functions build up changes
     pub fn set(&mut self, key: &OsStr, value: &OsStr) {
+        let key = EnvKey::from(key);
         self.maybe_saw_path(&key);
-        self.vars.insert(key.to_owned().into(), Some(value.to_owned()));
+        self.vars.insert(key, Some(value.to_owned()));
     }
 
     pub fn remove(&mut self, key: &OsStr) {
+        let key = EnvKey::from(key);
         self.maybe_saw_path(&key);
         if self.clear {
-            self.vars.remove(key);
+            self.vars.remove(&key);
         } else {
-            self.vars.insert(key.to_owned().into(), None);
+            self.vars.insert(key, None);
         }
     }
 
@@ -87,7 +89,7 @@ impl CommandEnv {
         self.saw_path || self.clear
     }
 
-    fn maybe_saw_path(&mut self, key: &OsStr) {
+    fn maybe_saw_path(&mut self, key: &EnvKey) {
         if !self.saw_path && key == "PATH" {
             self.saw_path = true;
         }
diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs
index 3705d641a1b..07ec20f4dc6 100644
--- a/library/std/src/sys_common/rwlock.rs
+++ b/library/std/src/sys_common/rwlock.rs
@@ -1,63 +1,112 @@
 use crate::sys::rwlock as imp;
 
+/// An OS-based reader-writer lock, meant for use in static variables.
+///
+/// This rwlock does not implement poisoning.
+///
+/// This rwlock has a const constructor ([`StaticRWLock::new`]), does not
+/// implement `Drop` to cleanup resources.
+pub struct StaticRWLock(imp::RWLock);
+
+impl StaticRWLock {
+    /// Creates a new rwlock for use.
+    pub const fn new() -> Self {
+        Self(imp::RWLock::new())
+    }
+
+    /// Acquires shared access to the underlying lock, blocking the current
+    /// thread to do so.
+    ///
+    /// The lock is automatically unlocked when the returned guard is dropped.
+    #[inline]
+    pub fn read(&'static self) -> StaticRWLockReadGuard {
+        unsafe { self.0.read() };
+        StaticRWLockReadGuard(&self.0)
+    }
+
+    /// Acquires write access to the underlying lock, blocking the current thread
+    /// to do so.
+    ///
+    /// The lock is automatically unlocked when the returned guard is dropped.
+    #[inline]
+    pub fn write(&'static self) -> StaticRWLockWriteGuard {
+        unsafe { self.0.write() };
+        StaticRWLockWriteGuard(&self.0)
+    }
+}
+
+#[must_use]
+pub struct StaticRWLockReadGuard(&'static imp::RWLock);
+
+impl Drop for StaticRWLockReadGuard {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.0.read_unlock();
+        }
+    }
+}
+
+#[must_use]
+pub struct StaticRWLockWriteGuard(&'static imp::RWLock);
+
+impl Drop for StaticRWLockWriteGuard {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.0.write_unlock();
+        }
+    }
+}
+
 /// An OS-based reader-writer lock.
 ///
-/// This structure is entirely unsafe and serves as the lowest layer of a
-/// cross-platform binding of system rwlocks. It is recommended to use the
-/// safer types at the top level of this crate instead of this type.
-pub struct RWLock(imp::RWLock);
+/// This rwlock does *not* have a const constructor, cleans up its resources in
+/// its `Drop` implementation and may safely be moved (when not borrowed).
+///
+/// This rwlock does not implement poisoning.
+///
+/// This is either a wrapper around `Box<imp::RWLock>` or `imp::RWLock`,
+/// depending on the platform. It is boxed on platforms where `imp::RWLock` may
+/// not be moved.
+pub struct MovableRWLock(imp::MovableRWLock);
 
-impl RWLock {
+impl MovableRWLock {
     /// Creates a new reader-writer lock for use.
-    ///
-    /// Behavior is undefined if the reader-writer lock is moved after it is
-    /// first used with any of the functions below.
-    pub const fn new() -> RWLock {
-        RWLock(imp::RWLock::new())
+    pub fn new() -> Self {
+        Self(imp::MovableRWLock::from(imp::RWLock::new()))
     }
 
     /// Acquires shared access to the underlying lock, blocking the current
     /// thread to do so.
-    ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
     #[inline]
-    pub unsafe fn read(&self) {
-        self.0.read()
+    pub fn read(&self) {
+        unsafe { self.0.read() }
     }
 
     /// Attempts to acquire shared access to this lock, returning whether it
     /// succeeded or not.
     ///
     /// This function does not block the current thread.
-    ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
     #[inline]
-    pub unsafe fn try_read(&self) -> bool {
-        self.0.try_read()
+    pub fn try_read(&self) -> bool {
+        unsafe { self.0.try_read() }
     }
 
     /// Acquires write access to the underlying lock, blocking the current thread
     /// to do so.
-    ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
     #[inline]
-    pub unsafe fn write(&self) {
-        self.0.write()
+    pub fn write(&self) {
+        unsafe { self.0.write() }
     }
 
     /// Attempts to acquire exclusive access to this lock, returning whether it
     /// succeeded or not.
     ///
     /// This function does not block the current thread.
-    ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
     #[inline]
-    pub unsafe fn try_write(&self) -> bool {
-        self.0.try_write()
+    pub fn try_write(&self) -> bool {
+        unsafe { self.0.try_write() }
     }
 
     /// Unlocks previously acquired shared access to this lock.
@@ -76,13 +125,10 @@ impl RWLock {
     pub unsafe fn write_unlock(&self) {
         self.0.write_unlock()
     }
+}
 
-    /// Destroys OS-related resources with this RWLock.
-    ///
-    /// Behavior is undefined if there are any currently active users of this
-    /// lock.
-    #[inline]
-    pub unsafe fn destroy(&self) {
-        self.0.destroy()
+impl Drop for MovableRWLock {
+    fn drop(&mut self) {
+        unsafe { self.0.destroy() };
     }
 }
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index 7d4b0d52831..1bd3cfd2200 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -853,10 +853,11 @@ impl<'a> Iterator for EncodeWide<'a> {
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         let (low, high) = self.code_points.size_hint();
+        let ext = (self.extra != 0) as usize;
         // every code point gets either one u16 or two u16,
         // so this iterator is between 1 or 2 times as
         // long as the underlying iterator.
-        (low, high.and_then(|n| n.checked_mul(2)))
+        (low + ext, high.and_then(|n| n.checked_mul(2)).and_then(|n| n.checked_add(ext)))
     }
 }
 
diff --git a/library/std/src/sys_common/wtf8/tests.rs b/library/std/src/sys_common/wtf8/tests.rs
index 385e01f92fa..1bafbaa6939 100644
--- a/library/std/src/sys_common/wtf8/tests.rs
+++ b/library/std/src/sys_common/wtf8/tests.rs
@@ -301,7 +301,7 @@ fn wtf8_slice() {
 #[test]
 #[should_panic]
 fn wtf8_slice_not_code_point_boundary() {
-    &Wtf8::from_str("aé 💩")[2..4];
+    let _ = &Wtf8::from_str("aé 💩")[2..4];
 }
 
 #[test]
@@ -312,7 +312,7 @@ fn wtf8_slice_from() {
 #[test]
 #[should_panic]
 fn wtf8_slice_from_not_code_point_boundary() {
-    &Wtf8::from_str("aé 💩")[2..];
+    let _ = &Wtf8::from_str("aé 💩")[2..];
 }
 
 #[test]
@@ -323,7 +323,7 @@ fn wtf8_slice_to() {
 #[test]
 #[should_panic]
 fn wtf8_slice_to_not_code_point_boundary() {
-    &Wtf8::from_str("aé 💩")[5..];
+    let _ = &Wtf8::from_str("aé 💩")[5..];
 }
 
 #[test]
@@ -395,3 +395,15 @@ fn wtf8_encode_wide() {
         vec![0x61, 0xE9, 0x20, 0xD83D, 0xD83D, 0xDCA9]
     );
 }
+
+#[test]
+fn wtf8_encode_wide_size_hint() {
+    let string = Wtf8Buf::from_str("\u{12345}");
+    let mut iter = string.encode_wide();
+    assert_eq!((1, Some(8)), iter.size_hint());
+    iter.next().unwrap();
+    assert_eq!((1, Some(1)), iter.size_hint());
+    iter.next().unwrap();
+    assert_eq!((0, Some(0)), iter.size_hint());
+    assert!(iter.next().is_none());
+}
diff --git a/library/std/src/thread/available_concurrency.rs b/library/std/src/thread/available_concurrency.rs
deleted file mode 100644
index e8cdde88014..00000000000
--- a/library/std/src/thread/available_concurrency.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-use crate::io;
-use crate::num::NonZeroUsize;
-
-/// Returns the number of hardware threads available to the program.
-///
-/// This value should be considered only a hint.
-///
-/// # Platform-specific behavior
-///
-/// If interpreted as the number of actual hardware threads, it may undercount on
-/// Windows systems with more than 64 hardware threads. If interpreted as the
-/// available concurrency for that process, it may overcount on Windows systems
-/// when limited by a process wide affinity mask or job object limitations, and
-/// it may overcount on Linux systems when limited by a process wide affinity
-/// mask or affected by cgroups limits.
-///
-/// # Errors
-///
-/// This function will return an error in the following situations, but is not
-/// limited to just these cases:
-///
-/// - If the number of hardware threads is not known for the target platform.
-/// - The process lacks permissions to view the number of hardware threads
-///   available.
-///
-/// # Examples
-///
-/// ```
-/// # #![allow(dead_code)]
-/// #![feature(available_concurrency)]
-/// use std::thread;
-///
-/// let count = thread::available_concurrency().map(|n| n.get()).unwrap_or(1);
-/// ```
-#[unstable(feature = "available_concurrency", issue = "74479")]
-pub fn available_concurrency() -> io::Result<NonZeroUsize> {
-    available_concurrency_internal()
-}
-
-cfg_if::cfg_if! {
-    if #[cfg(windows)] {
-        #[allow(nonstandard_style)]
-        fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
-            #[repr(C)]
-            struct SYSTEM_INFO {
-                wProcessorArchitecture: u16,
-                wReserved: u16,
-                dwPageSize: u32,
-                lpMinimumApplicationAddress: *mut u8,
-                lpMaximumApplicationAddress: *mut u8,
-                dwActiveProcessorMask: *mut u8,
-                dwNumberOfProcessors: u32,
-                dwProcessorType: u32,
-                dwAllocationGranularity: u32,
-                wProcessorLevel: u16,
-                wProcessorRevision: u16,
-            }
-            extern "system" {
-                fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32;
-            }
-            let res = unsafe {
-                let mut sysinfo = crate::mem::zeroed();
-                GetSystemInfo(&mut sysinfo);
-                sysinfo.dwNumberOfProcessors as usize
-            };
-            match res {
-                0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")),
-                cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }),
-            }
-        }
-    } else if #[cfg(any(
-        target_os = "android",
-        target_os = "emscripten",
-        target_os = "fuchsia",
-        target_os = "ios",
-        target_os = "linux",
-        target_os = "macos",
-        target_os = "solaris",
-        target_os = "illumos",
-    ))] {
-        fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
-            match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
-                -1 => Err(io::Error::last_os_error()),
-                0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")),
-                cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }),
-            }
-        }
-    } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] {
-        fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
-            use crate::ptr;
-
-            let mut cpus: libc::c_uint = 0;
-            let mut cpus_size = crate::mem::size_of_val(&cpus);
-
-            unsafe {
-                cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
-            }
-
-            // Fallback approach in case of errors or no hardware threads.
-            if cpus < 1 {
-                let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
-                let res = unsafe {
-                    libc::sysctl(
-                        mib.as_mut_ptr(),
-                        2,
-                        &mut cpus as *mut _ as *mut _,
-                        &mut cpus_size as *mut _ as *mut _,
-                        ptr::null_mut(),
-                        0,
-                    )
-                };
-
-                // Handle errors if any.
-                if res == -1 {
-                    return Err(io::Error::last_os_error());
-                } else if cpus == 0 {
-                    return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
-                }
-            }
-            Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
-        }
-    } else if #[cfg(target_os = "openbsd")] {
-        fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
-            use crate::ptr;
-
-            let mut cpus: libc::c_uint = 0;
-            let mut cpus_size = crate::mem::size_of_val(&cpus);
-            let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
-
-            let res = unsafe {
-                libc::sysctl(
-                    mib.as_mut_ptr(),
-                    2,
-                    &mut cpus as *mut _ as *mut _,
-                    &mut cpus_size as *mut _ as *mut _,
-                    ptr::null_mut(),
-                    0,
-                )
-            };
-
-            // Handle errors if any.
-            if res == -1 {
-                return Err(io::Error::last_os_error());
-            } else if cpus == 0 {
-                return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"));
-            }
-
-            Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) })
-        }
-    } else {
-        // FIXME: implement on vxWorks, Redox, HermitCore, Haiku, l4re
-        fn available_concurrency_internal() -> io::Result<NonZeroUsize> {
-            Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform"))
-        }
-    }
-}
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index e62f4440b36..c53290ec0c7 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -324,10 +324,9 @@ macro_rules! __thread_local_inner {
 
 /// An error returned by [`LocalKey::try_with`](struct.LocalKey.html#method.try_with).
 #[stable(feature = "thread_local_try_with", since = "1.26.0")]
+#[non_exhaustive]
 #[derive(Clone, Copy, Eq, PartialEq)]
-pub struct AccessError {
-    _private: (),
-}
+pub struct AccessError;
 
 #[stable(feature = "thread_local_try_with", since = "1.26.0")]
 impl fmt::Debug for AccessError {
@@ -396,7 +395,7 @@ impl<T: 'static> LocalKey<T> {
         F: FnOnce(&T) -> R,
     {
         unsafe {
-            let thread_local = (self.inner)().ok_or(AccessError { _private: () })?;
+            let thread_local = (self.inner)().ok_or(AccessError)?;
             Ok(f(thread_local))
         }
     }
diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs
index f33d6129619..1df1ca758c0 100644
--- a/library/std/src/thread/local/tests.rs
+++ b/library/std/src/thread/local/tests.rs
@@ -297,7 +297,7 @@ fn join_orders_after_tls_destructors() {
             .unwrap();
 
         loop {
-            match SYNC_STATE.compare_exchange_weak(
+            match SYNC_STATE.compare_exchange(
                 THREAD1_WAITING,
                 MAIN_THREAD_RENDEZVOUS,
                 Ordering::SeqCst,
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 30d8c2a1b6f..f44df845bf4 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -28,7 +28,7 @@
 //! When the main thread of a Rust program terminates, the entire program shuts
 //! down, even if other threads are still running. However, this module provides
 //! convenient facilities for automatically waiting for the termination of a
-//! child thread (i.e., join).
+//! thread (i.e., join).
 //!
 //! ## Spawning a thread
 //!
@@ -42,38 +42,43 @@
 //! });
 //! ```
 //!
-//! In this example, the spawned thread is "detached" from the current
-//! thread. This means that it can outlive its parent (the thread that spawned
-//! it), unless this parent is the main thread.
+//! In this example, the spawned thread is "detached," which means that there is
+//! no way for the program to learn when the spawned thread completes or otherwise
+//! terminates.
 //!
-//! The parent thread can also wait on the completion of the child
-//! thread; a call to [`spawn`] produces a [`JoinHandle`], which provides
-//! a `join` method for waiting:
+//! To learn when a thread completes, it is necessary to capture the [`JoinHandle`]
+//! object that is returned by the call to [`spawn`], which provides
+//! a `join` method that allows the caller to wait for the completion of the
+//! spawned thread:
 //!
 //! ```rust
 //! use std::thread;
 //!
-//! let child = thread::spawn(move || {
+//! let thread_join_handle = thread::spawn(move || {
 //!     // some work here
 //! });
 //! // some work here
-//! let res = child.join();
+//! let res = thread_join_handle.join();
 //! ```
 //!
 //! The [`join`] method returns a [`thread::Result`] containing [`Ok`] of the final
-//! value produced by the child thread, or [`Err`] of the value given to
-//! a call to [`panic!`] if the child panicked.
+//! value produced by the spawned thread, or [`Err`] of the value given to
+//! a call to [`panic!`] if the thread panicked.
+//!
+//! Note that there is no parent/child relationship between a thread that spawns a
+//! new thread and the thread being spawned.  In particular, the spawned thread may or
+//! may not outlive the spawning thread, unless the spawning thread is the main thread.
 //!
 //! ## Configuring threads
 //!
 //! A new thread can be configured before it is spawned via the [`Builder`] type,
-//! which currently allows you to set the name and stack size for the child thread:
+//! which currently allows you to set the name and stack size for the thread:
 //!
 //! ```rust
 //! # #![allow(unused_must_use)]
 //! use std::thread;
 //!
-//! thread::Builder::new().name("child1".to_string()).spawn(move || {
+//! thread::Builder::new().name("thread1".to_string()).spawn(move || {
 //!     println!("Hello, world!");
 //! });
 //! ```
@@ -155,6 +160,7 @@ use crate::fmt;
 use crate::io;
 use crate::mem;
 use crate::num::NonZeroU64;
+use crate::num::NonZeroUsize;
 use crate::panic;
 use crate::panicking;
 use crate::str;
@@ -174,15 +180,9 @@ use crate::time::Duration;
 #[macro_use]
 mod local;
 
-#[unstable(feature = "available_concurrency", issue = "74479")]
-mod available_concurrency;
-
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::local::{AccessError, LocalKey};
 
-#[unstable(feature = "available_concurrency", issue = "74479")]
-pub use available_concurrency::available_concurrency;
-
 // The types used by the thread_local! macro to access TLS keys. Note that there
 // are two types, the "OS" type and the "fast" type. The OS thread local key
 // type is accessed via platform-specific API calls and is slow, while the fast
@@ -349,7 +349,7 @@ impl Builder {
     /// The spawned thread may outlive the caller (unless the caller thread
     /// is the main thread; the whole process is terminated when the main
     /// thread finishes). The join handle can be used to block on
-    /// termination of the child thread, including recovering its panics.
+    /// termination of the spawned thread, including recovering its panics.
     ///
     /// For a more complete documentation see [`thread::spawn`][`spawn`].
     ///
@@ -394,7 +394,7 @@ impl Builder {
     /// The spawned thread may outlive the caller (unless the caller thread
     /// is the main thread; the whole process is terminated when the main
     /// thread finishes). The join handle can be used to block on
-    /// termination of the child thread, including recovering its panics.
+    /// termination of the spawned thread, including recovering its panics.
     ///
     /// This method is identical to [`thread::Builder::spawn`][`Builder::spawn`],
     /// except for the relaxed lifetime bounds, which render it unsafe.
@@ -521,15 +521,16 @@ impl Builder {
 
 /// Spawns a new thread, returning a [`JoinHandle`] for it.
 ///
-/// The join handle will implicitly *detach* the child thread upon being
-/// dropped. In this case, the child thread may outlive the parent (unless
-/// the parent thread is the main thread; the whole process is terminated when
-/// the main thread finishes). Additionally, the join handle provides a [`join`]
-/// method that can be used to join the child thread. If the child thread
-/// panics, [`join`] will return an [`Err`] containing the argument given to
-/// [`panic!`].
+/// The join handle provides a [`join`] method that can be used to join the spawned
+/// thread. If the spawned thread panics, [`join`] will return an [`Err`] containing
+/// the argument given to [`panic!`].
+///
+/// If the join handle is dropped, the spawned thread will implicitly be *detached*.
+/// In this case, the spawned thread may no longer be joined.
+/// (It is the responsibility of the program to either eventually join threads it
+/// creates or detach them; otherwise, a resource leak will result.)
 ///
-/// This will create a thread using default parameters of [`Builder`], if you
+/// This call will create a thread using default parameters of [`Builder`], if you
 /// want to specify the stack size or the name of the thread, use this API
 /// instead.
 ///
@@ -538,8 +539,8 @@ impl Builder {
 ///
 /// - The `'static` constraint means that the closure and its return value
 ///   must have a lifetime of the whole program execution. The reason for this
-///   is that threads can `detach` and outlive the lifetime they have been
-///   created in.
+///   is that threads can outlive the lifetime they have been created in.
+///
 ///   Indeed if the thread, and by extension its return value, can outlive their
 ///   caller, we need to make sure that they will be valid afterwards, and since
 ///   we *can't* know when it will return we need to have them valid as long as
@@ -656,22 +657,23 @@ pub fn current() -> Thread {
 
 /// Cooperatively gives up a timeslice to the OS scheduler.
 ///
-/// This is used when the programmer knows that the thread will have nothing
-/// to do for some time, and thus avoid wasting computing time.
+/// This calls the underlying OS scheduler's yield primitive, signaling
+/// that the calling thread is willing to give up its remaining timeslice
+/// so that the OS may schedule other threads on the CPU.
 ///
-/// For example when polling on a resource, it is common to check that it is
-/// available, and if not to yield in order to avoid busy waiting.
+/// A drawback of yielding in a loop is that if the OS does not have any
+/// other ready threads to run on the current CPU, the thread will effectively
+/// busy-wait, which wastes CPU time and energy.
 ///
-/// Thus the pattern of `yield`ing after a failed poll is rather common when
-/// implementing low-level shared resources or synchronization primitives.
+/// Therefore, when waiting for events of interest, a programmer's first
+/// choice should be to use synchronization devices such as [`channel`]s,
+/// [`Condvar`]s, [`Mutex`]es or [`join`] since these primitives are
+/// implemented in a blocking manner, giving up the CPU until the event
+/// of interest has occurred which avoids repeated yielding.
 ///
-/// However programmers will usually prefer to use [`channel`]s, [`Condvar`]s,
-/// [`Mutex`]es or [`join`] for their synchronization routines, as they avoid
-/// thinking about thread scheduling.
-///
-/// Note that [`channel`]s for example are implemented using this primitive.
-/// Indeed when you call `send` or `recv`, which are blocking, they will yield
-/// if the channel is not available.
+/// `yield_now` should thus be used only rarely, mostly in situations where
+/// repeated polling is required because there is no other suitable way to
+/// learn when an event of interest has occurred.
 ///
 /// # Examples
 ///
@@ -910,7 +912,7 @@ pub fn park() {
 /// The semantics of this function are equivalent to [`park`] except
 /// that the thread will be blocked for roughly no longer than `dur`. This
 /// method should not be used for precise timing due to anomalies such as
-/// preemption or platform differences that may not cause the maximum
+/// preemption or platform differences that might not cause the maximum
 /// amount of time waited to be precisely `ms` long.
 ///
 /// See the [park documentation][`park`] for more detail.
@@ -926,7 +928,7 @@ pub fn park_timeout_ms(ms: u32) {
 /// The semantics of this function are equivalent to [`park`][park] except
 /// that the thread will be blocked for roughly no longer than `dur`. This
 /// method should not be used for precise timing due to anomalies such as
-/// preemption or platform differences that may not cause the maximum
+/// preemption or platform differences that might not cause the maximum
 /// amount of time waited to be precisely `dur` long.
 ///
 /// See the [park documentation][park] for more details.
@@ -1003,11 +1005,12 @@ impl ThreadId {
         static mut COUNTER: u64 = 1;
 
         unsafe {
-            let _guard = GUARD.lock();
+            let guard = GUARD.lock();
 
             // If we somehow use up all our bits, panic so that we're not
             // covering up subtle bugs of IDs being reused.
             if COUNTER == u64::MAX {
+                drop(guard); // in case the panic handler ends up calling `ThreadId::new()`, avoid reentrant lock acquire.
                 panic!("failed to generate unique thread ID: bitspace exhausted");
             }
 
@@ -1239,10 +1242,10 @@ impl fmt::Debug for Thread {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = crate::result::Result<T, Box<dyn Any + Send + 'static>>;
 
-// This packet is used to communicate the return value between the child thread
-// and the parent thread. Memory is shared through the `Arc` within and there's
+// This packet is used to communicate the return value between the spawned thread
+// and the rest of the program. Memory is shared through the `Arc` within and there's
 // no need for a mutex here because synchronization happens with `join()` (the
-// parent thread never reads this packet until the child has exited).
+// caller will never read this packet until the thread has exited).
 //
 // This packet itself is then stored into a `JoinInner` which in turns is placed
 // in `JoinHandle` and `JoinGuard`. Due to the usage of `UnsafeCell` we need to
@@ -1306,7 +1309,7 @@ impl<T> JoinInner<T> {
 /// }).unwrap();
 /// ```
 ///
-/// Child being detached and outliving its parent:
+/// A thread being detached and outliving the thread that spawned it:
 ///
 /// ```no_run
 /// use std::thread;
@@ -1364,12 +1367,15 @@ impl<T> JoinHandle<T> {
 
     /// Waits for the associated thread to finish.
     ///
+    /// This function will return immediately if the associated thread has already finished.
+    ///
     /// In terms of [atomic memory orderings],  the completion of the associated
     /// thread synchronizes with this function returning. In other words, all
-    /// operations performed by that thread are ordered before all
+    /// operations performed by that thread [happen
+    /// before](https://doc.rust-lang.org/nomicon/atomics.html#data-accesses) all
     /// operations that happen after `join` returns.
     ///
-    /// If the child thread panics, [`Err`] is returned with the parameter given
+    /// If the associated thread panics, [`Err`] is returned with the parameter given
     /// to [`panic!`].
     ///
     /// [`Err`]: crate::result::Result::Err
@@ -1422,3 +1428,39 @@ fn _assert_sync_and_send() {
     _assert_both::<JoinHandle<()>>();
     _assert_both::<Thread>();
 }
+
+/// Returns the number of hardware threads available to the program.
+///
+/// This value should be considered only a hint.
+///
+/// # Platform-specific behavior
+///
+/// If interpreted as the number of actual hardware threads, it may undercount on
+/// Windows systems with more than 64 hardware threads. If interpreted as the
+/// available concurrency for that process, it may overcount on Windows systems
+/// when limited by a process wide affinity mask or job object limitations, and
+/// it may overcount on Linux systems when limited by a process wide affinity
+/// mask or affected by cgroups limits.
+///
+/// # Errors
+///
+/// This function will return an error in the following situations, but is not
+/// limited to just these cases:
+///
+/// - If the number of hardware threads is not known for the target platform.
+/// - The process lacks permissions to view the number of hardware threads
+///   available.
+///
+/// # Examples
+///
+/// ```
+/// # #![allow(dead_code)]
+/// #![feature(available_concurrency)]
+/// use std::thread;
+///
+/// let count = thread::available_concurrency().map(|n| n.get()).unwrap_or(1);
+/// ```
+#[unstable(feature = "available_concurrency", issue = "74479")]
+pub fn available_concurrency() -> io::Result<NonZeroUsize> {
+    imp::available_concurrency()
+}
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index 899cf6841ee..6d70c7270d3 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -34,7 +34,7 @@ pub use core::time::Duration;
 /// benchmarks or timing how long an operation takes.
 ///
 /// Note, however, that instants are not guaranteed to be **steady**. In other
-/// words, each tick of the underlying clock may not be the same length (e.g.
+/// words, each tick of the underlying clock might not be the same length (e.g.
 /// some seconds may be longer than others). An instant may jump forwards or
 /// experience time dilation (slow down or speed up), but it will never go
 /// backwards.
@@ -168,7 +168,7 @@ pub struct Instant(time::Instant);
 ///
 /// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
 /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode
-/// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html
+/// [gettimeofday]: https://man7.org/linux/man-pages/man2/gettimeofday.2.html
 /// [clock_gettime (Realtime Clock)]: https://linux.die.net/man/3/clock_gettime
 /// [__wasi_clock_time_get (Realtime Clock)]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/docs.md#clock_time_get
 /// [GetSystemTimePreciseAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
@@ -485,7 +485,7 @@ impl SystemTime {
     ///
     /// This function may fail as the underlying system clock is susceptible to
     /// drift and updates (e.g., the system clock could go backwards), so this
-    /// function may not always succeed. If successful, [`Ok`]`(`[`Duration`]`)` is
+    /// function might not always succeed. If successful, [`Ok`]`(`[`Duration`]`)` is
     /// returned where the duration represents the amount of time elapsed from
     /// this time measurement to the current time.
     ///
diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs
index c7107b5d0a3..079f00a5753 100644
--- a/library/std/tests/run-time-detect.rs
+++ b/library/std/tests/run-time-detect.rs
@@ -16,22 +16,56 @@
 fn arm_linux() {
     println!("neon: {}", is_arm_feature_detected!("neon"));
     println!("pmull: {}", is_arm_feature_detected!("pmull"));
+    println!("crypto: {}", is_arm_feature_detected!("crypto"));
+    println!("crc: {}", is_arm_feature_detected!("crc"));
+    println!("aes: {}", is_arm_feature_detected!("aes"));
+    println!("sha2: {}", is_arm_feature_detected!("sha2"));
 }
 
 #[test]
 #[cfg(all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")))]
 fn aarch64_linux() {
-    println!("fp: {}", is_aarch64_feature_detected!("fp"));
-    println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
     println!("neon: {}", is_aarch64_feature_detected!("neon"));
     println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
+    println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
+    println!("fp: {}", is_aarch64_feature_detected!("fp"));
+    println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
     println!("sve: {}", is_aarch64_feature_detected!("sve"));
     println!("crc: {}", is_aarch64_feature_detected!("crc"));
     println!("lse: {}", is_aarch64_feature_detected!("lse"));
+    println!("lse2: {}", is_aarch64_feature_detected!("lse2"));
     println!("rdm: {}", is_aarch64_feature_detected!("rdm"));
     println!("rcpc: {}", is_aarch64_feature_detected!("rcpc"));
+    println!("rcpc2: {}", is_aarch64_feature_detected!("rcpc2"));
     println!("dotprod: {}", is_aarch64_feature_detected!("dotprod"));
     println!("tme: {}", is_aarch64_feature_detected!("tme"));
+    println!("fhm: {}", is_aarch64_feature_detected!("fhm"));
+    println!("dit: {}", is_aarch64_feature_detected!("dit"));
+    println!("flagm: {}", is_aarch64_feature_detected!("flagm"));
+    println!("ssbs: {}", is_aarch64_feature_detected!("ssbs"));
+    println!("sb: {}", is_aarch64_feature_detected!("sb"));
+    println!("pauth: {}", is_aarch64_feature_detected!("pauth"));
+    println!("dpb: {}", is_aarch64_feature_detected!("dpb"));
+    println!("dpb2: {}", is_aarch64_feature_detected!("dpb2"));
+    println!("sve2: {}", is_aarch64_feature_detected!("sve2"));
+    println!("sve2-aes: {}", is_aarch64_feature_detected!("sve2-aes"));
+    println!("sve2-sm4: {}", is_aarch64_feature_detected!("sve2-sm4"));
+    println!("sve2-sha3: {}", is_aarch64_feature_detected!("sve2-sha3"));
+    println!("sve2-bitperm: {}", is_aarch64_feature_detected!("sve2-bitperm"));
+    println!("frintts: {}", is_aarch64_feature_detected!("frintts"));
+    println!("i8mm: {}", is_aarch64_feature_detected!("i8mm"));
+    println!("f32mm: {}", is_aarch64_feature_detected!("f32mm"));
+    println!("f64mm: {}", is_aarch64_feature_detected!("f64mm"));
+    println!("bf16: {}", is_aarch64_feature_detected!("bf16"));
+    println!("rand: {}", is_aarch64_feature_detected!("rand"));
+    println!("bti: {}", is_aarch64_feature_detected!("bti"));
+    println!("mte: {}", is_aarch64_feature_detected!("mte"));
+    println!("jsconv: {}", is_aarch64_feature_detected!("jsconv"));
+    println!("fcma: {}", is_aarch64_feature_detected!("fcma"));
+    println!("aes: {}", is_aarch64_feature_detected!("aes"));
+    println!("sha2: {}", is_aarch64_feature_detected!("sha2"));
+    println!("sha3: {}", is_aarch64_feature_detected!("sha3"));
+    println!("sm4: {}", is_aarch64_feature_detected!("sm4"));
 }
 
 #[test]
diff --git a/library/stdarch b/library/stdarch
-Subproject 37d6e1886369ea0176356286dc7fbd42ee5aa79
+Subproject c158cfd38e20d855f5d6ca8a5a101eefb82604a
diff --git a/library/term/Cargo.toml b/library/term/Cargo.toml
deleted file mode 100644
index ddf85b5c5bc..00000000000
--- a/library/term/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "term"
-version = "0.0.0"
-edition = "2018"
-
-[dependencies]
-core = { path = "../core" }
-std = { path = "../std" }
diff --git a/library/term/src/lib.rs b/library/term/src/lib.rs
deleted file mode 100644
index 943b276a220..00000000000
--- a/library/term/src/lib.rs
+++ /dev/null
@@ -1,194 +0,0 @@
-//! Terminal formatting library.
-//!
-//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
-//! Terminal][ansi] to provide color printing, among other things. There are two
-//! implementations, the `TerminfoTerminal`, which uses control characters from
-//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
-//! API][win].
-//!
-//! # Examples
-//!
-//! ```no_run
-//! # #![feature(rustc_private)]
-//! extern crate term;
-//! use std::io::prelude::*;
-//!
-//! fn main() {
-//!     let mut t = term::stdout().unwrap();
-//!
-//!     t.fg(term::color::GREEN).unwrap();
-//!     write!(t, "hello, ").unwrap();
-//!
-//!     t.fg(term::color::RED).unwrap();
-//!     writeln!(t, "world!").unwrap();
-//!
-//!     assert!(t.reset().unwrap());
-//! }
-//! ```
-//!
-//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
-//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
-//! [ti]: https://en.wikipedia.org/wiki/Terminfo
-
-#![doc(html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))]
-#![deny(missing_docs)]
-#![cfg_attr(windows, feature(libc))]
-
-use std::io::prelude::*;
-use std::io::{self, Stderr, Stdout};
-
-pub use terminfo::TerminfoTerminal;
-#[cfg(windows)]
-pub use win::WinConsole;
-
-pub mod terminfo;
-
-#[cfg(windows)]
-mod win;
-
-/// Alias for stdout terminals.
-pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
-/// Alias for stderr terminals.
-pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
-    TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
-    TerminfoTerminal::new(io::stdout())
-        .map(|t| Box::new(t) as Box<StdoutTerminal>)
-        .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
-}
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
-    TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
-    TerminfoTerminal::new(io::stderr())
-        .map(|t| Box::new(t) as Box<StderrTerminal>)
-        .or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
-}
-
-/// Terminal color definitions
-#[allow(missing_docs)]
-pub mod color {
-    /// Number for a terminal color
-    pub type Color = u32;
-
-    pub const BLACK: Color = 0;
-    pub const RED: Color = 1;
-    pub const GREEN: Color = 2;
-    pub const YELLOW: Color = 3;
-    pub const BLUE: Color = 4;
-    pub const MAGENTA: Color = 5;
-    pub const CYAN: Color = 6;
-    pub const WHITE: Color = 7;
-
-    pub const BRIGHT_BLACK: Color = 8;
-    pub const BRIGHT_RED: Color = 9;
-    pub const BRIGHT_GREEN: Color = 10;
-    pub const BRIGHT_YELLOW: Color = 11;
-    pub const BRIGHT_BLUE: Color = 12;
-    pub const BRIGHT_MAGENTA: Color = 13;
-    pub const BRIGHT_CYAN: Color = 14;
-    pub const BRIGHT_WHITE: Color = 15;
-}
-
-/// Terminal attributes for use with term.attr().
-///
-/// Most attributes can only be turned on and must be turned off with term.reset().
-/// The ones that can be turned off explicitly take a boolean value.
-/// Color is also represented as an attribute for convenience.
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
-pub enum Attr {
-    /// Bold (or possibly bright) mode
-    Bold,
-    /// Dim mode, also called faint or half-bright. Often not supported
-    Dim,
-    /// Italics mode. Often not supported
-    Italic(bool),
-    /// Underline mode
-    Underline(bool),
-    /// Blink mode
-    Blink,
-    /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
-    Standout(bool),
-    /// Reverse mode, inverts the foreground and background colors
-    Reverse,
-    /// Secure mode, also called invis mode. Hides the printed text
-    Secure,
-    /// Convenience attribute to set the foreground color
-    ForegroundColor(color::Color),
-    /// Convenience attribute to set the background color
-    BackgroundColor(color::Color),
-}
-
-/// A terminal with similar capabilities to an ANSI Terminal
-/// (foreground/background colors etc).
-pub trait Terminal: Write {
-    /// The terminal's output writer type.
-    type Output: Write;
-
-    /// Sets the foreground color to the given color.
-    ///
-    /// If the color is a bright color, but the terminal only supports 8 colors,
-    /// the corresponding normal color will be used instead.
-    ///
-    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
-    /// if there was an I/O error.
-    fn fg(&mut self, color: color::Color) -> io::Result<bool>;
-
-    /// Sets the background color to the given color.
-    ///
-    /// If the color is a bright color, but the terminal only supports 8 colors,
-    /// the corresponding normal color will be used instead.
-    ///
-    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
-    /// if there was an I/O error.
-    fn bg(&mut self, color: color::Color) -> io::Result<bool>;
-
-    /// Sets the given terminal attribute, if supported. Returns `Ok(true)`
-    /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
-    /// there was an I/O error.
-    fn attr(&mut self, attr: Attr) -> io::Result<bool>;
-
-    /// Returns `true` if the given terminal attribute is supported.
-    fn supports_attr(&self, attr: Attr) -> bool;
-
-    /// Resets all terminal attributes and colors to their defaults.
-    ///
-    /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
-    /// was an I/O error.
-    ///
-    /// *Note: This does not flush.*
-    ///
-    /// That means the reset command may get buffered so, if you aren't planning on doing anything
-    /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
-    /// calling reset.
-    fn reset(&mut self) -> io::Result<bool>;
-
-    /// Gets an immutable reference to the stream inside
-    fn get_ref(&self) -> &Self::Output;
-
-    /// Gets a mutable reference to the stream inside
-    fn get_mut(&mut self) -> &mut Self::Output;
-
-    /// Returns the contained stream, destroying the `Terminal`
-    fn into_inner(self) -> Self::Output
-    where
-        Self: Sized;
-}
diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml
index 226557430df..80d6072e9b5 100644
--- a/library/test/Cargo.toml
+++ b/library/test/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "test"
 version = "0.0.0"
 edition = "2018"
@@ -10,7 +9,6 @@ crate-type = ["dylib", "rlib"]
 [dependencies]
 cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
-term = { path = "../term" }
 std = { path = "../std" }
 core = { path = "../core" }
 libc = { version = "0.2", default-features = false }
diff --git a/library/test/src/console.rs b/library/test/src/console.rs
index 9cfc7eaf4bc..54e30a1fcd0 100644
--- a/library/test/src/console.rs
+++ b/library/test/src/console.rs
@@ -13,7 +13,7 @@ use super::{
     formatters::{JsonFormatter, JunitFormatter, OutputFormatter, PrettyFormatter, TerseFormatter},
     helpers::{concurrency::get_concurrency, metrics::MetricMap},
     options::{Options, OutputFormat},
-    run_tests,
+    run_tests, term,
     test_result::TestResult,
     time::{TestExecTime, TestSuiteExecTime},
     types::{NamePadding, TestDesc, TestDescAndFn},
diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs
index ec66fc1219f..c4b0e1e5c23 100644
--- a/library/test/src/formatters/junit.rs
+++ b/library/test/src/formatters/junit.rs
@@ -79,7 +79,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                          name=\"{}\" time=\"{}\">",
                         class_name,
                         test_name,
-                        duration.as_secs()
+                        duration.as_secs_f64()
                     ))?;
                     self.write_message("<failure type=\"assert\"/>")?;
                     self.write_message("</testcase>")?;
@@ -91,7 +91,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                          name=\"{}\" time=\"{}\">",
                         class_name,
                         test_name,
-                        duration.as_secs()
+                        duration.as_secs_f64()
                     ))?;
                     self.write_message(&*format!("<failure message=\"{}\" type=\"assert\"/>", m))?;
                     self.write_message("</testcase>")?;
@@ -103,7 +103,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                          name=\"{}\" time=\"{}\">",
                         class_name,
                         test_name,
-                        duration.as_secs()
+                        duration.as_secs_f64()
                     ))?;
                     self.write_message("<failure type=\"timeout\"/>")?;
                     self.write_message("</testcase>")?;
@@ -123,7 +123,7 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
                          name=\"{}\" time=\"{}\"/>",
                         class_name,
                         test_name,
-                        duration.as_secs()
+                        duration.as_secs_f64()
                     ))?;
                 }
             }
diff --git a/library/test/src/formatters/pretty.rs b/library/test/src/formatters/pretty.rs
index e17fc08a9ae..9cad71e30bd 100644
--- a/library/test/src/formatters/pretty.rs
+++ b/library/test/src/formatters/pretty.rs
@@ -4,6 +4,7 @@ use super::OutputFormatter;
 use crate::{
     bench::fmt_bench_samples,
     console::{ConsoleTestState, OutputLocation},
+    term,
     test_result::TestResult,
     time,
     types::TestDesc,
diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs
index a2c223c494c..0c8215c5dac 100644
--- a/library/test/src/formatters/terse.rs
+++ b/library/test/src/formatters/terse.rs
@@ -4,6 +4,7 @@ use super::OutputFormatter;
 use crate::{
     bench::fmt_bench_samples,
     console::{ConsoleTestState, OutputLocation},
+    term,
     test_result::TestResult,
     time,
     types::NamePadding,
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 3da4d434f48..251f099f28a 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -20,7 +20,7 @@
 #![crate_name = "test"]
 #![unstable(feature = "test", issue = "50297")]
 #![doc(test(attr(deny(warnings))))]
-#![cfg_attr(unix, feature(libc))]
+#![feature(libc)]
 #![feature(rustc_private)]
 #![feature(nll)]
 #![feature(available_concurrency)]
@@ -80,6 +80,7 @@ mod formatters;
 mod helpers;
 mod options;
 pub mod stats;
+mod term;
 mod test_result;
 mod time;
 mod types;
diff --git a/library/test/src/stats.rs b/library/test/src/stats.rs
index 53f38894474..45fae9c76b4 100644
--- a/library/test/src/stats.rs
+++ b/library/test/src/stats.rs
@@ -19,7 +19,7 @@ pub trait Stats {
     /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric
     /// Predicates"][paper]
     ///
-    /// [paper]: http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps
+    /// [paper]: https://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps
     fn sum(&self) -> f64;
 
     /// Minimum value of the samples.
diff --git a/library/test/src/term.rs b/library/test/src/term.rs
new file mode 100644
index 00000000000..b256ab7b8f8
--- /dev/null
+++ b/library/test/src/term.rs
@@ -0,0 +1,85 @@
+//! Terminal formatting module.
+//!
+//! This module provides the `Terminal` trait, which abstracts over an [ANSI
+//! Terminal][ansi] to provide color printing, among other things. There are two
+//! implementations, the `TerminfoTerminal`, which uses control characters from
+//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
+//! API][win].
+//!
+//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
+//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
+//! [ti]: https://en.wikipedia.org/wiki/Terminfo
+
+#![deny(missing_docs)]
+
+use std::io::{self, prelude::*};
+
+pub(crate) use terminfo::TerminfoTerminal;
+#[cfg(windows)]
+pub(crate) use win::WinConsole;
+
+pub(crate) mod terminfo;
+
+#[cfg(windows)]
+mod win;
+
+/// Alias for stdout terminals.
+pub(crate) type StdoutTerminal = dyn Terminal + Send;
+
+#[cfg(not(windows))]
+/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
+/// opened.
+pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
+    TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
+}
+
+#[cfg(windows)]
+/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
+/// opened.
+pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
+    TerminfoTerminal::new(io::stdout())
+        .map(|t| Box::new(t) as Box<StdoutTerminal>)
+        .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
+}
+
+/// Terminal color definitions
+#[allow(missing_docs)]
+#[cfg_attr(not(windows), allow(dead_code))]
+pub(crate) mod color {
+    /// Number for a terminal color
+    pub(crate) type Color = u32;
+
+    pub(crate) const BLACK: Color = 0;
+    pub(crate) const RED: Color = 1;
+    pub(crate) const GREEN: Color = 2;
+    pub(crate) const YELLOW: Color = 3;
+    pub(crate) const BLUE: Color = 4;
+    pub(crate) const MAGENTA: Color = 5;
+    pub(crate) const CYAN: Color = 6;
+    pub(crate) const WHITE: Color = 7;
+}
+
+/// A terminal with similar capabilities to an ANSI Terminal
+/// (foreground/background colors etc).
+pub trait Terminal: Write {
+    /// Sets the foreground color to the given color.
+    ///
+    /// If the color is a bright color, but the terminal only supports 8 colors,
+    /// the corresponding normal color will be used instead.
+    ///
+    /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
+    /// if there was an I/O error.
+    fn fg(&mut self, color: color::Color) -> io::Result<bool>;
+
+    /// Resets all terminal attributes and colors to their defaults.
+    ///
+    /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
+    /// was an I/O error.
+    ///
+    /// *Note: This does not flush.*
+    ///
+    /// That means the reset command may get buffered so, if you aren't planning on doing anything
+    /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
+    /// calling reset.
+    fn reset(&mut self) -> io::Result<bool>;
+}
diff --git a/library/term/src/terminfo/mod.rs b/library/test/src/term/terminfo/mod.rs
index fec59aaa0c2..f4c5a05d1e2 100644
--- a/library/term/src/terminfo/mod.rs
+++ b/library/test/src/term/terminfo/mod.rs
@@ -8,9 +8,8 @@ use std::fs::File;
 use std::io::{self, prelude::*, BufReader};
 use std::path::Path;
 
-use crate::color;
-use crate::Attr;
-use crate::Terminal;
+use super::color;
+use super::Terminal;
 
 use parm::{expand, Param, Variables};
 use parser::compiled::{msys_terminfo, parse};
@@ -18,20 +17,20 @@ use searcher::get_dbpath_for_term;
 
 /// A parsed terminfo database entry.
 #[derive(Debug)]
-pub struct TermInfo {
+pub(crate) struct TermInfo {
     /// Names for the terminal
-    pub names: Vec<String>,
+    pub(crate) names: Vec<String>,
     /// Map of capability name to boolean value
-    pub bools: HashMap<String, bool>,
+    pub(crate) bools: HashMap<String, bool>,
     /// Map of capability name to numeric value
-    pub numbers: HashMap<String, u32>,
+    pub(crate) numbers: HashMap<String, u32>,
     /// Map of capability name to raw (unexpanded) string
-    pub strings: HashMap<String, Vec<u8>>,
+    pub(crate) strings: HashMap<String, Vec<u8>>,
 }
 
 /// A terminfo creation error.
 #[derive(Debug)]
-pub enum Error {
+pub(crate) enum Error {
     /// TermUnset Indicates that the environment doesn't include enough information to find
     /// the terminfo entry.
     TermUnset,
@@ -64,7 +63,7 @@ impl fmt::Display for Error {
 
 impl TermInfo {
     /// Creates a TermInfo based on current environment.
-    pub fn from_env() -> Result<TermInfo, Error> {
+    pub(crate) fn from_env() -> Result<TermInfo, Error> {
         let term = match env::var("TERM") {
             Ok(name) => TermInfo::from_name(&name),
             Err(..) => return Err(Error::TermUnset),
@@ -79,7 +78,7 @@ impl TermInfo {
     }
 
     /// Creates a TermInfo for the named terminal.
-    pub fn from_name(name: &str) -> Result<TermInfo, Error> {
+    pub(crate) fn from_name(name: &str) -> Result<TermInfo, Error> {
         get_dbpath_for_term(name)
             .ok_or_else(|| {
                 Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
@@ -88,7 +87,7 @@ impl TermInfo {
     }
 
     /// Parse the given TermInfo.
-    pub fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
+    pub(crate) fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
         Self::_from_path(path.as_ref())
     }
     // Keep the metadata small
@@ -99,43 +98,24 @@ impl TermInfo {
     }
 }
 
-pub mod searcher;
+pub(crate) mod searcher;
 
 /// TermInfo format parsing.
-pub mod parser {
+pub(crate) mod parser {
     //! ncurses-compatible compiled terminfo format parsing (term(5))
-    pub mod compiled;
-}
-pub mod parm;
-
-fn cap_for_attr(attr: Attr) -> &'static str {
-    match attr {
-        Attr::Bold => "bold",
-        Attr::Dim => "dim",
-        Attr::Italic(true) => "sitm",
-        Attr::Italic(false) => "ritm",
-        Attr::Underline(true) => "smul",
-        Attr::Underline(false) => "rmul",
-        Attr::Blink => "blink",
-        Attr::Standout(true) => "smso",
-        Attr::Standout(false) => "rmso",
-        Attr::Reverse => "rev",
-        Attr::Secure => "invis",
-        Attr::ForegroundColor(_) => "setaf",
-        Attr::BackgroundColor(_) => "setab",
-    }
+    pub(crate) mod compiled;
 }
+pub(crate) mod parm;
 
 /// A Terminal that knows how many colors it supports, with a reference to its
 /// parsed Terminfo database record.
-pub struct TerminfoTerminal<T> {
+pub(crate) struct TerminfoTerminal<T> {
     num_colors: u32,
     out: T,
     ti: TermInfo,
 }
 
 impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
-    type Output = T;
     fn fg(&mut self, color: color::Color) -> io::Result<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
@@ -144,32 +124,6 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
         Ok(false)
     }
 
-    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
-        let color = self.dim_if_necessary(color);
-        if self.num_colors > color {
-            return self.apply_cap("setab", &[Param::Number(color as i32)]);
-        }
-        Ok(false)
-    }
-
-    fn attr(&mut self, attr: Attr) -> io::Result<bool> {
-        match attr {
-            Attr::ForegroundColor(c) => self.fg(c),
-            Attr::BackgroundColor(c) => self.bg(c),
-            _ => self.apply_cap(cap_for_attr(attr), &[]),
-        }
-    }
-
-    fn supports_attr(&self, attr: Attr) -> bool {
-        match attr {
-            Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => self.num_colors > 0,
-            _ => {
-                let cap = cap_for_attr(attr);
-                self.ti.strings.get(cap).is_some()
-            }
-        }
-    }
-
     fn reset(&mut self) -> io::Result<bool> {
         // are there any terminals that have color/attrs and not sgr0?
         // Try falling back to sgr, then op
@@ -182,26 +136,11 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
         };
         self.out.write_all(&cmd).and(Ok(true))
     }
-
-    fn get_ref(&self) -> &T {
-        &self.out
-    }
-
-    fn get_mut(&mut self) -> &mut T {
-        &mut self.out
-    }
-
-    fn into_inner(self) -> T
-    where
-        Self: Sized,
-    {
-        self.out
-    }
 }
 
 impl<T: Write + Send> TerminfoTerminal<T> {
     /// Creates a new TerminfoTerminal with the given TermInfo and Write.
-    pub fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
+    pub(crate) fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
         let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab")
         {
             terminfo.numbers.get("colors").map_or(0, |&n| n)
@@ -215,7 +154,7 @@ impl<T: Write + Send> TerminfoTerminal<T> {
     /// Creates a new TerminfoTerminal for the current environment with the given Write.
     ///
     /// Returns `None` when the terminfo cannot be found or parsed.
-    pub fn new(out: T) -> Option<TerminfoTerminal<T>> {
+    pub(crate) fn new(out: T) -> Option<TerminfoTerminal<T>> {
         TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
     }
 
diff --git a/library/term/src/terminfo/parm.rs b/library/test/src/term/terminfo/parm.rs
index 2e4e917891e..0d37eb7359d 100644
--- a/library/term/src/terminfo/parm.rs
+++ b/library/test/src/term/terminfo/parm.rs
@@ -35,13 +35,12 @@ enum FormatState {
 /// Types of parameters a capability can use
 #[allow(missing_docs)]
 #[derive(Clone)]
-pub enum Param {
-    Words(String),
+pub(crate) enum Param {
     Number(i32),
 }
 
 /// Container for static and dynamic variable arrays
-pub struct Variables {
+pub(crate) struct Variables {
     /// Static variables A-Z
     sta_va: [Param; 26],
     /// Dynamic variables a-z
@@ -50,7 +49,7 @@ pub struct Variables {
 
 impl Variables {
     /// Returns a new zero-initialized Variables
-    pub fn new() -> Variables {
+    pub(crate) fn new() -> Variables {
         Variables {
             sta_va: [
                 Number(0),
@@ -121,7 +120,11 @@ impl Variables {
 ///
 /// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
 /// multiple capabilities for the same terminal.
-pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<u8>, String> {
+pub(crate) fn expand(
+    cap: &[u8],
+    params: &[Param],
+    vars: &mut Variables,
+) -> Result<Vec<u8>, String> {
     let mut state = Nothing;
 
     // expanded cap will only rarely be larger than the cap itself
@@ -168,7 +171,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                             Some(Number(0)) => output.push(128u8),
                             // Don't check bounds. ncurses just casts and truncates.
                             Some(Number(c)) => output.push(c as u8),
-                            Some(_) => return Err("a non-char was used with %c".to_string()),
                             None => return Err("stack is empty".to_string()),
                         }
                     }
@@ -178,7 +180,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                     '\'' => state = CharConstant,
                     '{' => state = IntConstant(0),
                     'l' => match stack.pop() {
-                        Some(Words(s)) => stack.push(Number(s.len() as i32)),
                         Some(_) => return Err("a non-str was used with %l".to_string()),
                         None => return Err("stack is empty".to_string()),
                     },
@@ -195,9 +196,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                                 'm' => x % y,
                                 _ => unreachable!("All cases handled"),
                             })),
-                            (Some(_), Some(_)) => {
-                                return Err(format!("non-numbers on stack with {}", cur));
-                            }
                             _ => return Err("stack is empty".to_string()),
                         }
                     }
@@ -216,9 +214,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                                 0
                             },
                         )),
-                        (Some(_), Some(_)) => {
-                            return Err(format!("non-numbers on stack with {}", cur));
-                        }
                         _ => return Err("stack is empty".to_string()),
                     },
                     '!' | '~' => match stack.pop() {
@@ -228,7 +223,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                             '~' => !x,
                             _ => unreachable!(),
                         })),
-                        Some(_) => return Err(format!("non-numbers on stack with {}", cur)),
                         None => return Err("stack is empty".to_string()),
                     },
                     'i' => match (&mparams[0], &mparams[1]) {
@@ -236,7 +230,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                             mparams[0] = Number(x + 1);
                             mparams[1] = Number(y + 1);
                         }
-                        _ => return Err("first two params not numbers with %i".to_string()),
                     },
 
                     // printf-style support for %doxXs
@@ -271,7 +264,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
                     't' => match stack.pop() {
                         Some(Number(0)) => state = SeekIfElse(0),
                         Some(Number(_)) => (),
-                        Some(_) => return Err("non-number on stack with conditional".to_string()),
                         None => return Err("stack is empty".to_string()),
                     },
                     'e' => state = SeekIfEnd(0),
@@ -480,15 +472,6 @@ impl FormatOp {
             _ => panic!("bad FormatOp char"),
         }
     }
-    fn to_char(self) -> char {
-        match self {
-            FormatOp::Digit => 'd',
-            FormatOp::Octal => 'o',
-            FormatOp::LowerHex => 'x',
-            FormatOp::UpperHex => 'X',
-            FormatOp::String => 's',
-        }
-    }
 }
 
 fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
@@ -533,16 +516,6 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
             }
             .into_bytes()
         }
-        Words(s) => match op {
-            FormatOp::String => {
-                let mut s = s.into_bytes();
-                if flags.precision > 0 && flags.precision < s.len() {
-                    s.truncate(flags.precision);
-                }
-                s
-            }
-            _ => return Err(format!("non-string on stack with %{}", op.to_char())),
-        },
     };
     if flags.width > s.len() {
         let n = flags.width - s.len();
diff --git a/library/term/src/terminfo/parm/tests.rs b/library/test/src/term/terminfo/parm/tests.rs
index 1cc0967c8f4..256d1aaf446 100644
--- a/library/term/src/terminfo/parm/tests.rs
+++ b/library/test/src/term/terminfo/parm/tests.rs
@@ -51,7 +51,10 @@ fn test_param_stack_failure_conditions() {
     for &cap in caps.iter() {
         let res = get_res("", cap, &[], vars);
         assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap);
-        let p = if cap == "%s" || cap == "%l" { Words("foo".to_string()) } else { Number(97) };
+        if cap == "%s" || cap == "%l" {
+            continue;
+        }
+        let p = Number(97);
         let res = get_res("%p1", cap, &[p], vars);
         assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err());
     }
@@ -109,23 +112,6 @@ fn test_conditionals() {
 fn test_format() {
     let mut varstruct = Variables::new();
     let vars = &mut varstruct;
-    assert_eq!(
-        expand(
-            b"%p1%s%p2%2s%p3%2s%p4%.2s",
-            &[
-                Words("foo".to_string()),
-                Words("foo".to_string()),
-                Words("f".to_string()),
-                Words("foo".to_string())
-            ],
-            vars
-        ),
-        Ok("foofoo ffo".bytes().collect::<Vec<_>>())
-    );
-    assert_eq!(
-        expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars),
-        Ok("fo  ".bytes().collect::<Vec<_>>())
-    );
 
     assert_eq!(
         expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
diff --git a/library/term/src/terminfo/parser/compiled.rs b/library/test/src/term/terminfo/parser/compiled.rs
index fbc5aebdb2c..b24f3f8b05e 100644
--- a/library/term/src/terminfo/parser/compiled.rs
+++ b/library/test/src/term/terminfo/parser/compiled.rs
@@ -13,7 +13,7 @@ mod tests;
 // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
 
 #[rustfmt::skip]
-pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
+pub(crate) static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
     "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
     "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
     "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
@@ -26,13 +26,13 @@ pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
     "return_does_clr_eol"];
 
 #[rustfmt::skip]
-pub static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
+pub(crate) static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
     "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
     "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
     "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
 
 #[rustfmt::skip]
-pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
+pub(crate) static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
     "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
     "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
     "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
@@ -43,13 +43,13 @@ pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
     "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
 
 #[rustfmt::skip]
-pub static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
+pub(crate) static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
     "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
     "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
     "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
 
 #[rustfmt::skip]
-pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
+pub(crate) static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
     "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
     "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
     "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
@@ -123,7 +123,7 @@ pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
     "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
 
 #[rustfmt::skip]
-pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
+pub(crate) static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
     "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
     "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
     "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
@@ -178,7 +178,7 @@ fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
 
 /// Parse a compiled terminfo entry, using long capability names if `longnames`
 /// is true
-pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
+pub(crate) fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
     macro_rules! t( ($e:expr) => (
         match $e {
             Ok(e) => e,
@@ -317,7 +317,7 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin
 }
 
 /// Creates a dummy TermInfo struct for msys terminals
-pub fn msys_terminfo() -> TermInfo {
+pub(crate) fn msys_terminfo() -> TermInfo {
     let mut strings = HashMap::new();
     strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
     strings.insert("bold".to_string(), b"\x1B[1m".to_vec());
diff --git a/library/term/src/terminfo/parser/compiled/tests.rs b/library/test/src/term/terminfo/parser/compiled/tests.rs
index 8a9187b0495..8a9187b0495 100644
--- a/library/term/src/terminfo/parser/compiled/tests.rs
+++ b/library/test/src/term/terminfo/parser/compiled/tests.rs
diff --git a/library/term/src/terminfo/searcher.rs b/library/test/src/term/terminfo/searcher.rs
index 5499e240e66..68e181a6895 100644
--- a/library/term/src/terminfo/searcher.rs
+++ b/library/test/src/term/terminfo/searcher.rs
@@ -11,7 +11,7 @@ mod tests;
 
 /// Return path to database entry for `term`
 #[allow(deprecated)]
-pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
+pub(crate) fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
     let mut dirs_to_search = Vec::new();
     let first_char = term.chars().next()?;
 
diff --git a/library/term/src/terminfo/searcher/tests.rs b/library/test/src/term/terminfo/searcher/tests.rs
index 4227a585e2f..4227a585e2f 100644
--- a/library/term/src/terminfo/searcher/tests.rs
+++ b/library/test/src/term/terminfo/searcher/tests.rs
diff --git a/library/term/src/win.rs b/library/test/src/term/win.rs
index c24cf9518aa..4bdbd6ee75f 100644
--- a/library/term/src/win.rs
+++ b/library/test/src/term/win.rs
@@ -5,12 +5,11 @@
 use std::io;
 use std::io::prelude::*;
 
-use crate::color;
-use crate::Attr;
-use crate::Terminal;
+use super::color;
+use super::Terminal;
 
 /// A Terminal implementation that uses the Win32 Console API.
-pub struct WinConsole<T> {
+pub(crate) struct WinConsole<T> {
     buf: T,
     def_foreground: color::Color,
     def_background: color::Color,
@@ -115,7 +114,7 @@ impl<T: Write + Send + 'static> WinConsole<T> {
     }
 
     /// Returns `None` whenever the terminal cannot be created for some reason.
-    pub fn new(out: T) -> io::Result<WinConsole<T>> {
+    pub(crate) fn new(out: T) -> io::Result<WinConsole<T>> {
         use std::mem::MaybeUninit;
 
         let fg;
@@ -154,8 +153,6 @@ impl<T: Write> Write for WinConsole<T> {
 }
 
 impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
-    type Output = T;
-
     fn fg(&mut self, color: color::Color) -> io::Result<bool> {
         self.foreground = color;
         self.apply();
@@ -163,38 +160,6 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
         Ok(true)
     }
 
-    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
-        self.background = color;
-        self.apply();
-
-        Ok(true)
-    }
-
-    fn attr(&mut self, attr: Attr) -> io::Result<bool> {
-        match attr {
-            Attr::ForegroundColor(f) => {
-                self.foreground = f;
-                self.apply();
-                Ok(true)
-            }
-            Attr::BackgroundColor(b) => {
-                self.background = b;
-                self.apply();
-                Ok(true)
-            }
-            _ => Ok(false),
-        }
-    }
-
-    fn supports_attr(&self, attr: Attr) -> bool {
-        // it claims support for underscore and reverse video, but I can't get
-        // it to do anything -cmr
-        match attr {
-            Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => true,
-            _ => false,
-        }
-    }
-
     fn reset(&mut self) -> io::Result<bool> {
         self.foreground = self.def_foreground;
         self.background = self.def_background;
@@ -202,19 +167,4 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
 
         Ok(true)
     }
-
-    fn get_ref(&self) -> &T {
-        &self.buf
-    }
-
-    fn get_mut(&mut self) -> &mut T {
-        &mut self.buf
-    }
-
-    fn into_inner(self) -> T
-    where
-        Self: Sized,
-    {
-        self.buf
-    }
 }
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 5a4a540b04e..794f7277004 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -61,9 +61,7 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
                 ignore: true,
                 should_panic: ShouldPanic::No,
                 allow_fail: false,
-                #[cfg(not(bootstrap))]
                 compile_fail: false,
-                #[cfg(not(bootstrap))]
                 no_run: false,
                 test_type: TestType::Unknown,
             },
@@ -75,9 +73,7 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
                 ignore: false,
                 should_panic: ShouldPanic::No,
                 allow_fail: false,
-                #[cfg(not(bootstrap))]
                 compile_fail: false,
-                #[cfg(not(bootstrap))]
                 no_run: false,
                 test_type: TestType::Unknown,
             },
@@ -97,9 +93,7 @@ pub fn do_not_run_ignored_tests() {
             ignore: true,
             should_panic: ShouldPanic::No,
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -120,9 +114,7 @@ pub fn ignored_tests_result_in_ignored() {
             ignore: true,
             should_panic: ShouldPanic::No,
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -147,9 +139,7 @@ fn test_should_panic() {
             ignore: false,
             should_panic: ShouldPanic::Yes,
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -174,9 +164,7 @@ fn test_should_panic_good_message() {
             ignore: false,
             should_panic: ShouldPanic::YesWithMessage("error message"),
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -206,9 +194,7 @@ fn test_should_panic_bad_message() {
             ignore: false,
             should_panic: ShouldPanic::YesWithMessage(expected),
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -242,9 +228,7 @@ fn test_should_panic_non_string_message_type() {
             ignore: false,
             should_panic: ShouldPanic::YesWithMessage(expected),
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -270,9 +254,7 @@ fn test_should_panic_but_succeeds() {
                 ignore: false,
                 should_panic,
                 allow_fail: false,
-                #[cfg(not(bootstrap))]
                 compile_fail: false,
-                #[cfg(not(bootstrap))]
                 no_run: false,
                 test_type: TestType::Unknown,
             },
@@ -306,9 +288,7 @@ fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
             ignore: false,
             should_panic: ShouldPanic::No,
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -343,9 +323,7 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
             ignore: false,
             should_panic: ShouldPanic::No,
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type,
         },
@@ -384,9 +362,7 @@ fn typed_test_desc(test_type: TestType) -> TestDesc {
         ignore: false,
         should_panic: ShouldPanic::No,
         allow_fail: false,
-        #[cfg(not(bootstrap))]
         compile_fail: false,
-        #[cfg(not(bootstrap))]
         no_run: false,
         test_type,
     }
@@ -499,9 +475,7 @@ pub fn exclude_should_panic_option() {
             ignore: false,
             should_panic: ShouldPanic::Yes,
             allow_fail: false,
-            #[cfg(not(bootstrap))]
             compile_fail: false,
-            #[cfg(not(bootstrap))]
             no_run: false,
             test_type: TestType::Unknown,
         },
@@ -525,9 +499,7 @@ pub fn exact_filter_match() {
                     ignore: false,
                     should_panic: ShouldPanic::No,
                     allow_fail: false,
-                    #[cfg(not(bootstrap))]
                     compile_fail: false,
-                    #[cfg(not(bootstrap))]
                     no_run: false,
                     test_type: TestType::Unknown,
                 },
@@ -621,9 +593,7 @@ pub fn sort_tests() {
                     ignore: false,
                     should_panic: ShouldPanic::No,
                     allow_fail: false,
-                    #[cfg(not(bootstrap))]
                     compile_fail: false,
-                    #[cfg(not(bootstrap))]
                     no_run: false,
                     test_type: TestType::Unknown,
                 },
@@ -702,9 +672,7 @@ pub fn test_bench_no_iter() {
         ignore: false,
         should_panic: ShouldPanic::No,
         allow_fail: false,
-        #[cfg(not(bootstrap))]
         compile_fail: false,
-        #[cfg(not(bootstrap))]
         no_run: false,
         test_type: TestType::Unknown,
     };
@@ -726,9 +694,7 @@ pub fn test_bench_iter() {
         ignore: false,
         should_panic: ShouldPanic::No,
         allow_fail: false,
-        #[cfg(not(bootstrap))]
         compile_fail: false,
-        #[cfg(not(bootstrap))]
         no_run: false,
         test_type: TestType::Unknown,
     };
@@ -744,9 +710,7 @@ fn should_sort_failures_before_printing_them() {
         ignore: false,
         should_panic: ShouldPanic::No,
         allow_fail: false,
-        #[cfg(not(bootstrap))]
         compile_fail: false,
-        #[cfg(not(bootstrap))]
         no_run: false,
         test_type: TestType::Unknown,
     };
@@ -756,9 +720,7 @@ fn should_sort_failures_before_printing_them() {
         ignore: false,
         should_panic: ShouldPanic::No,
         allow_fail: false,
-        #[cfg(not(bootstrap))]
         compile_fail: false,
-        #[cfg(not(bootstrap))]
         no_run: false,
         test_type: TestType::Unknown,
     };
diff --git a/library/test/src/types.rs b/library/test/src/types.rs
index 63907c71ea7..3512a57e8e4 100644
--- a/library/test/src/types.rs
+++ b/library/test/src/types.rs
@@ -124,9 +124,7 @@ pub struct TestDesc {
     pub ignore: bool,
     pub should_panic: options::ShouldPanic,
     pub allow_fail: bool,
-    #[cfg(not(bootstrap))]
     pub compile_fail: bool,
-    #[cfg(not(bootstrap))]
     pub no_run: bool,
     pub test_type: TestType,
 }
@@ -147,7 +145,6 @@ impl TestDesc {
 
     /// Returns None for ignored test or that that are just run, otherwise give a description of the type of test.
     /// Descriptions include "should panic", "compile fail" and "compile".
-    #[cfg(not(bootstrap))]
     pub fn test_mode(&self) -> Option<&'static str> {
         if self.ignore {
             return None;
@@ -169,11 +166,6 @@ impl TestDesc {
         }
         None
     }
-
-    #[cfg(bootstrap)]
-    pub fn test_mode(&self) -> Option<&'static str> {
-        None
-    }
 }
 
 #[derive(Debug)]
diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml
index c76ba7667d4..1941f2b5a00 100644
--- a/library/unwind/Cargo.toml
+++ b/library/unwind/Cargo.toml
@@ -1,5 +1,4 @@
 [package]
-authors = ["The Rust Project Developers"]
 name = "unwind"
 version = "0.0.0"
 license = "MIT OR Apache-2.0"
@@ -21,7 +20,7 @@ compiler_builtins = "0.1.0"
 cfg-if = "0.1.8"
 
 [build-dependencies]
-cc = "1.0.68"
+cc = "1.0.69"
 
 [features]
 
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index eaeec72fbb5..53b13b9043b 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -3,8 +3,8 @@
 #![feature(link_cfg)]
 #![feature(nll)]
 #![feature(staged_api)]
-#![feature(unwind_attributes)]
 #![feature(static_nobundle)]
+#![feature(c_unwind)]
 #![cfg_attr(not(target_env = "msvc"), feature(libc))]
 
 cfg_if::cfg_if! {
@@ -13,6 +13,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(any(
         target_os = "l4re",
         target_os = "none",
+        target_os = "espidf",
     ))] {
         // These "unix" family members do not have unwinder.
         // Note this also matches x86_64-unknown-none-linuxkernel.
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index faf554d285a..196be74decb 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -81,9 +81,10 @@ pub type _Unwind_Exception_Cleanup_Fn =
     all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")),
     link(name = "unwind", kind = "static")
 )]
-extern "C" {
-    #[unwind(allowed)]
+extern "C-unwind" {
     pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
+}
+extern "C" {
     pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
     pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
     pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
@@ -230,9 +231,10 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
     #[cfg_attr(all(feature = "llvm-libunwind",
                    any(target_os = "fuchsia", target_os = "linux")),
                link(name = "unwind", kind = "static"))]
-    extern "C" {
-        #[unwind(allowed)]
+    extern "C-unwind" {
         pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
+    }
+    extern "C" {
         pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
                                  trace_argument: *mut c_void)
                                  -> _Unwind_Reason_Code;
@@ -242,8 +244,7 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
     #[cfg_attr(all(feature = "llvm-libunwind",
                    any(target_os = "fuchsia", target_os = "linux")),
                link(name = "unwind", kind = "static"))]
-    extern "C" {
-        #[unwind(allowed)]
+    extern "C-unwind" {
         pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
     }