about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-10-04 13:37:12 +0000
committerbors <bors@rust-lang.org>2025-10-04 13:37:12 +0000
commit1bd98acf0e54f1ea678c4fabb8e1b10851eb8465 (patch)
treee1e0adfca6dd8050387b45ffb09c0985cf2a32a8
parent99b9a8850349e56247acb6ce19910c7f96db8439 (diff)
parent1ebbb3c2fd78de38d0730cf9d874295f0d5dc2f1 (diff)
downloadrust-auto.tar.gz
rust-auto.zip
Auto merge of #147330 - matthiaskrgr:rollup-h4jyzmv, r=matthiaskrgr auto
Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#142670 (Document fully-qualified syntax in `as`' keyword doc)
 - rust-lang/rust#145685 (add CloneFromCell and Cell::get_cloned)
 - rust-lang/rust#146330 (Bump unicode_data and printables to version 17.0.0)
 - rust-lang/rust#146451 (Fix atan2 inaccuracy in documentation)
 - rust-lang/rust#146479 (add mem::conjure_zst)
 - rust-lang/rust#147117 (interpret `#[used]` as `#[used(compiler)]` on illumos)
 - rust-lang/rust#147190 (std: `sys::net` cleanups)
 - rust-lang/rust#147251 (Do not assert that a change in global cache only happens when concurrent)
 - rust-lang/rust#147280 (Return to needs-llvm-components being info-only)
 - rust-lang/rust#147288 (compiletest: Make `DirectiveLine` responsible for name/value splitting)
 - rust-lang/rust#147315 (bless autodiff batching test)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs36
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs13
-rw-r--r--compiler/rustc_hir/src/attrs/data_structures.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs5
-rw-r--r--compiler/rustc_type_ir/src/interner.rs8
-rw-r--r--compiler/rustc_type_ir/src/search_graph/global_cache.rs4
-rw-r--r--compiler/rustc_type_ir/src/search_graph/mod.rs2
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/rc.rs10
-rw-r--r--library/alloc/src/sync.rs9
-rw-r--r--library/core/src/cell.rs92
-rw-r--r--library/core/src/mem/mod.rs58
-rw-r--r--library/core/src/tuple.rs10
-rw-r--r--library/core/src/unicode/printable.rs160
-rw-r--r--library/core/src/unicode/unicode_data.rs750
-rw-r--r--library/std/src/keyword_docs.rs35
-rw-r--r--library/std/src/num/f128.rs10
-rw-r--r--library/std/src/num/f16.rs10
-rw-r--r--library/std/src/num/f32.rs10
-rw-r--r--library/std/src/num/f64.rs10
-rw-r--r--library/std/src/os/unix/net/datagram.rs2
-rw-r--r--library/std/src/os/unix/net/listener.rs4
-rw-r--r--library/std/src/os/unix/net/stream.rs4
-rw-r--r--library/std/src/sys/net/connection/socket/hermit.rs24
-rw-r--r--library/std/src/sys/net/connection/socket/mod.rs199
-rw-r--r--library/std/src/sys/net/connection/socket/solid.rs30
-rw-r--r--library/std/src/sys/net/connection/socket/unix.rs162
-rw-r--r--library/std/src/sys/net/connection/socket/wasip2.rs22
-rw-r--r--library/std/src/sys/net/connection/socket/windows.rs22
-rw-r--r--library/std/src/sys/pal/windows/mod.rs2
-rw-r--r--src/tools/compiletest/src/directives.rs180
-rw-r--r--src/tools/compiletest/src/directives/auxiliary.rs4
-rw-r--r--src/tools/compiletest/src/directives/cfg.rs26
-rw-r--r--src/tools/compiletest/src/directives/line.rs108
-rw-r--r--src/tools/compiletest/src/directives/needs.rs20
-rw-r--r--src/tools/compiletest/src/directives/tests.rs11
-rw-r--r--tests/codegen-llvm/autodiff/batched.rs74
-rw-r--r--tests/ui/consts/std/conjure_zst.rs10
-rw-r--r--tests/ui/consts/std/conjure_zst.stderr12
-rw-r--r--tests/ui/delegation/unsupported.current.stderr (renamed from tests/ui/delegation/unsupported.stderr)28
-rw-r--r--tests/ui/delegation/unsupported.next.stderr51
-rw-r--r--tests/ui/delegation/unsupported.rs8
42 files changed, 1329 insertions, 910 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index 262b8213977..7978bf28214 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -370,6 +370,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for NoMangleParser {
 pub(crate) struct UsedParser {
     first_compiler: Option<Span>,
     first_linker: Option<Span>,
+    first_default: Option<Span>,
 }
 
 // A custom `AttributeParser` is used rather than a Simple attribute parser because
@@ -382,7 +383,7 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
         template!(Word, List: &["compiler", "linker"]),
         |group: &mut Self, cx, args| {
             let used_by = match args {
-                ArgParser::NoArgs => UsedBy::Linker,
+                ArgParser::NoArgs => UsedBy::Default,
                 ArgParser::List(list) => {
                     let Some(l) = list.single() else {
                         cx.expected_single_argument(list.span);
@@ -423,12 +424,29 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
                 ArgParser::NameValue(_) => return,
             };
 
+            let attr_span = cx.attr_span;
+
+            // `#[used]` is interpreted as `#[used(linker)]` (though depending on target OS the
+            // circumstances are more complicated). While we're checking `used_by`, also report
+            // these cross-`UsedBy` duplicates to warn.
             let target = match used_by {
                 UsedBy::Compiler => &mut group.first_compiler,
-                UsedBy::Linker => &mut group.first_linker,
+                UsedBy::Linker => {
+                    if let Some(prev) = group.first_default {
+                        cx.warn_unused_duplicate(prev, attr_span);
+                        return;
+                    }
+                    &mut group.first_linker
+                }
+                UsedBy::Default => {
+                    if let Some(prev) = group.first_linker {
+                        cx.warn_unused_duplicate(prev, attr_span);
+                        return;
+                    }
+                    &mut group.first_default
+                }
             };
 
-            let attr_span = cx.attr_span;
             if let Some(prev) = *target {
                 cx.warn_unused_duplicate(prev, attr_span);
             } else {
@@ -440,11 +458,13 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
         AllowedTargets::AllowList(&[Allow(Target::Static), Warn(Target::MacroCall)]);
 
     fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
-        // Ratcheting behaviour, if both `linker` and `compiler` are specified, use `linker`
-        Some(match (self.first_compiler, self.first_linker) {
-            (_, Some(span)) => AttributeKind::Used { used_by: UsedBy::Linker, span },
-            (Some(span), _) => AttributeKind::Used { used_by: UsedBy::Compiler, span },
-            (None, None) => return None,
+        // If a specific form of `used` is specified, it takes precedence over generic `#[used]`.
+        // If both `linker` and `compiler` are specified, use `linker`.
+        Some(match (self.first_compiler, self.first_linker, self.first_default) {
+            (_, Some(span), _) => AttributeKind::Used { used_by: UsedBy::Linker, span },
+            (Some(span), _, _) => AttributeKind::Used { used_by: UsedBy::Compiler, span },
+            (_, _, Some(span)) => AttributeKind::Used { used_by: UsedBy::Default, span },
+            (None, None, None) => return None,
         })
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 32ae810ecc8..2c7643e46ce 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -263,6 +263,19 @@ fn process_builtin_attrs(
                 AttributeKind::Used { used_by, .. } => match used_by {
                     UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER,
                     UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER,
+                    UsedBy::Default => {
+                        let used_form = if tcx.sess.target.os == "illumos" {
+                            // illumos' `ld` doesn't support a section header that would represent
+                            // `#[used(linker)]`, see
+                            // https://github.com/rust-lang/rust/issues/146169. For that target,
+                            // downgrade as if `#[used(compiler)]` was requested and hope for the
+                            // best.
+                            CodegenFnAttrFlags::USED_COMPILER
+                        } else {
+                            CodegenFnAttrFlags::USED_LINKER
+                        };
+                        codegen_fn_attrs.flags |= used_form;
+                    }
                 },
                 AttributeKind::FfiConst(_) => {
                     codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index ddcbaeaad88..beeca7332cb 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -146,12 +146,13 @@ impl Deprecation {
 }
 
 /// There are three valid forms of the attribute:
-/// `#[used]`, which is semantically equivalent to `#[used(linker)]` except that the latter is currently unstable.
+/// `#[used]`, which is equivalent to `#[used(linker)]` on targets that support it, but `#[used(compiler)]` if not.
 /// `#[used(compiler)]`
 /// `#[used(linker)]`
 #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
 #[derive(HashStable_Generic, PrintAttribute)]
 pub enum UsedBy {
+    Default,
     Compiler,
     Linker,
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 1b89a49cf98..3c5c21a7a89 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -207,8 +207,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         from_entry(entry)
     }
 
-    fn evaluation_is_concurrent(&self) -> bool {
-        self.sess.threads() > 1
+    fn assert_evaluation_is_concurrent(&self) {
+        // Turns out, the assumption for this function isn't perfect.
+        // See trait-system-refactor-initiative#234.
     }
 
     fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 886d1a78bcb..f933423197d 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -183,7 +183,9 @@ pub trait Interner:
         from_entry: impl FnOnce(&CanonicalParamEnvCacheEntry<Self>) -> R,
     ) -> R;
 
-    fn evaluation_is_concurrent(&self) -> bool;
+    /// Useful for testing. If a cache entry is replaced, this should
+    /// (in theory) only happen when concurrent.
+    fn assert_evaluation_is_concurrent(&self);
 
     fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
 
@@ -567,7 +569,7 @@ impl<I: Interner> search_graph::Cx for I {
     fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
         I::with_global_cache(self, f)
     }
-    fn evaluation_is_concurrent(&self) -> bool {
-        self.evaluation_is_concurrent()
+    fn assert_evaluation_is_concurrent(&self) {
+        self.assert_evaluation_is_concurrent()
     }
 }
diff --git a/compiler/rustc_type_ir/src/search_graph/global_cache.rs b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
index eb56c1af408..7e438fefffc 100644
--- a/compiler/rustc_type_ir/src/search_graph/global_cache.rs
+++ b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
@@ -56,13 +56,13 @@ impl<X: Cx> GlobalCache<X> {
             let with_overflow = WithOverflow { nested_goals, result };
             let prev = entry.with_overflow.insert(required_depth, with_overflow);
             if let Some(prev) = &prev {
-                assert!(cx.evaluation_is_concurrent());
+                cx.assert_evaluation_is_concurrent();
                 assert_eq!(cx.get_tracked(&prev.result), evaluation_result.result);
             }
         } else {
             let prev = entry.success.replace(Success { required_depth, nested_goals, result });
             if let Some(prev) = &prev {
-                assert!(cx.evaluation_is_concurrent());
+                cx.assert_evaluation_is_concurrent();
                 assert_eq!(cx.get_tracked(&prev.result), evaluation_result.result);
             }
         }
diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs
index 7aa58d096d5..8a41c99aeaa 100644
--- a/compiler/rustc_type_ir/src/search_graph/mod.rs
+++ b/compiler/rustc_type_ir/src/search_graph/mod.rs
@@ -53,7 +53,7 @@ pub trait Cx: Copy {
 
     fn with_global_cache<R>(self, f: impl FnOnce(&mut GlobalCache<Self>) -> R) -> R;
 
-    fn evaluation_is_concurrent(&self) -> bool;
+    fn assert_evaluation_is_concurrent(&self);
 }
 
 pub trait Delegate: Sized {
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index fc3266b7479..87ad5b0ce30 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -96,6 +96,7 @@
 #![feature(bstr)]
 #![feature(bstr_internals)]
 #![feature(cast_maybe_uninit)]
+#![feature(cell_get_cloned)]
 #![feature(char_internals)]
 #![feature(char_max_len)]
 #![feature(clone_to_uninit)]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 023238a00db..2b62b92d438 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -242,7 +242,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use core::any::Any;
-use core::cell::Cell;
+use core::cell::{Cell, CloneFromCell};
 #[cfg(not(no_global_oom_handling))]
 use core::clone::CloneToUninit;
 use core::clone::UseCloned;
@@ -340,6 +340,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Rc<U, A>> for
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T> {}
 
+// SAFETY: `Rc::clone` doesn't access any `Cell`s which could contain the `Rc` being cloned.
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: ?Sized> CloneFromCell for Rc<T> {}
+
 impl<T: ?Sized> Rc<T> {
     #[inline]
     unsafe fn from_inner(ptr: NonNull<RcInner<T>>) -> Self {
@@ -3013,6 +3017,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
 
+// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned.
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: ?Sized> CloneFromCell for Weak<T> {}
+
 impl<T> Weak<T> {
     /// Constructs a new `Weak<T>`, without allocating any memory.
     /// Calling [`upgrade`] on the return value always gives [`None`].
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 6432bdfbbed..5927d036469 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -9,6 +9,7 @@
 //! `#[cfg(target_has_atomic = "ptr")]`.
 
 use core::any::Any;
+use core::cell::CloneFromCell;
 #[cfg(not(no_global_oom_handling))]
 use core::clone::CloneToUninit;
 use core::clone::UseCloned;
@@ -281,6 +282,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Arc<U, A>> fo
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}
 
+// SAFETY: `Arc::clone` doesn't access any `Cell`s which could contain the `Arc` being cloned.
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: ?Sized> CloneFromCell for Arc<T> {}
+
 impl<T: ?Sized> Arc<T> {
     unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
         unsafe { Self::from_inner_in(ptr, Global) }
@@ -356,6 +361,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
 
+// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned.
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: ?Sized> CloneFromCell for Weak<T> {}
+
 #[stable(feature = "arc_weak", since = "1.4.0")]
 impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 6aadb7a86cd..aeac35e45a5 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -253,11 +253,12 @@
 use crate::cmp::Ordering;
 use crate::fmt::{self, Debug, Display};
 use crate::marker::{PhantomData, Unsize};
-use crate::mem;
-use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
+use crate::mem::{self, ManuallyDrop};
+use crate::ops::{self, CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
 use crate::panic::const_panic;
 use crate::pin::PinCoerceUnsized;
 use crate::ptr::{self, NonNull};
+use crate::range;
 
 mod lazy;
 mod once;
@@ -713,6 +714,93 @@ impl<T, const N: usize> Cell<[T; N]> {
     }
 }
 
+/// Types for which cloning `Cell<Self>` is sound.
+///
+/// # Safety
+///
+/// Implementing this trait for a type is sound if and only if the following code is sound for T =
+/// that type.
+///
+/// ```
+/// #![feature(cell_get_cloned)]
+/// # use std::cell::{CloneFromCell, Cell};
+/// fn clone_from_cell<T: CloneFromCell>(cell: &Cell<T>) -> T {
+///     unsafe { T::clone(&*cell.as_ptr()) }
+/// }
+/// ```
+///
+/// Importantly, you can't just implement `CloneFromCell` for any arbitrary `Copy` type, e.g. the
+/// following is unsound:
+///
+/// ```rust
+/// #![feature(cell_get_cloned)]
+/// # use std::cell::Cell;
+///
+/// #[derive(Copy, Debug)]
+/// pub struct Bad<'a>(Option<&'a Cell<Bad<'a>>>, u8);
+///
+/// impl Clone for Bad<'_> {
+///     fn clone(&self) -> Self {
+///         let a: &u8 = &self.1;
+///         // when self.0 points to self, we write to self.1 while we have a live `&u8` pointing to
+///         // it -- this is UB
+///         self.0.unwrap().set(Self(None, 1));
+///         dbg!((a, self));
+///         Self(None, 0)
+///     }
+/// }
+///
+/// // this is not sound
+/// // unsafe impl CloneFromCell for Bad<'_> {}
+/// ```
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+// Allow potential overlapping implementations in user code
+#[marker]
+pub unsafe trait CloneFromCell: Clone {}
+
+// `CloneFromCell` can be implemented for types that don't have indirection and which don't access
+// `Cell`s in their `Clone` implementation. A commonly-used subset is covered here.
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: CloneFromCell, const N: usize> CloneFromCell for [T; N] {}
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: CloneFromCell> CloneFromCell for Option<T> {}
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: CloneFromCell, E: CloneFromCell> CloneFromCell for Result<T, E> {}
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: ?Sized> CloneFromCell for PhantomData<T> {}
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: CloneFromCell> CloneFromCell for ManuallyDrop<T> {}
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: CloneFromCell> CloneFromCell for ops::Range<T> {}
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+unsafe impl<T: CloneFromCell> CloneFromCell for range::Range<T> {}
+
+#[unstable(feature = "cell_get_cloned", issue = "145329")]
+impl<T: CloneFromCell> Cell<T> {
+    /// Get a clone of the `Cell` that contains a copy of the original value.
+    ///
+    /// This allows a cheaply `Clone`-able type like an `Rc` to be stored in a `Cell`, exposing the
+    /// cheaper `clone()` method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(cell_get_cloned)]
+    ///
+    /// use core::cell::Cell;
+    /// use std::rc::Rc;
+    ///
+    /// let rc = Rc::new(1usize);
+    /// let c1 = Cell::new(rc);
+    /// let c2 = c1.get_cloned();
+    /// assert_eq!(*c2.into_inner(), 1);
+    /// ```
+    pub fn get_cloned(&self) -> Self {
+        // SAFETY: T is CloneFromCell, which guarantees that this is sound.
+        Cell::new(T::clone(unsafe { &*self.as_ptr() }))
+    }
+}
+
 /// A mutable memory location with dynamically checked borrow rules
 ///
 /// See the [module-level documentation](self) for more.
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index db4c8e9e551..c484551187c 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -7,6 +7,7 @@
 
 use crate::alloc::Layout;
 use crate::marker::DiscriminantKind;
+use crate::panic::const_assert;
 use crate::{clone, cmp, fmt, hash, intrinsics, ptr};
 
 mod manually_drop;
@@ -1407,3 +1408,60 @@ pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
     // The `{}` is for better error messages
     {builtin # offset_of($Container, $($fields)+)}
 }
+
+/// Create a fresh instance of the inhabited ZST type `T`.
+///
+/// Prefer this to [`zeroed`] or [`uninitialized`] or [`transmute_copy`]
+/// in places where you know that `T` is zero-sized, but don't have a bound
+/// (such as [`Default`]) that would allow you to instantiate it using safe code.
+///
+/// If you're not sure whether `T` is an inhabited ZST, then you should be
+/// using [`MaybeUninit`], not this function.
+///
+/// # Panics
+///
+/// If `size_of::<T>() != 0`.
+///
+/// # Safety
+///
+/// - `T` must be *[inhabited]*, i.e. possible to construct. This means that types
+///   like zero-variant enums and [`!`] are unsound to conjure.
+/// - You must use the value only in ways which do not violate any *safety*
+///   invariants of the type.
+///
+/// While it's easy to create a *valid* instance of an inhabited ZST, since having
+/// no bits in its representation means there's only one possible value, that
+/// doesn't mean that it's always *sound* to do so.
+///
+/// For example, a library could design zero-sized tokens that are `!Default + !Clone`, limiting
+/// their creation to functions that initialize some state or establish a scope. Conjuring such a
+/// token could break invariants and lead to unsoundness.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(mem_conjure_zst)]
+/// use std::mem::conjure_zst;
+///
+/// assert_eq!(unsafe { conjure_zst::<()>() }, ());
+/// assert_eq!(unsafe { conjure_zst::<[i32; 0]>() }, []);
+/// ```
+///
+/// [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited
+#[unstable(feature = "mem_conjure_zst", issue = "95383")]
+pub const unsafe fn conjure_zst<T>() -> T {
+    const_assert!(
+        size_of::<T>() == 0,
+        "mem::conjure_zst invoked on a nonzero-sized type",
+        "mem::conjure_zst invoked on type {t}, which is not zero-sized",
+        t: &str = stringify!(T)
+    );
+
+    // SAFETY: because the caller must guarantee that it's inhabited and zero-sized,
+    // there's nothing in the representation that needs to be set.
+    // `assume_init` calls `assert_inhabited`, so we don't need to here.
+    unsafe {
+        #[allow(clippy::uninit_assumed_init)]
+        MaybeUninit::uninit().assume_init()
+    }
+}
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index c57a8d81ade..58f81372aff 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -1,5 +1,6 @@
 // See core/src/primitive_docs.rs for documentation.
 
+use crate::cell::CloneFromCell;
 use crate::cmp::Ordering::{self, *};
 use crate::marker::{ConstParamTy_, StructuralPartialEq};
 use crate::ops::ControlFlow::{self, Break, Continue};
@@ -155,6 +156,15 @@ macro_rules! tuple_impls {
                 }
             }
         }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            // SAFETY: tuples introduce no additional indirection, so they can be copied whenever T
+            // can.
+            #[unstable(feature = "cell_get_cloned", issue = "145329")]
+            unsafe impl<$($T: CloneFromCell),+> CloneFromCell for ($($T,)+)
+            {}
+        }
     }
 }
 
diff --git a/library/core/src/unicode/printable.rs b/library/core/src/unicode/printable.rs
index d8fb50e4ed2..68e1c8ae31c 100644
--- a/library/core/src/unicode/printable.rs
+++ b/library/core/src/unicode/printable.rs
@@ -54,13 +54,10 @@ pub(crate) fn is_printable(x: char) -> bool {
         if 0x2a6e0 <= x && x < 0x2a700 {
             return false;
         }
-        if 0x2b73a <= x && x < 0x2b740 {
-            return false;
-        }
         if 0x2b81e <= x && x < 0x2b820 {
             return false;
         }
-        if 0x2cea2 <= x && x < 0x2ceb0 {
+        if 0x2ceae <= x && x < 0x2ceb0 {
             return false;
         }
         if 0x2ebe1 <= x && x < 0x2ebf0 {
@@ -75,7 +72,7 @@ pub(crate) fn is_printable(x: char) -> bool {
         if 0x3134b <= x && x < 0x31350 {
             return false;
         }
-        if 0x323b0 <= x && x < 0xe0100 {
+        if 0x3347a <= x && x < 0xe0100 {
             return false;
         }
         if 0xe01f0 <= x && x < 0x110000 {
@@ -96,7 +93,7 @@ const SINGLETONS0U: &[(u8, u8)] = &[
     (0x09, 17),
     (0x0a, 28),
     (0x0b, 25),
-    (0x0c, 26),
+    (0x0c, 25),
     (0x0d, 16),
     (0x0e, 12),
     (0x0f, 4),
@@ -107,24 +104,22 @@ const SINGLETONS0U: &[(u8, u8)] = &[
     (0x17, 4),
     (0x18, 1),
     (0x19, 3),
-    (0x1a, 7),
+    (0x1a, 9),
     (0x1b, 1),
     (0x1c, 2),
     (0x1f, 22),
     (0x20, 3),
-    (0x2b, 3),
+    (0x2b, 2),
     (0x2d, 11),
     (0x2e, 1),
     (0x30, 4),
     (0x31, 2),
     (0x32, 1),
-    (0xa7, 4),
     (0xa9, 2),
     (0xaa, 4),
     (0xab, 8),
     (0xfa, 2),
     (0xfb, 5),
-    (0xfd, 2),
     (0xfe, 3),
     (0xff, 9),
 ];
@@ -143,30 +138,29 @@ const SINGLETONS0L: &[u8] = &[
     0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e,
     0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce,
     0xcf, 0x0d, 0x11, 0x29, 0x3a, 0x3b, 0x45, 0x49,
-    0x57, 0x5b, 0x5c, 0x5e, 0x5f, 0x64, 0x65, 0x8d,
-    0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf,
-    0xe4, 0xe5, 0xf0, 0x0d, 0x11, 0x45, 0x49, 0x64,
-    0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,
-    0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6,
-    0xbe, 0xbf, 0xc5, 0xc7, 0xcf, 0xda, 0xdb, 0x48,
-    0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e,
-    0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f,
-    0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7,
-    0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe,
-    0xff, 0x80, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x1f,
-    0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae,
-    0xaf, 0x4d, 0xbb, 0xbc, 0x16, 0x17, 0x1e, 0x1f,
-    0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e,
-    0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0,
-    0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, 0x96,
+    0x57, 0x5b, 0x5e, 0x5f, 0x64, 0x65, 0x8d, 0x91,
+    0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4,
+    0xe5, 0xf0, 0x0d, 0x11, 0x45, 0x49, 0x64, 0x65,
+    0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7,
+    0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe,
+    0xbf, 0xc5, 0xc7, 0xcf, 0xda, 0xdb, 0x48, 0x98,
+    0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x4f,
+    0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1,
+    0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11,
+    0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0xff,
+    0x80, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x1f, 0x6e,
+    0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf,
+    0xde, 0xdf, 0x4d, 0xbb, 0xbc, 0x16, 0x17, 0x1e,
+    0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c,
+    0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc,
+    0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75,
     0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, 0xc7,
     0xcf, 0xd7, 0xdf, 0x9a, 0x00, 0x40, 0x97, 0x98,
-    0x30, 0x8f, 0x1f, 0xce, 0xcf, 0xd2, 0xd4, 0xce,
-    0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f,
-    0x10, 0x27, 0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37,
-    0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, 0x53, 0x67,
-    0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,
-    0xfe, 0xff,
+    0x30, 0x8f, 0x1f, 0xce, 0xff, 0x4e, 0x4f, 0x5a,
+    0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee,
+    0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45,
+    0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8,
+    0xd9, 0xe7, 0xfe, 0xff,
 ];
 #[rustfmt::skip]
 const SINGLETONS1U: &[(u8, u8)] = &[
@@ -195,6 +189,7 @@ const SINGLETONS1U: &[(u8, u8)] = &[
     (0x24, 1),
     (0x6a, 4),
     (0x6b, 2),
+    (0x6e, 2),
     (0xaf, 3),
     (0xb1, 2),
     (0xbc, 2),
@@ -207,12 +202,13 @@ const SINGLETONS1U: &[(u8, u8)] = &[
     (0xda, 1),
     (0xe0, 5),
     (0xe1, 2),
+    (0xe6, 1),
     (0xe7, 4),
     (0xe8, 2),
     (0xee, 32),
     (0xf0, 4),
     (0xf8, 2),
-    (0xfa, 4),
+    (0xfa, 5),
     (0xfb, 1),
 ];
 #[rustfmt::skip]
@@ -231,18 +227,19 @@ const SINGLETONS1L: &[u8] = &[
     0x39, 0x3a, 0xa8, 0xa9, 0xd8, 0xd9, 0x09, 0x37,
     0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66,
     0x69, 0x8f, 0x92, 0x11, 0x6f, 0x5f, 0xbf, 0xee,
-    0xef, 0x5a, 0x62, 0xf4, 0xfc, 0xff, 0x53, 0x54,
-    0x9a, 0x9b, 0x2e, 0x2f, 0x27, 0x28, 0x55, 0x9d,
-    0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba,
-    0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a,
-    0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd, 0xa0,
-    0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xe7,
-    0xec, 0xef, 0xff, 0xc5, 0xc6, 0x04, 0x20, 0x23,
-    0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a,
-    0x4c, 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c,
-    0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b, 0x73, 0x78,
-    0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0,
-    0xd0, 0xae, 0xaf, 0x6e, 0x6f, 0xdd, 0xde, 0x93,
+    0xef, 0x5a, 0x62, 0xb9, 0xba, 0xf4, 0xfc, 0xff,
+    0x53, 0x54, 0x9a, 0x9b, 0x2e, 0x2f, 0x27, 0x28,
+    0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8,
+    0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15,
+    0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc,
+    0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e,
+    0x3f, 0xdf, 0xe7, 0xec, 0xef, 0xff, 0xc5, 0xc6,
+    0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38,
+    0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56,
+    0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66,
+    0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa,
+    0xaf, 0xb0, 0xc0, 0xd0, 0xae, 0xaf, 0x6e, 0x6f,
+    0xc7, 0xdd, 0xde, 0x93,
 ];
 #[rustfmt::skip]
 const NORMAL0: &[u8] = &[
@@ -254,7 +251,7 @@ const NORMAL0: &[u8] = &[
     0x06, 0x11,
     0x81, 0xac, 0x0e,
     0x80, 0xab, 0x05,
-    0x1f, 0x08,
+    0x20, 0x07,
     0x81, 0x1c, 0x03,
     0x19, 0x08,
     0x01, 0x04,
@@ -282,8 +279,8 @@ const NORMAL0: &[u8] = &[
     0x4e, 0x07,
     0x1b, 0x07,
     0x57, 0x07,
-    0x02, 0x06,
-    0x17, 0x0c,
+    0x02, 0x05,
+    0x18, 0x0c,
     0x50, 0x04,
     0x43, 0x03,
     0x2d, 0x03,
@@ -319,7 +316,7 @@ const NORMAL0: &[u8] = &[
     0x0b, 0x03,
     0x80, 0xac, 0x06,
     0x0a, 0x06,
-    0x2f, 0x31,
+    0x4c, 0x14,
     0x80, 0xf4, 0x08,
     0x3c, 0x03,
     0x0f, 0x03,
@@ -330,7 +327,7 @@ const NORMAL0: &[u8] = &[
     0x18, 0x08,
     0x2f, 0x11,
     0x2d, 0x03,
-    0x21, 0x0f,
+    0x22, 0x0e,
     0x21, 0x0f,
     0x80, 0x8c, 0x04,
     0x82, 0x9a, 0x16,
@@ -349,8 +346,8 @@ const NORMAL0: &[u8] = &[
     0x37, 0x09,
     0x81, 0x5c, 0x14,
     0x80, 0xb8, 0x08,
-    0x80, 0xdd, 0x15,
-    0x3b, 0x03,
+    0x80, 0xdd, 0x14,
+    0x3c, 0x03,
     0x0a, 0x06,
     0x38, 0x08,
     0x46, 0x08,
@@ -370,9 +367,7 @@ const NORMAL0: &[u8] = &[
     0x81, 0xda, 0x26,
     0x07, 0x0c,
     0x05, 0x05,
-    0x80, 0xa6, 0x10,
-    0x81, 0xf5, 0x07,
-    0x01, 0x20,
+    0x82, 0xb3, 0x20,
     0x2a, 0x06,
     0x4c, 0x04,
     0x80, 0x8d, 0x04,
@@ -414,7 +409,7 @@ const NORMAL1: &[u8] = &[
     0x16, 0x05,
     0x21, 0x03,
     0x1b, 0x05,
-    0x01, 0x40,
+    0x1b, 0x26,
     0x38, 0x04,
     0x4b, 0x05,
     0x2f, 0x04,
@@ -437,8 +432,9 @@ const NORMAL1: &[u8] = &[
     0x1d, 0x08,
     0x02, 0x80, 0xd0,
     0x52, 0x10,
-    0x03, 0x37,
-    0x2c, 0x08,
+    0x06, 0x08,
+    0x09, 0x21,
+    0x2e, 0x08,
     0x2a, 0x16,
     0x1a, 0x26,
     0x1c, 0x14,
@@ -481,7 +477,8 @@ const NORMAL1: &[u8] = &[
     0x48, 0x08,
     0x53, 0x0d,
     0x49, 0x07,
-    0x0a, 0x80, 0xb6,
+    0x0a, 0x56,
+    0x08, 0x58,
     0x22, 0x0e,
     0x0a, 0x06,
     0x46, 0x0a,
@@ -491,7 +488,9 @@ const NORMAL1: &[u8] = &[
     0x0e, 0x08,
     0x0a, 0x06,
     0x39, 0x07,
-    0x0a, 0x81, 0x36,
+    0x0a, 0x06,
+    0x2c, 0x04,
+    0x0a, 0x80, 0xf6,
     0x19, 0x07,
     0x3b, 0x03,
     0x1d, 0x55,
@@ -514,15 +513,16 @@ const NORMAL1: &[u8] = &[
     0x28, 0x05,
     0x13, 0x81, 0xb0,
     0x3a, 0x80, 0xc6,
-    0x5b, 0x65,
+    0x5b, 0x05,
+    0x34, 0x2c,
     0x4b, 0x04,
     0x39, 0x07,
     0x11, 0x40,
     0x05, 0x0b,
-    0x02, 0x0e,
-    0x97, 0xf8, 0x08,
-    0x84, 0xd6, 0x29,
-    0x0a, 0xa2, 0xe7,
+    0x07, 0x09,
+    0x9c, 0xd6, 0x29,
+    0x20, 0x61,
+    0x73, 0xa1, 0xfd,
     0x81, 0x33, 0x0f,
     0x01, 0x1d,
     0x06, 0x0e,
@@ -532,8 +532,10 @@ const NORMAL1: &[u8] = &[
     0x0d, 0x03,
     0x09, 0x07,
     0x10, 0x8f, 0x60,
-    0x80, 0xfa, 0x06,
-    0x81, 0xb4, 0x4c,
+    0x80, 0xfd, 0x03,
+    0x81, 0xb4, 0x06,
+    0x17, 0x0f,
+    0x11, 0x0f,
     0x47, 0x09,
     0x74, 0x3c,
     0x80, 0xf6, 0x0a,
@@ -560,7 +562,9 @@ const NORMAL1: &[u8] = &[
     0x01, 0x81, 0xd0,
     0x2a, 0x80, 0xd6,
     0x2b, 0x04,
-    0x01, 0x81, 0xe0,
+    0x01, 0x80, 0xc0,
+    0x36, 0x08,
+    0x02, 0x80, 0xe0,
     0x80, 0xf7, 0x29,
     0x4c, 0x04,
     0x0a, 0x04,
@@ -581,11 +585,10 @@ const NORMAL1: &[u8] = &[
     0x09, 0x07,
     0x02, 0x0e,
     0x06, 0x80, 0x9a,
-    0x83, 0xd8, 0x04,
+    0x83, 0xd9, 0x03,
     0x11, 0x03,
     0x0d, 0x03,
-    0x77, 0x04,
-    0x5f, 0x06,
+    0x80, 0xda, 0x06,
     0x0c, 0x04,
     0x01, 0x0f,
     0x0c, 0x04,
@@ -593,12 +596,13 @@ const NORMAL1: &[u8] = &[
     0x0a, 0x06,
     0x28, 0x08,
     0x2c, 0x04,
-    0x02, 0x3e,
-    0x81, 0x54, 0x0c,
+    0x02, 0x0e,
+    0x09, 0x27,
+    0x81, 0x58, 0x08,
     0x1d, 0x03,
-    0x0a, 0x05,
-    0x38, 0x07,
-    0x1c, 0x06,
-    0x09, 0x07,
-    0x80, 0xfa, 0x84, 0x06,
+    0x0b, 0x03,
+    0x3b, 0x04,
+    0x1e, 0x04,
+    0x0a, 0x07,
+    0x80, 0xfb, 0x84, 0x05,
 ];
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index 2f53de183f6..3c38b44224f 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -1,15 +1,15 @@
 //! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!
-// Alphabetic      :  1723 bytes, 142707 codepoints in 755 ranges (U+0000AA - U+0323B0) using skiplist
-// Case_Ignorable  :  1043 bytes,   2744 codepoints in 447 ranges (U+0000A8 - U+0E01F0) using skiplist
-// Cased           :   403 bytes,   4526 codepoints in 157 ranges (U+0000AA - U+01F18A) using skiplist
-// Grapheme_Extend :   887 bytes,   2193 codepoints in 375 ranges (U+000300 - U+0E01F0) using skiplist
-// Lowercase       :   933 bytes,   2543 codepoints in 674 ranges (U+0000AA - U+01E944) using bitset
-// N               :   455 bytes,   1901 codepoints in 143 ranges (U+0000B2 - U+01FBFA) using skiplist
-// Uppercase       :   797 bytes,   1952 codepoints in 655 ranges (U+0000C0 - U+01F18A) using bitset
+// Alphabetic      :  1723 bytes, 147369 codepoints in 759 ranges (U+0000AA - U+03347A) using skiplist
+// Case_Ignorable  :  1063 bytes,   2789 codepoints in 459 ranges (U+0000A8 - U+0E01F0) using skiplist
+// Cased           :   401 bytes,   4580 codepoints in 156 ranges (U+0000AA - U+01F18A) using skiplist
+// Grapheme_Extend :   899 bytes,   2232 codepoints in 383 ranges (U+000300 - U+0E01F0) using skiplist
+// Lowercase       :   943 bytes,   2569 codepoints in 676 ranges (U+0000AA - U+01E944) using bitset
+// N               :   463 bytes,   1914 codepoints in 145 ranges (U+0000B2 - U+01FBFA) using skiplist
+// Uppercase       :   799 bytes,   1980 codepoints in 659 ranges (U+0000C0 - U+01F18A) using bitset
 // White_Space     :   256 bytes,     19 codepoints in   8 ranges (U+000085 - U+003001) using cascading
-// to_lower        : 11484 bytes
-// to_upper        : 13432 bytes
-// Total           : 31413 bytes
+// to_lower        : 11708 bytes
+// to_upper        : 13656 bytes
+// Total           : 31911 bytes
 
 #[inline(always)]
 const fn bitset_search<
@@ -140,53 +140,52 @@ unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
     offset_idx % 2 == 1
 }
 
-pub const UNICODE_VERSION: (u8, u8, u8) = (16, 0, 0);
+pub const UNICODE_VERSION: (u8, u8, u8) = (17, 0, 0);
 
 #[rustfmt::skip]
 pub mod alphabetic {
     use super::ShortOffsetRunHeader;
 
-    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 53] = [
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 51] = [
         ShortOffsetRunHeader::new(0, 706), ShortOffsetRunHeader::new(12, 4681),
         ShortOffsetRunHeader::new(414, 5741), ShortOffsetRunHeader::new(452, 7958),
         ShortOffsetRunHeader::new(552, 9398), ShortOffsetRunHeader::new(623, 11264),
         ShortOffsetRunHeader::new(625, 12293), ShortOffsetRunHeader::new(663, 13312),
         ShortOffsetRunHeader::new(687, 19904), ShortOffsetRunHeader::new(688, 42125),
         ShortOffsetRunHeader::new(690, 42509), ShortOffsetRunHeader::new(694, 55204),
-        ShortOffsetRunHeader::new(784, 63744), ShortOffsetRunHeader::new(789, 64110),
-        ShortOffsetRunHeader::new(790, 64830), ShortOffsetRunHeader::new(812, 66176),
-        ShortOffsetRunHeader::new(853, 67383), ShortOffsetRunHeader::new(900, 73440),
+        ShortOffsetRunHeader::new(778, 63744), ShortOffsetRunHeader::new(783, 64110),
+        ShortOffsetRunHeader::new(784, 64830), ShortOffsetRunHeader::new(806, 66176),
+        ShortOffsetRunHeader::new(847, 67383), ShortOffsetRunHeader::new(894, 73440),
         ShortOffsetRunHeader::new(1217, 74650), ShortOffsetRunHeader::new(1228, 77712),
         ShortOffsetRunHeader::new(1233, 78896), ShortOffsetRunHeader::new(1236, 82939),
         ShortOffsetRunHeader::new(1240, 83527), ShortOffsetRunHeader::new(1242, 90368),
         ShortOffsetRunHeader::new(1243, 92160), ShortOffsetRunHeader::new(1245, 92729),
-        ShortOffsetRunHeader::new(1246, 93504), ShortOffsetRunHeader::new(1261, 100344),
-        ShortOffsetRunHeader::new(1278, 101590), ShortOffsetRunHeader::new(1280, 110576),
-        ShortOffsetRunHeader::new(1283, 110883), ShortOffsetRunHeader::new(1290, 111356),
-        ShortOffsetRunHeader::new(1300, 113664), ShortOffsetRunHeader::new(1301, 119808),
-        ShortOffsetRunHeader::new(1311, 120486), ShortOffsetRunHeader::new(1348, 122624),
-        ShortOffsetRunHeader::new(1371, 123536), ShortOffsetRunHeader::new(1395, 124112),
-        ShortOffsetRunHeader::new(1399, 124896), ShortOffsetRunHeader::new(1405, 126464),
-        ShortOffsetRunHeader::new(1421, 127280), ShortOffsetRunHeader::new(1487, 131072),
-        ShortOffsetRunHeader::new(1493, 173792), ShortOffsetRunHeader::new(1494, 177978),
-        ShortOffsetRunHeader::new(1496, 183970), ShortOffsetRunHeader::new(1500, 191457),
-        ShortOffsetRunHeader::new(1502, 192094), ShortOffsetRunHeader::new(1504, 194560),
-        ShortOffsetRunHeader::new(1505, 195102), ShortOffsetRunHeader::new(1506, 196608),
-        ShortOffsetRunHeader::new(1507, 201547), ShortOffsetRunHeader::new(1508, 205744),
-        ShortOffsetRunHeader::new(1510, 1319856),
+        ShortOffsetRunHeader::new(1246, 93504), ShortOffsetRunHeader::new(1261, 101590),
+        ShortOffsetRunHeader::new(1282, 110576), ShortOffsetRunHeader::new(1287, 110883),
+        ShortOffsetRunHeader::new(1294, 111356), ShortOffsetRunHeader::new(1304, 113664),
+        ShortOffsetRunHeader::new(1305, 119808), ShortOffsetRunHeader::new(1315, 120486),
+        ShortOffsetRunHeader::new(1352, 122624), ShortOffsetRunHeader::new(1375, 123536),
+        ShortOffsetRunHeader::new(1399, 124112), ShortOffsetRunHeader::new(1403, 126464),
+        ShortOffsetRunHeader::new(1431, 127280), ShortOffsetRunHeader::new(1497, 131072),
+        ShortOffsetRunHeader::new(1503, 173792), ShortOffsetRunHeader::new(1504, 178206),
+        ShortOffsetRunHeader::new(1506, 183982), ShortOffsetRunHeader::new(1508, 191457),
+        ShortOffsetRunHeader::new(1510, 192094), ShortOffsetRunHeader::new(1512, 194560),
+        ShortOffsetRunHeader::new(1513, 195102), ShortOffsetRunHeader::new(1514, 196608),
+        ShortOffsetRunHeader::new(1515, 201547), ShortOffsetRunHeader::new(1516, 210042),
+        ShortOffsetRunHeader::new(1518, 1324154),
     ];
-    static OFFSETS: [u8; 1511] = [
+    static OFFSETS: [u8; 1519] = [
         170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 29, 18, 1, 2, 2,
         4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 2, 1, 6, 41, 39, 14, 1, 1,
         1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10, 3, 2, 1,
-        16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 6, 8, 1, 8, 42,
+        16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 7, 7, 1, 8, 42,
         10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3, 8,
         2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2,
         1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1, 5,
         3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2,
         2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3, 12,
-        4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1, 3, 2,
-        1, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 6, 2, 1, 4, 13, 3,
+        4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1, 3, 1,
+        2, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 5, 3, 1, 4, 13, 3,
         12, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24, 1, 9, 1,
         1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1, 1, 1, 19,
         1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 19, 4, 16, 1, 36, 67, 55, 1, 1, 2, 5,
@@ -201,37 +200,37 @@ pub mod alphabetic {
         4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23, 9, 7, 1,
         7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4, 86, 6, 3,
         1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10, 2, 20, 47,
-        5, 8, 3, 113, 39, 9, 2, 103, 2, 67, 2, 2, 1, 1, 1, 8, 21, 20, 1, 33, 24, 52, 12, 68, 1, 1,
-        44, 6, 3, 1, 1, 3, 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1, 55, 9, 14,
-        18, 23, 3, 69, 1, 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 43, 1, 14,
-        6, 123, 21, 0, 12, 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1, 1, 1, 2, 1,
-        2, 1, 108, 33, 0, 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89, 3, 6, 2, 6,
-        2, 6, 2, 3, 35, 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3, 49, 47, 32,
-        13, 30, 5, 43, 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52, 12, 11, 1,
-        15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1, 9,
-        69, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26, 70, 56,
-        6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, 10, 22, 10, 19,
-        13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, 42, 1, 2, 3, 2, 16, 3,
-        55, 1, 3, 29, 10, 1, 8, 22, 42, 18, 46, 21, 27, 23, 9, 70, 43, 5, 10, 57, 9, 1, 13, 25, 23,
-        51, 17, 4, 8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 4, 62, 7, 1,
-        1, 1, 4, 1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2,
-        3, 1, 6, 1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1, 4, 1, 2, 3, 1, 1, 1, 44,
-        66, 1, 3, 1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54,
-        2, 1, 71, 27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2,
-        4, 93, 8, 2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 199, 33, 31, 9, 1,
-        45, 1, 7, 1, 1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24,
-        6, 1, 2, 1, 37, 1, 2, 1, 4, 1, 1, 0, 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, 102, 111, 17,
-        196, 0, 97, 15, 0, 17, 6, 25, 0, 5, 0, 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, 48, 16, 4,
-        31, 21, 5, 19, 0, 45, 211, 64, 128, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 2, 14, 0, 8, 0, 41,
-        10, 0, 4, 1, 7, 1, 2, 1, 0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5, 13, 3, 9, 7, 10, 4,
-        1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28,
-        1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31,
-        1, 25, 1, 8, 0, 31, 6, 6, 213, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 112, 45, 10, 7, 16,
-        1, 0, 30, 18, 44, 0, 28, 228, 30, 2, 1, 0, 7, 1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1,
-        0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2,
-        1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17,
-        5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0, 32, 0, 6, 222, 2, 0, 14, 0, 15, 0, 0, 0, 0, 0,
-        5, 0, 0,
+        5, 8, 3, 113, 39, 9, 2, 103, 2, 82, 20, 21, 1, 33, 24, 52, 12, 68, 1, 1, 44, 6, 3, 1, 1, 3,
+        10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1, 55, 9, 14, 18, 23, 3, 69, 1,
+        1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 43, 1, 14, 6, 123, 21, 0, 12,
+        23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1, 1, 1, 2, 1, 2, 1, 108, 33, 0,
+        18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89, 3, 6, 2, 6, 2, 6, 2, 3, 35,
+        12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3, 49, 47, 32, 13, 30, 5, 43,
+        5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52, 12, 11, 1, 15, 1, 7, 1, 2,
+        1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1, 9, 69, 6, 2, 1, 1,
+        44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26, 6, 26, 38, 56, 6, 2, 64,
+        4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, 10, 22, 10, 19, 13, 18,
+        110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, 42, 1, 2, 3, 2, 16, 6, 50, 3, 3,
+        29, 10, 1, 8, 22, 42, 18, 46, 21, 27, 23, 9, 70, 43, 5, 10, 57, 9, 1, 13, 25, 23, 51, 17, 4,
+        8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 4, 62, 7, 1, 1, 1, 4,
+        1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6,
+        1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1, 4, 1, 2, 3, 1, 1, 1, 44, 66, 1, 3,
+        1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1, 71,
+        27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4, 93, 8,
+        2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 103, 8, 88, 33, 31, 9, 1, 45,
+        1, 7, 1, 1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6,
+        1, 2, 1, 37, 1, 2, 1, 4, 1, 1, 23, 44, 0, 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, 102, 111,
+        17, 196, 0, 97, 15, 0, 17, 6, 25, 0, 5, 0, 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, 48, 16,
+        4, 31, 21, 5, 19, 0, 45, 211, 64, 32, 25, 2, 25, 44, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 7,
+        9, 0, 41, 32, 97, 115, 0, 4, 1, 7, 1, 2, 1, 0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5,
+        13, 3, 9, 7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4,
+        2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25,
+        1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 31, 6, 6, 213, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33,
+        1, 112, 45, 10, 7, 16, 1, 0, 30, 18, 44, 0, 28, 228, 30, 2, 1, 207, 31, 1, 22, 8, 2, 224, 7,
+        1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4,
+        1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+        1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0,
+        32, 0, 2, 0, 2, 0, 15, 0, 0, 0, 0, 0, 5, 0, 0,
     ];
     #[inline]
     pub fn lookup(c: char) -> bool {
@@ -259,28 +258,27 @@ pub mod alphabetic {
 pub mod case_ignorable {
     use super::ShortOffsetRunHeader;
 
-    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 37] = [
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 36] = [
         ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(11, 4957),
         ShortOffsetRunHeader::new(263, 5906), ShortOffsetRunHeader::new(265, 8125),
-        ShortOffsetRunHeader::new(375, 11388), ShortOffsetRunHeader::new(409, 12293),
-        ShortOffsetRunHeader::new(421, 40981), ShortOffsetRunHeader::new(433, 42232),
-        ShortOffsetRunHeader::new(435, 42508), ShortOffsetRunHeader::new(437, 64286),
-        ShortOffsetRunHeader::new(533, 65024), ShortOffsetRunHeader::new(537, 66045),
-        ShortOffsetRunHeader::new(567, 67456), ShortOffsetRunHeader::new(573, 68097),
-        ShortOffsetRunHeader::new(579, 68900), ShortOffsetRunHeader::new(591, 69291),
-        ShortOffsetRunHeader::new(599, 71727), ShortOffsetRunHeader::new(723, 71995),
-        ShortOffsetRunHeader::new(727, 72752), ShortOffsetRunHeader::new(755, 73459),
-        ShortOffsetRunHeader::new(785, 78896), ShortOffsetRunHeader::new(797, 90398),
-        ShortOffsetRunHeader::new(801, 92912), ShortOffsetRunHeader::new(805, 93504),
-        ShortOffsetRunHeader::new(811, 94031), ShortOffsetRunHeader::new(815, 110576),
-        ShortOffsetRunHeader::new(823, 113821), ShortOffsetRunHeader::new(829, 118528),
-        ShortOffsetRunHeader::new(833, 119143), ShortOffsetRunHeader::new(837, 121344),
-        ShortOffsetRunHeader::new(847, 122880), ShortOffsetRunHeader::new(859, 123566),
-        ShortOffsetRunHeader::new(875, 124139), ShortOffsetRunHeader::new(879, 125136),
-        ShortOffsetRunHeader::new(883, 127995), ShortOffsetRunHeader::new(887, 917505),
-        ShortOffsetRunHeader::new(889, 2032112),
+        ShortOffsetRunHeader::new(377, 11388), ShortOffsetRunHeader::new(411, 12293),
+        ShortOffsetRunHeader::new(423, 40981), ShortOffsetRunHeader::new(435, 42232),
+        ShortOffsetRunHeader::new(437, 42508), ShortOffsetRunHeader::new(439, 64286),
+        ShortOffsetRunHeader::new(535, 65024), ShortOffsetRunHeader::new(539, 66045),
+        ShortOffsetRunHeader::new(569, 67456), ShortOffsetRunHeader::new(575, 68097),
+        ShortOffsetRunHeader::new(581, 68900), ShortOffsetRunHeader::new(593, 69291),
+        ShortOffsetRunHeader::new(601, 71727), ShortOffsetRunHeader::new(727, 71995),
+        ShortOffsetRunHeader::new(731, 73459), ShortOffsetRunHeader::new(797, 78896),
+        ShortOffsetRunHeader::new(809, 90398), ShortOffsetRunHeader::new(813, 92912),
+        ShortOffsetRunHeader::new(817, 93504), ShortOffsetRunHeader::new(823, 94031),
+        ShortOffsetRunHeader::new(827, 110576), ShortOffsetRunHeader::new(837, 113821),
+        ShortOffsetRunHeader::new(843, 118528), ShortOffsetRunHeader::new(847, 119143),
+        ShortOffsetRunHeader::new(851, 121344), ShortOffsetRunHeader::new(861, 122880),
+        ShortOffsetRunHeader::new(873, 123566), ShortOffsetRunHeader::new(889, 124139),
+        ShortOffsetRunHeader::new(893, 125136), ShortOffsetRunHeader::new(907, 127995),
+        ShortOffsetRunHeader::new(911, 917505), ShortOffsetRunHeader::new(913, 2032112),
     ];
-    static OFFSETS: [u8; 895] = [
+    static OFFSETS: [u8; 919] = [
         168, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2, 1, 1, 251, 7, 207, 1, 5, 1, 49,
         45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35, 1, 10, 21, 16, 1, 101, 8, 1, 10,
         1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24, 24, 43, 3, 44, 1, 7, 2, 5, 9, 41,
@@ -292,28 +290,29 @@ pub mod case_ignorable {
         1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3,
         16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1,
         2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58,
-        1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 31, 49, 4, 48, 1, 1, 5, 1, 1, 5, 1, 40, 9,
-        12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13, 1, 7,
-        4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2, 12, 5, 8,
-        2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, 0, 2, 113, 3, 125, 1, 15,
-        1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10, 1,
-        1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 103, 3, 3, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2,
-        26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2, 12,
-        1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5, 9,
-        3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6, 1,
-        11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9, 0,
-        3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, 26, 5, 1, 1, 0, 2, 79, 4, 70, 11, 49, 4,
-        123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3, 36, 5, 1, 8, 62,
-        1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 3,
-        1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4,
-        2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 1, 1,
-        1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1,
-        9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1,
-        7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 11, 2, 52, 5, 5, 1, 1, 1, 23, 1, 0, 17, 6, 15, 0, 12, 3,
-        3, 0, 5, 59, 7, 9, 4, 0, 3, 40, 2, 0, 1, 63, 17, 64, 2, 1, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4,
-        0, 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0,
-        7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160, 14, 0, 1, 61, 4, 0, 5, 254, 2, 0, 7, 109, 8,
-        0, 5, 0, 1, 30, 96, 128, 240, 0,
+        1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 46, 2, 12, 20, 4, 48, 1, 1, 5, 1, 1, 5, 1,
+        40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13,
+        1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2, 12,
+        5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, 0, 2, 113, 3, 125, 1,
+        15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10,
+        1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 102, 4, 3, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151,
+        2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2,
+        12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5,
+        9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6,
+        1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9,
+        0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, 26, 5, 1, 1, 0, 2, 24, 1, 52, 6, 70, 11,
+        49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3, 36, 5, 1,
+        8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57,
+        2, 3, 1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1,
+        1, 4, 2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101,
+        1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4,
+        8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2,
+        1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 65, 1, 0, 2, 11, 2, 52, 5, 5, 1, 1,
+        1, 23, 1, 0, 17, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 9, 4, 0, 3, 40, 2, 0, 1, 63, 17, 64, 2, 1,
+        2, 13, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0, 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0,
+        55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160, 14,
+        0, 1, 61, 4, 0, 5, 254, 2, 243, 1, 2, 1, 7, 2, 5, 1, 9, 1, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96,
+        128, 240, 0,
     ];
     #[inline]
     pub fn lookup(c: char) -> bool {
@@ -346,24 +345,24 @@ pub mod cased {
         ShortOffsetRunHeader::new(61, 7296), ShortOffsetRunHeader::new(65, 7958),
         ShortOffsetRunHeader::new(74, 9398), ShortOffsetRunHeader::new(149, 11264),
         ShortOffsetRunHeader::new(151, 42560), ShortOffsetRunHeader::new(163, 43824),
-        ShortOffsetRunHeader::new(183, 64256), ShortOffsetRunHeader::new(189, 65313),
-        ShortOffsetRunHeader::new(193, 66560), ShortOffsetRunHeader::new(197, 67456),
-        ShortOffsetRunHeader::new(219, 68736), ShortOffsetRunHeader::new(227, 71840),
-        ShortOffsetRunHeader::new(235, 93760), ShortOffsetRunHeader::new(237, 119808),
-        ShortOffsetRunHeader::new(239, 120486), ShortOffsetRunHeader::new(276, 122624),
-        ShortOffsetRunHeader::new(299, 122928), ShortOffsetRunHeader::new(305, 125184),
-        ShortOffsetRunHeader::new(307, 127280), ShortOffsetRunHeader::new(309, 1241482),
+        ShortOffsetRunHeader::new(177, 64256), ShortOffsetRunHeader::new(183, 65313),
+        ShortOffsetRunHeader::new(187, 66560), ShortOffsetRunHeader::new(191, 67456),
+        ShortOffsetRunHeader::new(213, 68736), ShortOffsetRunHeader::new(221, 71840),
+        ShortOffsetRunHeader::new(229, 93760), ShortOffsetRunHeader::new(231, 119808),
+        ShortOffsetRunHeader::new(237, 120486), ShortOffsetRunHeader::new(274, 122624),
+        ShortOffsetRunHeader::new(297, 122928), ShortOffsetRunHeader::new(303, 125184),
+        ShortOffsetRunHeader::new(305, 127280), ShortOffsetRunHeader::new(307, 1241482),
     ];
-    static OFFSETS: [u8; 315] = [
-        170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 1, 36, 7, 2, 30, 5, 96, 1, 42, 4,
+    static OFFSETS: [u8; 313] = [
+        170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 2, 35, 7, 2, 30, 5, 96, 1, 42, 4,
         2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9, 41, 0, 38, 1, 1,
         5, 1, 2, 43, 1, 4, 0, 86, 2, 6, 0, 11, 5, 43, 2, 3, 64, 192, 64, 0, 2, 6, 2, 38, 2, 6, 2, 8,
         1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116,
         1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 6, 4, 1, 2, 4,
         5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 0, 46, 18, 30, 132,
-        102, 3, 4, 1, 62, 2, 2, 1, 1, 1, 8, 21, 5, 1, 3, 0, 43, 1, 14, 6, 80, 0, 7, 12, 5, 0, 26, 6,
-        26, 0, 80, 96, 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 0, 1, 2, 3,
-        1, 42, 1, 9, 0, 51, 13, 51, 93, 22, 10, 22, 0, 64, 0, 64, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2,
+        102, 3, 4, 1, 77, 20, 6, 1, 3, 0, 43, 1, 14, 6, 80, 0, 7, 12, 5, 0, 26, 6, 26, 0, 80, 96,
+        36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 0, 1, 2, 3, 1, 42, 1, 9, 0,
+        51, 13, 51, 93, 22, 10, 22, 0, 64, 0, 64, 32, 25, 2, 25, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2,
         4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25,
         1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 10, 1, 20, 6, 6, 0,
         62, 0, 68, 0, 26, 6, 26, 6, 26, 0,
@@ -394,26 +393,26 @@ pub mod cased {
 pub mod grapheme_extend {
     use super::ShortOffsetRunHeader;
 
-    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 34] = [
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 33] = [
         ShortOffsetRunHeader::new(0, 768), ShortOffsetRunHeader::new(1, 1155),
         ShortOffsetRunHeader::new(3, 1425), ShortOffsetRunHeader::new(5, 4957),
         ShortOffsetRunHeader::new(249, 5906), ShortOffsetRunHeader::new(251, 8204),
-        ShortOffsetRunHeader::new(345, 11503), ShortOffsetRunHeader::new(349, 12330),
-        ShortOffsetRunHeader::new(355, 42607), ShortOffsetRunHeader::new(359, 43010),
-        ShortOffsetRunHeader::new(367, 64286), ShortOffsetRunHeader::new(433, 65024),
-        ShortOffsetRunHeader::new(435, 65438), ShortOffsetRunHeader::new(439, 66045),
-        ShortOffsetRunHeader::new(441, 68097), ShortOffsetRunHeader::new(447, 68900),
-        ShortOffsetRunHeader::new(459, 69291), ShortOffsetRunHeader::new(463, 71727),
-        ShortOffsetRunHeader::new(599, 72752), ShortOffsetRunHeader::new(631, 73459),
-        ShortOffsetRunHeader::new(661, 78912), ShortOffsetRunHeader::new(671, 90398),
-        ShortOffsetRunHeader::new(675, 92912), ShortOffsetRunHeader::new(679, 94031),
-        ShortOffsetRunHeader::new(683, 113821), ShortOffsetRunHeader::new(691, 118528),
-        ShortOffsetRunHeader::new(693, 119141), ShortOffsetRunHeader::new(697, 121344),
-        ShortOffsetRunHeader::new(709, 122880), ShortOffsetRunHeader::new(721, 123566),
-        ShortOffsetRunHeader::new(735, 124140), ShortOffsetRunHeader::new(739, 125136),
-        ShortOffsetRunHeader::new(743, 917536), ShortOffsetRunHeader::new(747, 2032112),
+        ShortOffsetRunHeader::new(347, 11503), ShortOffsetRunHeader::new(351, 12330),
+        ShortOffsetRunHeader::new(357, 42607), ShortOffsetRunHeader::new(361, 43010),
+        ShortOffsetRunHeader::new(369, 64286), ShortOffsetRunHeader::new(435, 65024),
+        ShortOffsetRunHeader::new(437, 65438), ShortOffsetRunHeader::new(441, 66045),
+        ShortOffsetRunHeader::new(443, 68097), ShortOffsetRunHeader::new(449, 68900),
+        ShortOffsetRunHeader::new(461, 69291), ShortOffsetRunHeader::new(465, 71727),
+        ShortOffsetRunHeader::new(601, 73459), ShortOffsetRunHeader::new(669, 78912),
+        ShortOffsetRunHeader::new(679, 90398), ShortOffsetRunHeader::new(683, 92912),
+        ShortOffsetRunHeader::new(687, 94031), ShortOffsetRunHeader::new(691, 113821),
+        ShortOffsetRunHeader::new(699, 118528), ShortOffsetRunHeader::new(701, 119141),
+        ShortOffsetRunHeader::new(705, 121344), ShortOffsetRunHeader::new(717, 122880),
+        ShortOffsetRunHeader::new(729, 123566), ShortOffsetRunHeader::new(743, 124140),
+        ShortOffsetRunHeader::new(747, 125136), ShortOffsetRunHeader::new(759, 917536),
+        ShortOffsetRunHeader::new(763, 2032112),
     ];
-    static OFFSETS: [u8; 751] = [
+    static OFFSETS: [u8; 767] = [
         0, 112, 0, 7, 0, 45, 1, 1, 1, 2, 1, 2, 1, 1, 72, 11, 48, 21, 16, 1, 101, 7, 2, 6, 2, 2, 1,
         4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 59, 9, 42, 24, 1, 32,
         55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2,
@@ -424,23 +423,24 @@ pub mod grapheme_extend {
         12, 8, 98, 1, 2, 9, 11, 7, 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
         102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 4, 28, 3,
         29, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 1, 1, 117, 2, 34, 1, 118, 3, 4, 2, 9,
-        1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 31, 49, 4, 48, 10, 4,
-        3, 38, 9, 12, 2, 32, 4, 2, 6, 56, 1, 1, 2, 3, 1, 1, 5, 56, 8, 2, 2, 152, 3, 1, 13, 1, 7, 4,
-        1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0, 4, 1, 10, 32,
-        2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 1, 1, 44, 3,
-        48, 1, 2, 4, 2, 2, 2, 1, 36, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3, 2, 2, 5,
-        2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1, 149, 5,
-        0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 65, 5, 0, 2, 79, 4, 70, 11, 49, 4, 123, 1, 54,
-        15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 1, 1, 8,
-        4, 2, 1, 95, 3, 2, 4, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 1, 1, 1, 1, 12, 1, 9, 1, 14,
-        7, 3, 5, 67, 1, 2, 6, 1, 1, 2, 1, 1, 3, 4, 3, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1, 81, 1,
-        2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1,
-        1, 2, 8, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 4, 4, 1, 144, 4, 2, 2, 4, 1, 32,
-        10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2,
-        122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 11, 2, 52, 5, 5, 3, 23, 1, 0, 1, 6,
-        15, 0, 12, 3, 3, 0, 5, 59, 7, 0, 1, 63, 4, 81, 1, 11, 2, 0, 2, 0, 46, 2, 23, 0, 5, 3, 6, 8,
-        8, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1,
-        5, 100, 1, 160, 7, 0, 1, 61, 4, 0, 4, 254, 2, 0, 7, 109, 7, 0, 96, 128, 240, 0,
+        1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 46, 2, 12, 20, 4, 48,
+        10, 4, 3, 38, 9, 12, 2, 32, 4, 2, 6, 56, 1, 1, 2, 3, 1, 1, 5, 56, 8, 2, 2, 152, 3, 1, 13, 1,
+        7, 4, 1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0, 4, 1,
+        10, 32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 1, 1,
+        44, 3, 48, 1, 2, 4, 2, 2, 2, 1, 36, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3,
+        2, 2, 5, 2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1,
+        149, 5, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 65, 5, 0, 2, 77, 6, 70, 11, 49, 4, 123,
+        1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9,
+        1, 1, 8, 4, 2, 1, 95, 3, 2, 4, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 1, 1, 1, 1, 12, 1, 9,
+        1, 14, 7, 3, 5, 67, 1, 2, 6, 1, 1, 2, 1, 1, 3, 4, 3, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1,
+        81, 1, 2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2,
+        106, 1, 1, 1, 2, 8, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 4, 4, 1, 144, 4, 2, 2,
+        4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6,
+        1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 11,
+        2, 52, 5, 5, 3, 23, 1, 0, 1, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 0, 1, 63, 4, 81, 1, 11, 2, 0,
+        2, 0, 46, 2, 23, 0, 5, 3, 6, 8, 8, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1,
+        15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 100, 1, 160, 7, 0, 1, 61, 4, 0, 4, 254, 2, 243, 1, 2, 1,
+        7, 2, 5, 1, 0, 7, 109, 7, 0, 96, 128, 240, 0,
     ];
     #[inline]
     pub fn lookup(c: char) -> bool {
@@ -475,27 +475,27 @@ pub mod lowercase {
     ];
     static BITSET_INDEX_CHUNKS: [[u8; 16]; 20] = [
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 56, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 43, 0, 52, 48, 50, 33],
-        [0, 0, 0, 0, 9, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 3, 0, 16, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27],
-        [0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 34, 17, 23, 53, 54, 49, 47, 7, 35, 42, 0, 28, 12, 31],
-        [0, 0, 46, 0, 56, 56, 56, 0, 22, 22, 69, 22, 36, 25, 24, 37],
-        [0, 5, 70, 0, 29, 15, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [10, 60, 0, 6, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 32, 0],
-        [16, 26, 22, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [16, 51, 2, 21, 68, 8, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [16, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [65, 41, 55, 11, 66, 63, 18, 13, 1, 64, 76, 20, 73, 74, 4, 45],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 57, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 19, 62, 0, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 44, 0, 53, 49, 51, 34],
+        [0, 0, 0, 0, 9, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 0, 3, 0, 16, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28],
+        [0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 35, 17, 24, 54, 55, 50, 48, 7, 36, 43, 0, 29, 12, 32],
+        [0, 0, 47, 0, 57, 57, 57, 0, 23, 23, 71, 23, 37, 26, 25, 38],
+        [0, 5, 72, 0, 30, 15, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [10, 61, 0, 6, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 33, 0],
+        [16, 27, 23, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [16, 52, 2, 22, 70, 8, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [16, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [67, 42, 56, 11, 68, 65, 18, 13, 1, 66, 78, 21, 75, 76, 4, 46],
     ];
-    static BITSET_CANONICAL: [u64; 56] = [
+    static BITSET_CANONICAL: [u64; 57] = [
         0b0000000000000000000000000000000000000000000000000000000000000000,
         0b0000111111111111111111111111110000000000000000000000000011111111,
         0b1010101010101010101010101010101010101010101010101010100000000010,
@@ -515,6 +515,7 @@ pub mod lowercase {
         0b1111111111111111000000000000000000000000000000000000000000000000,
         0b1111111101111111111111111111111110000000000000000000000000000000,
         0b1111110000000000000000000000000011111111111111111111111111000000,
+        0b1111100000000000000000000000000000000000000000000000000000000000,
         0b1111011111111111111111111111111111111111111111110000000000000000,
         0b1111000000000000000000000000001111110111111111111111111111111100,
         0b1010101010101010101010101010101010101010101010101101010101010100,
@@ -529,9 +530,9 @@ pub mod lowercase {
         0b0001101111111011111111111111101111111111100000000000000000000000,
         0b0001100100101111101010101010101010101010111000110111111111111111,
         0b0000011111111101111111111111111111111111111111111111111110111001,
-        0b0000011101011100000000000000000000001010101010100010010100001010,
+        0b0000011101011110000000000000000000001010101010101010010100001010,
         0b0000010000100000000001000000000000000000000000000000000000000000,
-        0b0000000111111111111111111111111111111111111011111111111111111111,
+        0b0000000111111111111111111111111111111111110011111111111111111111,
         0b0000000011111111000000001111111100000000001111110000000011111111,
         0b0000000011011100000000001111111100000000110011110000000011011100,
         0b0000000000001000010100000001101010101010101010101010101010101010,
@@ -553,10 +554,10 @@ pub mod lowercase {
         0b1110011001010001001011010010101001001110001001000011000100101001,
         0b1110101111000000000000000000000000001111111111111111111111111100,
     ];
-    static BITSET_MAPPING: [(u8, u8); 21] = [
-        (0, 64), (1, 184), (1, 182), (1, 179), (1, 172), (1, 161), (1, 146), (1, 144), (1, 140),
-        (1, 136), (1, 132), (2, 146), (2, 144), (2, 83), (3, 93), (3, 147), (3, 133), (4, 12),
-        (4, 6), (5, 187), (6, 78),
+    static BITSET_MAPPING: [(u8, u8); 22] = [
+        (0, 64), (1, 184), (1, 182), (1, 179), (1, 172), (1, 168), (1, 161), (1, 146), (1, 144),
+        (1, 140), (1, 136), (1, 132), (2, 146), (2, 144), (2, 83), (3, 93), (3, 147), (3, 133),
+        (4, 12), (4, 6), (5, 187), (6, 78),
     ];
 
     pub const fn lookup(c: char) -> bool {
@@ -576,7 +577,7 @@ pub mod lowercase {
 pub mod n {
     use super::ShortOffsetRunHeader;
 
-    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 42] = [
+    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 43] = [
         ShortOffsetRunHeader::new(0, 1632), ShortOffsetRunHeader::new(7, 2406),
         ShortOffsetRunHeader::new(13, 4160), ShortOffsetRunHeader::new(47, 4969),
         ShortOffsetRunHeader::new(51, 5870), ShortOffsetRunHeader::new(53, 6470),
@@ -590,16 +591,17 @@ pub mod n {
         ShortOffsetRunHeader::new(181, 69216), ShortOffsetRunHeader::new(187, 70736),
         ShortOffsetRunHeader::new(207, 71248), ShortOffsetRunHeader::new(211, 71904),
         ShortOffsetRunHeader::new(219, 72688), ShortOffsetRunHeader::new(223, 73552),
-        ShortOffsetRunHeader::new(231, 74752), ShortOffsetRunHeader::new(235, 90416),
-        ShortOffsetRunHeader::new(237, 92768), ShortOffsetRunHeader::new(239, 93552),
-        ShortOffsetRunHeader::new(247, 93824), ShortOffsetRunHeader::new(249, 118000),
-        ShortOffsetRunHeader::new(251, 119488), ShortOffsetRunHeader::new(253, 120782),
-        ShortOffsetRunHeader::new(259, 123200), ShortOffsetRunHeader::new(261, 123632),
-        ShortOffsetRunHeader::new(263, 124144), ShortOffsetRunHeader::new(265, 125127),
-        ShortOffsetRunHeader::new(269, 126065), ShortOffsetRunHeader::new(273, 127232),
-        ShortOffsetRunHeader::new(283, 130032), ShortOffsetRunHeader::new(285, 1244154),
+        ShortOffsetRunHeader::new(233, 74752), ShortOffsetRunHeader::new(237, 90416),
+        ShortOffsetRunHeader::new(239, 92768), ShortOffsetRunHeader::new(241, 93552),
+        ShortOffsetRunHeader::new(249, 93824), ShortOffsetRunHeader::new(251, 94196),
+        ShortOffsetRunHeader::new(253, 118000), ShortOffsetRunHeader::new(255, 119488),
+        ShortOffsetRunHeader::new(257, 120782), ShortOffsetRunHeader::new(263, 123200),
+        ShortOffsetRunHeader::new(265, 123632), ShortOffsetRunHeader::new(267, 124144),
+        ShortOffsetRunHeader::new(269, 125127), ShortOffsetRunHeader::new(273, 126065),
+        ShortOffsetRunHeader::new(277, 127232), ShortOffsetRunHeader::new(287, 130032),
+        ShortOffsetRunHeader::new(289, 1244154),
     ];
-    static OFFSETS: [u8; 287] = [
+    static OFFSETS: [u8; 291] = [
         178, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118, 10, 118,
         10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10, 70, 20,
         0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, 182, 10,
@@ -609,9 +611,9 @@ pub mod n {
         1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, 52, 2,
         30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 6, 10, 0, 31, 158, 10, 42, 4, 112, 7, 134,
         30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 6, 20, 76, 12,
-        0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 0, 10, 102, 21, 0, 111, 0, 10, 0, 10, 86, 10,
-        134, 10, 1, 7, 0, 10, 0, 23, 0, 10, 0, 20, 12, 20, 108, 25, 0, 50, 0, 10, 0, 10, 0, 10, 247,
-        10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0,
+        0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 54, 10, 0, 10, 102, 21, 0, 111, 0, 10, 0, 10,
+        86, 10, 134, 10, 1, 7, 0, 10, 0, 23, 0, 3, 0, 10, 0, 20, 12, 20, 108, 25, 0, 50, 0, 10, 0,
+        10, 0, 10, 247, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0,
     ];
     #[inline]
     pub fn lookup(c: char) -> bool {
@@ -647,28 +649,28 @@ pub mod uppercase {
     static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [
         [44, 44, 5, 35, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 5, 0],
         [44, 44, 5, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
-        [44, 44, 40, 44, 44, 44, 44, 44, 17, 17, 62, 17, 43, 29, 24, 23],
+        [44, 44, 40, 44, 44, 44, 44, 44, 17, 17, 66, 17, 43, 29, 24, 23],
         [44, 44, 44, 32, 36, 21, 22, 15, 13, 34, 44, 44, 44, 11, 30, 39],
         [44, 44, 44, 44, 9, 8, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44],
-        [44, 44, 44, 44, 37, 28, 66, 44, 44, 44, 44, 44, 44, 44, 44, 44],
+        [44, 44, 44, 44, 37, 28, 67, 44, 44, 44, 44, 44, 44, 44, 44, 44],
         [44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
         [44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 44, 44, 44],
-        [44, 44, 44, 44, 44, 44, 44, 44, 44, 49, 44, 44, 44, 44, 44, 44],
-        [44, 44, 44, 44, 44, 44, 44, 44, 44, 61, 60, 44, 20, 14, 16, 4],
+        [44, 44, 44, 44, 44, 44, 44, 44, 44, 49, 63, 44, 44, 44, 44, 44],
+        [44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 64, 44, 20, 14, 16, 4],
         [44, 44, 44, 44, 50, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
         [44, 44, 53, 44, 44, 31, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
         [44, 44, 54, 46, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
         [51, 44, 9, 47, 44, 42, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44],
-        [52, 19, 2, 18, 10, 48, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
+        [52, 19, 3, 18, 10, 48, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
         [52, 38, 17, 27, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
-        [58, 1, 26, 55, 12, 7, 25, 56, 41, 59, 6, 3, 65, 64, 63, 67],
+        [58, 1, 26, 55, 12, 7, 25, 56, 41, 59, 6, 2, 62, 61, 60, 68],
     ];
     static BITSET_CANONICAL: [u64; 44] = [
         0b0000000000111111111111111111111111111111111111111111111111111111,
         0b1111111111111111111111110000000000000000000000000011111111111111,
-        0b0101010101010101010101010101010101010101010101010101010000000001,
         0b0000011111111111111111111111110000000000000000000000000000000001,
-        0b0000000000100000000000000000000000010101010000010001101011110101,
+        0b0101010101010101010101010101010101010101010101010101010000000001,
+        0b0000000000100000000000000000000000010101010101010101101011110101,
         0b1111111111111111111111111111111100000000000000000000000000000000,
         0b1111111111111111111111110000000000000000000000000000001111111111,
         0b1111111111111111111100000000000000000000000000011111110001011111,
@@ -709,10 +711,10 @@ pub mod uppercase {
         0b1111011111111111000000000000000000000000000000000000000000000000,
         0b1111111100000000111111110000000000111111000000001111111100000000,
     ];
-    static BITSET_MAPPING: [(u8, u8); 24] = [
+    static BITSET_MAPPING: [(u8, u8); 25] = [
         (0, 182), (0, 74), (0, 166), (0, 162), (0, 159), (0, 150), (0, 148), (0, 142), (0, 134),
-        (0, 131), (0, 64), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 164), (2, 146), (2, 20),
-        (3, 146), (3, 140), (3, 134), (4, 178), (4, 171),
+        (0, 131), (0, 64), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 146), (2, 140), (2, 134),
+        (2, 130), (3, 164), (3, 146), (3, 20), (4, 178), (4, 171),
     ];
 
     pub const fn lookup(c: char) -> bool {
@@ -792,7 +794,7 @@ pub mod conversions {
         }
     }
 
-    static LOWERCASE_TABLE: &[(char, u32); 1434] = &[
+    static LOWERCASE_TABLE: &[(char, u32); 1462] = &[
         ('\u{c0}', 224), ('\u{c1}', 225), ('\u{c2}', 226), ('\u{c3}', 227), ('\u{c4}', 228),
         ('\u{c5}', 229), ('\u{c6}', 230), ('\u{c7}', 231), ('\u{c8}', 232), ('\u{c9}', 233),
         ('\u{ca}', 234), ('\u{cb}', 235), ('\u{cc}', 236), ('\u{cd}', 237), ('\u{ce}', 238),
@@ -1060,77 +1062,84 @@ pub mod conversions {
         ('\u{a7b4}', 42933), ('\u{a7b6}', 42935), ('\u{a7b8}', 42937), ('\u{a7ba}', 42939),
         ('\u{a7bc}', 42941), ('\u{a7be}', 42943), ('\u{a7c0}', 42945), ('\u{a7c2}', 42947),
         ('\u{a7c4}', 42900), ('\u{a7c5}', 642), ('\u{a7c6}', 7566), ('\u{a7c7}', 42952),
-        ('\u{a7c9}', 42954), ('\u{a7cb}', 612), ('\u{a7cc}', 42957), ('\u{a7d0}', 42961),
-        ('\u{a7d6}', 42967), ('\u{a7d8}', 42969), ('\u{a7da}', 42971), ('\u{a7dc}', 411),
-        ('\u{a7f5}', 42998), ('\u{ff21}', 65345), ('\u{ff22}', 65346), ('\u{ff23}', 65347),
-        ('\u{ff24}', 65348), ('\u{ff25}', 65349), ('\u{ff26}', 65350), ('\u{ff27}', 65351),
-        ('\u{ff28}', 65352), ('\u{ff29}', 65353), ('\u{ff2a}', 65354), ('\u{ff2b}', 65355),
-        ('\u{ff2c}', 65356), ('\u{ff2d}', 65357), ('\u{ff2e}', 65358), ('\u{ff2f}', 65359),
-        ('\u{ff30}', 65360), ('\u{ff31}', 65361), ('\u{ff32}', 65362), ('\u{ff33}', 65363),
-        ('\u{ff34}', 65364), ('\u{ff35}', 65365), ('\u{ff36}', 65366), ('\u{ff37}', 65367),
-        ('\u{ff38}', 65368), ('\u{ff39}', 65369), ('\u{ff3a}', 65370), ('\u{10400}', 66600),
-        ('\u{10401}', 66601), ('\u{10402}', 66602), ('\u{10403}', 66603), ('\u{10404}', 66604),
-        ('\u{10405}', 66605), ('\u{10406}', 66606), ('\u{10407}', 66607), ('\u{10408}', 66608),
-        ('\u{10409}', 66609), ('\u{1040a}', 66610), ('\u{1040b}', 66611), ('\u{1040c}', 66612),
-        ('\u{1040d}', 66613), ('\u{1040e}', 66614), ('\u{1040f}', 66615), ('\u{10410}', 66616),
-        ('\u{10411}', 66617), ('\u{10412}', 66618), ('\u{10413}', 66619), ('\u{10414}', 66620),
-        ('\u{10415}', 66621), ('\u{10416}', 66622), ('\u{10417}', 66623), ('\u{10418}', 66624),
-        ('\u{10419}', 66625), ('\u{1041a}', 66626), ('\u{1041b}', 66627), ('\u{1041c}', 66628),
-        ('\u{1041d}', 66629), ('\u{1041e}', 66630), ('\u{1041f}', 66631), ('\u{10420}', 66632),
-        ('\u{10421}', 66633), ('\u{10422}', 66634), ('\u{10423}', 66635), ('\u{10424}', 66636),
-        ('\u{10425}', 66637), ('\u{10426}', 66638), ('\u{10427}', 66639), ('\u{104b0}', 66776),
-        ('\u{104b1}', 66777), ('\u{104b2}', 66778), ('\u{104b3}', 66779), ('\u{104b4}', 66780),
-        ('\u{104b5}', 66781), ('\u{104b6}', 66782), ('\u{104b7}', 66783), ('\u{104b8}', 66784),
-        ('\u{104b9}', 66785), ('\u{104ba}', 66786), ('\u{104bb}', 66787), ('\u{104bc}', 66788),
-        ('\u{104bd}', 66789), ('\u{104be}', 66790), ('\u{104bf}', 66791), ('\u{104c0}', 66792),
-        ('\u{104c1}', 66793), ('\u{104c2}', 66794), ('\u{104c3}', 66795), ('\u{104c4}', 66796),
-        ('\u{104c5}', 66797), ('\u{104c6}', 66798), ('\u{104c7}', 66799), ('\u{104c8}', 66800),
-        ('\u{104c9}', 66801), ('\u{104ca}', 66802), ('\u{104cb}', 66803), ('\u{104cc}', 66804),
-        ('\u{104cd}', 66805), ('\u{104ce}', 66806), ('\u{104cf}', 66807), ('\u{104d0}', 66808),
-        ('\u{104d1}', 66809), ('\u{104d2}', 66810), ('\u{104d3}', 66811), ('\u{10570}', 66967),
-        ('\u{10571}', 66968), ('\u{10572}', 66969), ('\u{10573}', 66970), ('\u{10574}', 66971),
-        ('\u{10575}', 66972), ('\u{10576}', 66973), ('\u{10577}', 66974), ('\u{10578}', 66975),
-        ('\u{10579}', 66976), ('\u{1057a}', 66977), ('\u{1057c}', 66979), ('\u{1057d}', 66980),
-        ('\u{1057e}', 66981), ('\u{1057f}', 66982), ('\u{10580}', 66983), ('\u{10581}', 66984),
-        ('\u{10582}', 66985), ('\u{10583}', 66986), ('\u{10584}', 66987), ('\u{10585}', 66988),
-        ('\u{10586}', 66989), ('\u{10587}', 66990), ('\u{10588}', 66991), ('\u{10589}', 66992),
-        ('\u{1058a}', 66993), ('\u{1058c}', 66995), ('\u{1058d}', 66996), ('\u{1058e}', 66997),
-        ('\u{1058f}', 66998), ('\u{10590}', 66999), ('\u{10591}', 67000), ('\u{10592}', 67001),
-        ('\u{10594}', 67003), ('\u{10595}', 67004), ('\u{10c80}', 68800), ('\u{10c81}', 68801),
-        ('\u{10c82}', 68802), ('\u{10c83}', 68803), ('\u{10c84}', 68804), ('\u{10c85}', 68805),
-        ('\u{10c86}', 68806), ('\u{10c87}', 68807), ('\u{10c88}', 68808), ('\u{10c89}', 68809),
-        ('\u{10c8a}', 68810), ('\u{10c8b}', 68811), ('\u{10c8c}', 68812), ('\u{10c8d}', 68813),
-        ('\u{10c8e}', 68814), ('\u{10c8f}', 68815), ('\u{10c90}', 68816), ('\u{10c91}', 68817),
-        ('\u{10c92}', 68818), ('\u{10c93}', 68819), ('\u{10c94}', 68820), ('\u{10c95}', 68821),
-        ('\u{10c96}', 68822), ('\u{10c97}', 68823), ('\u{10c98}', 68824), ('\u{10c99}', 68825),
-        ('\u{10c9a}', 68826), ('\u{10c9b}', 68827), ('\u{10c9c}', 68828), ('\u{10c9d}', 68829),
-        ('\u{10c9e}', 68830), ('\u{10c9f}', 68831), ('\u{10ca0}', 68832), ('\u{10ca1}', 68833),
-        ('\u{10ca2}', 68834), ('\u{10ca3}', 68835), ('\u{10ca4}', 68836), ('\u{10ca5}', 68837),
-        ('\u{10ca6}', 68838), ('\u{10ca7}', 68839), ('\u{10ca8}', 68840), ('\u{10ca9}', 68841),
-        ('\u{10caa}', 68842), ('\u{10cab}', 68843), ('\u{10cac}', 68844), ('\u{10cad}', 68845),
-        ('\u{10cae}', 68846), ('\u{10caf}', 68847), ('\u{10cb0}', 68848), ('\u{10cb1}', 68849),
-        ('\u{10cb2}', 68850), ('\u{10d50}', 68976), ('\u{10d51}', 68977), ('\u{10d52}', 68978),
-        ('\u{10d53}', 68979), ('\u{10d54}', 68980), ('\u{10d55}', 68981), ('\u{10d56}', 68982),
-        ('\u{10d57}', 68983), ('\u{10d58}', 68984), ('\u{10d59}', 68985), ('\u{10d5a}', 68986),
-        ('\u{10d5b}', 68987), ('\u{10d5c}', 68988), ('\u{10d5d}', 68989), ('\u{10d5e}', 68990),
-        ('\u{10d5f}', 68991), ('\u{10d60}', 68992), ('\u{10d61}', 68993), ('\u{10d62}', 68994),
-        ('\u{10d63}', 68995), ('\u{10d64}', 68996), ('\u{10d65}', 68997), ('\u{118a0}', 71872),
-        ('\u{118a1}', 71873), ('\u{118a2}', 71874), ('\u{118a3}', 71875), ('\u{118a4}', 71876),
-        ('\u{118a5}', 71877), ('\u{118a6}', 71878), ('\u{118a7}', 71879), ('\u{118a8}', 71880),
-        ('\u{118a9}', 71881), ('\u{118aa}', 71882), ('\u{118ab}', 71883), ('\u{118ac}', 71884),
-        ('\u{118ad}', 71885), ('\u{118ae}', 71886), ('\u{118af}', 71887), ('\u{118b0}', 71888),
-        ('\u{118b1}', 71889), ('\u{118b2}', 71890), ('\u{118b3}', 71891), ('\u{118b4}', 71892),
-        ('\u{118b5}', 71893), ('\u{118b6}', 71894), ('\u{118b7}', 71895), ('\u{118b8}', 71896),
-        ('\u{118b9}', 71897), ('\u{118ba}', 71898), ('\u{118bb}', 71899), ('\u{118bc}', 71900),
-        ('\u{118bd}', 71901), ('\u{118be}', 71902), ('\u{118bf}', 71903), ('\u{16e40}', 93792),
-        ('\u{16e41}', 93793), ('\u{16e42}', 93794), ('\u{16e43}', 93795), ('\u{16e44}', 93796),
-        ('\u{16e45}', 93797), ('\u{16e46}', 93798), ('\u{16e47}', 93799), ('\u{16e48}', 93800),
-        ('\u{16e49}', 93801), ('\u{16e4a}', 93802), ('\u{16e4b}', 93803), ('\u{16e4c}', 93804),
-        ('\u{16e4d}', 93805), ('\u{16e4e}', 93806), ('\u{16e4f}', 93807), ('\u{16e50}', 93808),
-        ('\u{16e51}', 93809), ('\u{16e52}', 93810), ('\u{16e53}', 93811), ('\u{16e54}', 93812),
-        ('\u{16e55}', 93813), ('\u{16e56}', 93814), ('\u{16e57}', 93815), ('\u{16e58}', 93816),
-        ('\u{16e59}', 93817), ('\u{16e5a}', 93818), ('\u{16e5b}', 93819), ('\u{16e5c}', 93820),
-        ('\u{16e5d}', 93821), ('\u{16e5e}', 93822), ('\u{16e5f}', 93823), ('\u{1e900}', 125218),
+        ('\u{a7c9}', 42954), ('\u{a7cb}', 612), ('\u{a7cc}', 42957), ('\u{a7ce}', 42959),
+        ('\u{a7d0}', 42961), ('\u{a7d2}', 42963), ('\u{a7d4}', 42965), ('\u{a7d6}', 42967),
+        ('\u{a7d8}', 42969), ('\u{a7da}', 42971), ('\u{a7dc}', 411), ('\u{a7f5}', 42998),
+        ('\u{ff21}', 65345), ('\u{ff22}', 65346), ('\u{ff23}', 65347), ('\u{ff24}', 65348),
+        ('\u{ff25}', 65349), ('\u{ff26}', 65350), ('\u{ff27}', 65351), ('\u{ff28}', 65352),
+        ('\u{ff29}', 65353), ('\u{ff2a}', 65354), ('\u{ff2b}', 65355), ('\u{ff2c}', 65356),
+        ('\u{ff2d}', 65357), ('\u{ff2e}', 65358), ('\u{ff2f}', 65359), ('\u{ff30}', 65360),
+        ('\u{ff31}', 65361), ('\u{ff32}', 65362), ('\u{ff33}', 65363), ('\u{ff34}', 65364),
+        ('\u{ff35}', 65365), ('\u{ff36}', 65366), ('\u{ff37}', 65367), ('\u{ff38}', 65368),
+        ('\u{ff39}', 65369), ('\u{ff3a}', 65370), ('\u{10400}', 66600), ('\u{10401}', 66601),
+        ('\u{10402}', 66602), ('\u{10403}', 66603), ('\u{10404}', 66604), ('\u{10405}', 66605),
+        ('\u{10406}', 66606), ('\u{10407}', 66607), ('\u{10408}', 66608), ('\u{10409}', 66609),
+        ('\u{1040a}', 66610), ('\u{1040b}', 66611), ('\u{1040c}', 66612), ('\u{1040d}', 66613),
+        ('\u{1040e}', 66614), ('\u{1040f}', 66615), ('\u{10410}', 66616), ('\u{10411}', 66617),
+        ('\u{10412}', 66618), ('\u{10413}', 66619), ('\u{10414}', 66620), ('\u{10415}', 66621),
+        ('\u{10416}', 66622), ('\u{10417}', 66623), ('\u{10418}', 66624), ('\u{10419}', 66625),
+        ('\u{1041a}', 66626), ('\u{1041b}', 66627), ('\u{1041c}', 66628), ('\u{1041d}', 66629),
+        ('\u{1041e}', 66630), ('\u{1041f}', 66631), ('\u{10420}', 66632), ('\u{10421}', 66633),
+        ('\u{10422}', 66634), ('\u{10423}', 66635), ('\u{10424}', 66636), ('\u{10425}', 66637),
+        ('\u{10426}', 66638), ('\u{10427}', 66639), ('\u{104b0}', 66776), ('\u{104b1}', 66777),
+        ('\u{104b2}', 66778), ('\u{104b3}', 66779), ('\u{104b4}', 66780), ('\u{104b5}', 66781),
+        ('\u{104b6}', 66782), ('\u{104b7}', 66783), ('\u{104b8}', 66784), ('\u{104b9}', 66785),
+        ('\u{104ba}', 66786), ('\u{104bb}', 66787), ('\u{104bc}', 66788), ('\u{104bd}', 66789),
+        ('\u{104be}', 66790), ('\u{104bf}', 66791), ('\u{104c0}', 66792), ('\u{104c1}', 66793),
+        ('\u{104c2}', 66794), ('\u{104c3}', 66795), ('\u{104c4}', 66796), ('\u{104c5}', 66797),
+        ('\u{104c6}', 66798), ('\u{104c7}', 66799), ('\u{104c8}', 66800), ('\u{104c9}', 66801),
+        ('\u{104ca}', 66802), ('\u{104cb}', 66803), ('\u{104cc}', 66804), ('\u{104cd}', 66805),
+        ('\u{104ce}', 66806), ('\u{104cf}', 66807), ('\u{104d0}', 66808), ('\u{104d1}', 66809),
+        ('\u{104d2}', 66810), ('\u{104d3}', 66811), ('\u{10570}', 66967), ('\u{10571}', 66968),
+        ('\u{10572}', 66969), ('\u{10573}', 66970), ('\u{10574}', 66971), ('\u{10575}', 66972),
+        ('\u{10576}', 66973), ('\u{10577}', 66974), ('\u{10578}', 66975), ('\u{10579}', 66976),
+        ('\u{1057a}', 66977), ('\u{1057c}', 66979), ('\u{1057d}', 66980), ('\u{1057e}', 66981),
+        ('\u{1057f}', 66982), ('\u{10580}', 66983), ('\u{10581}', 66984), ('\u{10582}', 66985),
+        ('\u{10583}', 66986), ('\u{10584}', 66987), ('\u{10585}', 66988), ('\u{10586}', 66989),
+        ('\u{10587}', 66990), ('\u{10588}', 66991), ('\u{10589}', 66992), ('\u{1058a}', 66993),
+        ('\u{1058c}', 66995), ('\u{1058d}', 66996), ('\u{1058e}', 66997), ('\u{1058f}', 66998),
+        ('\u{10590}', 66999), ('\u{10591}', 67000), ('\u{10592}', 67001), ('\u{10594}', 67003),
+        ('\u{10595}', 67004), ('\u{10c80}', 68800), ('\u{10c81}', 68801), ('\u{10c82}', 68802),
+        ('\u{10c83}', 68803), ('\u{10c84}', 68804), ('\u{10c85}', 68805), ('\u{10c86}', 68806),
+        ('\u{10c87}', 68807), ('\u{10c88}', 68808), ('\u{10c89}', 68809), ('\u{10c8a}', 68810),
+        ('\u{10c8b}', 68811), ('\u{10c8c}', 68812), ('\u{10c8d}', 68813), ('\u{10c8e}', 68814),
+        ('\u{10c8f}', 68815), ('\u{10c90}', 68816), ('\u{10c91}', 68817), ('\u{10c92}', 68818),
+        ('\u{10c93}', 68819), ('\u{10c94}', 68820), ('\u{10c95}', 68821), ('\u{10c96}', 68822),
+        ('\u{10c97}', 68823), ('\u{10c98}', 68824), ('\u{10c99}', 68825), ('\u{10c9a}', 68826),
+        ('\u{10c9b}', 68827), ('\u{10c9c}', 68828), ('\u{10c9d}', 68829), ('\u{10c9e}', 68830),
+        ('\u{10c9f}', 68831), ('\u{10ca0}', 68832), ('\u{10ca1}', 68833), ('\u{10ca2}', 68834),
+        ('\u{10ca3}', 68835), ('\u{10ca4}', 68836), ('\u{10ca5}', 68837), ('\u{10ca6}', 68838),
+        ('\u{10ca7}', 68839), ('\u{10ca8}', 68840), ('\u{10ca9}', 68841), ('\u{10caa}', 68842),
+        ('\u{10cab}', 68843), ('\u{10cac}', 68844), ('\u{10cad}', 68845), ('\u{10cae}', 68846),
+        ('\u{10caf}', 68847), ('\u{10cb0}', 68848), ('\u{10cb1}', 68849), ('\u{10cb2}', 68850),
+        ('\u{10d50}', 68976), ('\u{10d51}', 68977), ('\u{10d52}', 68978), ('\u{10d53}', 68979),
+        ('\u{10d54}', 68980), ('\u{10d55}', 68981), ('\u{10d56}', 68982), ('\u{10d57}', 68983),
+        ('\u{10d58}', 68984), ('\u{10d59}', 68985), ('\u{10d5a}', 68986), ('\u{10d5b}', 68987),
+        ('\u{10d5c}', 68988), ('\u{10d5d}', 68989), ('\u{10d5e}', 68990), ('\u{10d5f}', 68991),
+        ('\u{10d60}', 68992), ('\u{10d61}', 68993), ('\u{10d62}', 68994), ('\u{10d63}', 68995),
+        ('\u{10d64}', 68996), ('\u{10d65}', 68997), ('\u{118a0}', 71872), ('\u{118a1}', 71873),
+        ('\u{118a2}', 71874), ('\u{118a3}', 71875), ('\u{118a4}', 71876), ('\u{118a5}', 71877),
+        ('\u{118a6}', 71878), ('\u{118a7}', 71879), ('\u{118a8}', 71880), ('\u{118a9}', 71881),
+        ('\u{118aa}', 71882), ('\u{118ab}', 71883), ('\u{118ac}', 71884), ('\u{118ad}', 71885),
+        ('\u{118ae}', 71886), ('\u{118af}', 71887), ('\u{118b0}', 71888), ('\u{118b1}', 71889),
+        ('\u{118b2}', 71890), ('\u{118b3}', 71891), ('\u{118b4}', 71892), ('\u{118b5}', 71893),
+        ('\u{118b6}', 71894), ('\u{118b7}', 71895), ('\u{118b8}', 71896), ('\u{118b9}', 71897),
+        ('\u{118ba}', 71898), ('\u{118bb}', 71899), ('\u{118bc}', 71900), ('\u{118bd}', 71901),
+        ('\u{118be}', 71902), ('\u{118bf}', 71903), ('\u{16e40}', 93792), ('\u{16e41}', 93793),
+        ('\u{16e42}', 93794), ('\u{16e43}', 93795), ('\u{16e44}', 93796), ('\u{16e45}', 93797),
+        ('\u{16e46}', 93798), ('\u{16e47}', 93799), ('\u{16e48}', 93800), ('\u{16e49}', 93801),
+        ('\u{16e4a}', 93802), ('\u{16e4b}', 93803), ('\u{16e4c}', 93804), ('\u{16e4d}', 93805),
+        ('\u{16e4e}', 93806), ('\u{16e4f}', 93807), ('\u{16e50}', 93808), ('\u{16e51}', 93809),
+        ('\u{16e52}', 93810), ('\u{16e53}', 93811), ('\u{16e54}', 93812), ('\u{16e55}', 93813),
+        ('\u{16e56}', 93814), ('\u{16e57}', 93815), ('\u{16e58}', 93816), ('\u{16e59}', 93817),
+        ('\u{16e5a}', 93818), ('\u{16e5b}', 93819), ('\u{16e5c}', 93820), ('\u{16e5d}', 93821),
+        ('\u{16e5e}', 93822), ('\u{16e5f}', 93823), ('\u{16ea0}', 93883), ('\u{16ea1}', 93884),
+        ('\u{16ea2}', 93885), ('\u{16ea3}', 93886), ('\u{16ea4}', 93887), ('\u{16ea5}', 93888),
+        ('\u{16ea6}', 93889), ('\u{16ea7}', 93890), ('\u{16ea8}', 93891), ('\u{16ea9}', 93892),
+        ('\u{16eaa}', 93893), ('\u{16eab}', 93894), ('\u{16eac}', 93895), ('\u{16ead}', 93896),
+        ('\u{16eae}', 93897), ('\u{16eaf}', 93898), ('\u{16eb0}', 93899), ('\u{16eb1}', 93900),
+        ('\u{16eb2}', 93901), ('\u{16eb3}', 93902), ('\u{16eb4}', 93903), ('\u{16eb5}', 93904),
+        ('\u{16eb6}', 93905), ('\u{16eb7}', 93906), ('\u{16eb8}', 93907), ('\u{1e900}', 125218),
         ('\u{1e901}', 125219), ('\u{1e902}', 125220), ('\u{1e903}', 125221), ('\u{1e904}', 125222),
         ('\u{1e905}', 125223), ('\u{1e906}', 125224), ('\u{1e907}', 125225), ('\u{1e908}', 125226),
         ('\u{1e909}', 125227), ('\u{1e90a}', 125228), ('\u{1e90b}', 125229), ('\u{1e90c}', 125230),
@@ -1146,7 +1155,7 @@ pub mod conversions {
         ['i', '\u{307}', '\u{0}'],
     ];
 
-    static UPPERCASE_TABLE: &[(char, u32); 1526] = &[
+    static UPPERCASE_TABLE: &[(char, u32); 1554] = &[
         ('\u{b5}', 924), ('\u{df}', 4194304), ('\u{e0}', 192), ('\u{e1}', 193), ('\u{e2}', 194),
         ('\u{e3}', 195), ('\u{e4}', 196), ('\u{e5}', 197), ('\u{e6}', 198), ('\u{e7}', 199),
         ('\u{e8}', 200), ('\u{e9}', 201), ('\u{ea}', 202), ('\u{eb}', 203), ('\u{ec}', 204),
@@ -1415,100 +1424,107 @@ pub mod conversions {
         ('\u{a7a7}', 42918), ('\u{a7a9}', 42920), ('\u{a7b5}', 42932), ('\u{a7b7}', 42934),
         ('\u{a7b9}', 42936), ('\u{a7bb}', 42938), ('\u{a7bd}', 42940), ('\u{a7bf}', 42942),
         ('\u{a7c1}', 42944), ('\u{a7c3}', 42946), ('\u{a7c8}', 42951), ('\u{a7ca}', 42953),
-        ('\u{a7cd}', 42956), ('\u{a7d1}', 42960), ('\u{a7d7}', 42966), ('\u{a7d9}', 42968),
-        ('\u{a7db}', 42970), ('\u{a7f6}', 42997), ('\u{ab53}', 42931), ('\u{ab70}', 5024),
-        ('\u{ab71}', 5025), ('\u{ab72}', 5026), ('\u{ab73}', 5027), ('\u{ab74}', 5028),
-        ('\u{ab75}', 5029), ('\u{ab76}', 5030), ('\u{ab77}', 5031), ('\u{ab78}', 5032),
-        ('\u{ab79}', 5033), ('\u{ab7a}', 5034), ('\u{ab7b}', 5035), ('\u{ab7c}', 5036),
-        ('\u{ab7d}', 5037), ('\u{ab7e}', 5038), ('\u{ab7f}', 5039), ('\u{ab80}', 5040),
-        ('\u{ab81}', 5041), ('\u{ab82}', 5042), ('\u{ab83}', 5043), ('\u{ab84}', 5044),
-        ('\u{ab85}', 5045), ('\u{ab86}', 5046), ('\u{ab87}', 5047), ('\u{ab88}', 5048),
-        ('\u{ab89}', 5049), ('\u{ab8a}', 5050), ('\u{ab8b}', 5051), ('\u{ab8c}', 5052),
-        ('\u{ab8d}', 5053), ('\u{ab8e}', 5054), ('\u{ab8f}', 5055), ('\u{ab90}', 5056),
-        ('\u{ab91}', 5057), ('\u{ab92}', 5058), ('\u{ab93}', 5059), ('\u{ab94}', 5060),
-        ('\u{ab95}', 5061), ('\u{ab96}', 5062), ('\u{ab97}', 5063), ('\u{ab98}', 5064),
-        ('\u{ab99}', 5065), ('\u{ab9a}', 5066), ('\u{ab9b}', 5067), ('\u{ab9c}', 5068),
-        ('\u{ab9d}', 5069), ('\u{ab9e}', 5070), ('\u{ab9f}', 5071), ('\u{aba0}', 5072),
-        ('\u{aba1}', 5073), ('\u{aba2}', 5074), ('\u{aba3}', 5075), ('\u{aba4}', 5076),
-        ('\u{aba5}', 5077), ('\u{aba6}', 5078), ('\u{aba7}', 5079), ('\u{aba8}', 5080),
-        ('\u{aba9}', 5081), ('\u{abaa}', 5082), ('\u{abab}', 5083), ('\u{abac}', 5084),
-        ('\u{abad}', 5085), ('\u{abae}', 5086), ('\u{abaf}', 5087), ('\u{abb0}', 5088),
-        ('\u{abb1}', 5089), ('\u{abb2}', 5090), ('\u{abb3}', 5091), ('\u{abb4}', 5092),
-        ('\u{abb5}', 5093), ('\u{abb6}', 5094), ('\u{abb7}', 5095), ('\u{abb8}', 5096),
-        ('\u{abb9}', 5097), ('\u{abba}', 5098), ('\u{abbb}', 5099), ('\u{abbc}', 5100),
-        ('\u{abbd}', 5101), ('\u{abbe}', 5102), ('\u{abbf}', 5103), ('\u{fb00}', 4194394),
-        ('\u{fb01}', 4194395), ('\u{fb02}', 4194396), ('\u{fb03}', 4194397), ('\u{fb04}', 4194398),
-        ('\u{fb05}', 4194399), ('\u{fb06}', 4194400), ('\u{fb13}', 4194401), ('\u{fb14}', 4194402),
-        ('\u{fb15}', 4194403), ('\u{fb16}', 4194404), ('\u{fb17}', 4194405), ('\u{ff41}', 65313),
-        ('\u{ff42}', 65314), ('\u{ff43}', 65315), ('\u{ff44}', 65316), ('\u{ff45}', 65317),
-        ('\u{ff46}', 65318), ('\u{ff47}', 65319), ('\u{ff48}', 65320), ('\u{ff49}', 65321),
-        ('\u{ff4a}', 65322), ('\u{ff4b}', 65323), ('\u{ff4c}', 65324), ('\u{ff4d}', 65325),
-        ('\u{ff4e}', 65326), ('\u{ff4f}', 65327), ('\u{ff50}', 65328), ('\u{ff51}', 65329),
-        ('\u{ff52}', 65330), ('\u{ff53}', 65331), ('\u{ff54}', 65332), ('\u{ff55}', 65333),
-        ('\u{ff56}', 65334), ('\u{ff57}', 65335), ('\u{ff58}', 65336), ('\u{ff59}', 65337),
-        ('\u{ff5a}', 65338), ('\u{10428}', 66560), ('\u{10429}', 66561), ('\u{1042a}', 66562),
-        ('\u{1042b}', 66563), ('\u{1042c}', 66564), ('\u{1042d}', 66565), ('\u{1042e}', 66566),
-        ('\u{1042f}', 66567), ('\u{10430}', 66568), ('\u{10431}', 66569), ('\u{10432}', 66570),
-        ('\u{10433}', 66571), ('\u{10434}', 66572), ('\u{10435}', 66573), ('\u{10436}', 66574),
-        ('\u{10437}', 66575), ('\u{10438}', 66576), ('\u{10439}', 66577), ('\u{1043a}', 66578),
-        ('\u{1043b}', 66579), ('\u{1043c}', 66580), ('\u{1043d}', 66581), ('\u{1043e}', 66582),
-        ('\u{1043f}', 66583), ('\u{10440}', 66584), ('\u{10441}', 66585), ('\u{10442}', 66586),
-        ('\u{10443}', 66587), ('\u{10444}', 66588), ('\u{10445}', 66589), ('\u{10446}', 66590),
-        ('\u{10447}', 66591), ('\u{10448}', 66592), ('\u{10449}', 66593), ('\u{1044a}', 66594),
-        ('\u{1044b}', 66595), ('\u{1044c}', 66596), ('\u{1044d}', 66597), ('\u{1044e}', 66598),
-        ('\u{1044f}', 66599), ('\u{104d8}', 66736), ('\u{104d9}', 66737), ('\u{104da}', 66738),
-        ('\u{104db}', 66739), ('\u{104dc}', 66740), ('\u{104dd}', 66741), ('\u{104de}', 66742),
-        ('\u{104df}', 66743), ('\u{104e0}', 66744), ('\u{104e1}', 66745), ('\u{104e2}', 66746),
-        ('\u{104e3}', 66747), ('\u{104e4}', 66748), ('\u{104e5}', 66749), ('\u{104e6}', 66750),
-        ('\u{104e7}', 66751), ('\u{104e8}', 66752), ('\u{104e9}', 66753), ('\u{104ea}', 66754),
-        ('\u{104eb}', 66755), ('\u{104ec}', 66756), ('\u{104ed}', 66757), ('\u{104ee}', 66758),
-        ('\u{104ef}', 66759), ('\u{104f0}', 66760), ('\u{104f1}', 66761), ('\u{104f2}', 66762),
-        ('\u{104f3}', 66763), ('\u{104f4}', 66764), ('\u{104f5}', 66765), ('\u{104f6}', 66766),
-        ('\u{104f7}', 66767), ('\u{104f8}', 66768), ('\u{104f9}', 66769), ('\u{104fa}', 66770),
-        ('\u{104fb}', 66771), ('\u{10597}', 66928), ('\u{10598}', 66929), ('\u{10599}', 66930),
-        ('\u{1059a}', 66931), ('\u{1059b}', 66932), ('\u{1059c}', 66933), ('\u{1059d}', 66934),
-        ('\u{1059e}', 66935), ('\u{1059f}', 66936), ('\u{105a0}', 66937), ('\u{105a1}', 66938),
-        ('\u{105a3}', 66940), ('\u{105a4}', 66941), ('\u{105a5}', 66942), ('\u{105a6}', 66943),
-        ('\u{105a7}', 66944), ('\u{105a8}', 66945), ('\u{105a9}', 66946), ('\u{105aa}', 66947),
-        ('\u{105ab}', 66948), ('\u{105ac}', 66949), ('\u{105ad}', 66950), ('\u{105ae}', 66951),
-        ('\u{105af}', 66952), ('\u{105b0}', 66953), ('\u{105b1}', 66954), ('\u{105b3}', 66956),
-        ('\u{105b4}', 66957), ('\u{105b5}', 66958), ('\u{105b6}', 66959), ('\u{105b7}', 66960),
-        ('\u{105b8}', 66961), ('\u{105b9}', 66962), ('\u{105bb}', 66964), ('\u{105bc}', 66965),
-        ('\u{10cc0}', 68736), ('\u{10cc1}', 68737), ('\u{10cc2}', 68738), ('\u{10cc3}', 68739),
-        ('\u{10cc4}', 68740), ('\u{10cc5}', 68741), ('\u{10cc6}', 68742), ('\u{10cc7}', 68743),
-        ('\u{10cc8}', 68744), ('\u{10cc9}', 68745), ('\u{10cca}', 68746), ('\u{10ccb}', 68747),
-        ('\u{10ccc}', 68748), ('\u{10ccd}', 68749), ('\u{10cce}', 68750), ('\u{10ccf}', 68751),
-        ('\u{10cd0}', 68752), ('\u{10cd1}', 68753), ('\u{10cd2}', 68754), ('\u{10cd3}', 68755),
-        ('\u{10cd4}', 68756), ('\u{10cd5}', 68757), ('\u{10cd6}', 68758), ('\u{10cd7}', 68759),
-        ('\u{10cd8}', 68760), ('\u{10cd9}', 68761), ('\u{10cda}', 68762), ('\u{10cdb}', 68763),
-        ('\u{10cdc}', 68764), ('\u{10cdd}', 68765), ('\u{10cde}', 68766), ('\u{10cdf}', 68767),
-        ('\u{10ce0}', 68768), ('\u{10ce1}', 68769), ('\u{10ce2}', 68770), ('\u{10ce3}', 68771),
-        ('\u{10ce4}', 68772), ('\u{10ce5}', 68773), ('\u{10ce6}', 68774), ('\u{10ce7}', 68775),
-        ('\u{10ce8}', 68776), ('\u{10ce9}', 68777), ('\u{10cea}', 68778), ('\u{10ceb}', 68779),
-        ('\u{10cec}', 68780), ('\u{10ced}', 68781), ('\u{10cee}', 68782), ('\u{10cef}', 68783),
-        ('\u{10cf0}', 68784), ('\u{10cf1}', 68785), ('\u{10cf2}', 68786), ('\u{10d70}', 68944),
-        ('\u{10d71}', 68945), ('\u{10d72}', 68946), ('\u{10d73}', 68947), ('\u{10d74}', 68948),
-        ('\u{10d75}', 68949), ('\u{10d76}', 68950), ('\u{10d77}', 68951), ('\u{10d78}', 68952),
-        ('\u{10d79}', 68953), ('\u{10d7a}', 68954), ('\u{10d7b}', 68955), ('\u{10d7c}', 68956),
-        ('\u{10d7d}', 68957), ('\u{10d7e}', 68958), ('\u{10d7f}', 68959), ('\u{10d80}', 68960),
-        ('\u{10d81}', 68961), ('\u{10d82}', 68962), ('\u{10d83}', 68963), ('\u{10d84}', 68964),
-        ('\u{10d85}', 68965), ('\u{118c0}', 71840), ('\u{118c1}', 71841), ('\u{118c2}', 71842),
-        ('\u{118c3}', 71843), ('\u{118c4}', 71844), ('\u{118c5}', 71845), ('\u{118c6}', 71846),
-        ('\u{118c7}', 71847), ('\u{118c8}', 71848), ('\u{118c9}', 71849), ('\u{118ca}', 71850),
-        ('\u{118cb}', 71851), ('\u{118cc}', 71852), ('\u{118cd}', 71853), ('\u{118ce}', 71854),
-        ('\u{118cf}', 71855), ('\u{118d0}', 71856), ('\u{118d1}', 71857), ('\u{118d2}', 71858),
-        ('\u{118d3}', 71859), ('\u{118d4}', 71860), ('\u{118d5}', 71861), ('\u{118d6}', 71862),
-        ('\u{118d7}', 71863), ('\u{118d8}', 71864), ('\u{118d9}', 71865), ('\u{118da}', 71866),
-        ('\u{118db}', 71867), ('\u{118dc}', 71868), ('\u{118dd}', 71869), ('\u{118de}', 71870),
-        ('\u{118df}', 71871), ('\u{16e60}', 93760), ('\u{16e61}', 93761), ('\u{16e62}', 93762),
-        ('\u{16e63}', 93763), ('\u{16e64}', 93764), ('\u{16e65}', 93765), ('\u{16e66}', 93766),
-        ('\u{16e67}', 93767), ('\u{16e68}', 93768), ('\u{16e69}', 93769), ('\u{16e6a}', 93770),
-        ('\u{16e6b}', 93771), ('\u{16e6c}', 93772), ('\u{16e6d}', 93773), ('\u{16e6e}', 93774),
-        ('\u{16e6f}', 93775), ('\u{16e70}', 93776), ('\u{16e71}', 93777), ('\u{16e72}', 93778),
-        ('\u{16e73}', 93779), ('\u{16e74}', 93780), ('\u{16e75}', 93781), ('\u{16e76}', 93782),
-        ('\u{16e77}', 93783), ('\u{16e78}', 93784), ('\u{16e79}', 93785), ('\u{16e7a}', 93786),
-        ('\u{16e7b}', 93787), ('\u{16e7c}', 93788), ('\u{16e7d}', 93789), ('\u{16e7e}', 93790),
-        ('\u{16e7f}', 93791), ('\u{1e922}', 125184), ('\u{1e923}', 125185), ('\u{1e924}', 125186),
+        ('\u{a7cd}', 42956), ('\u{a7cf}', 42958), ('\u{a7d1}', 42960), ('\u{a7d3}', 42962),
+        ('\u{a7d5}', 42964), ('\u{a7d7}', 42966), ('\u{a7d9}', 42968), ('\u{a7db}', 42970),
+        ('\u{a7f6}', 42997), ('\u{ab53}', 42931), ('\u{ab70}', 5024), ('\u{ab71}', 5025),
+        ('\u{ab72}', 5026), ('\u{ab73}', 5027), ('\u{ab74}', 5028), ('\u{ab75}', 5029),
+        ('\u{ab76}', 5030), ('\u{ab77}', 5031), ('\u{ab78}', 5032), ('\u{ab79}', 5033),
+        ('\u{ab7a}', 5034), ('\u{ab7b}', 5035), ('\u{ab7c}', 5036), ('\u{ab7d}', 5037),
+        ('\u{ab7e}', 5038), ('\u{ab7f}', 5039), ('\u{ab80}', 5040), ('\u{ab81}', 5041),
+        ('\u{ab82}', 5042), ('\u{ab83}', 5043), ('\u{ab84}', 5044), ('\u{ab85}', 5045),
+        ('\u{ab86}', 5046), ('\u{ab87}', 5047), ('\u{ab88}', 5048), ('\u{ab89}', 5049),
+        ('\u{ab8a}', 5050), ('\u{ab8b}', 5051), ('\u{ab8c}', 5052), ('\u{ab8d}', 5053),
+        ('\u{ab8e}', 5054), ('\u{ab8f}', 5055), ('\u{ab90}', 5056), ('\u{ab91}', 5057),
+        ('\u{ab92}', 5058), ('\u{ab93}', 5059), ('\u{ab94}', 5060), ('\u{ab95}', 5061),
+        ('\u{ab96}', 5062), ('\u{ab97}', 5063), ('\u{ab98}', 5064), ('\u{ab99}', 5065),
+        ('\u{ab9a}', 5066), ('\u{ab9b}', 5067), ('\u{ab9c}', 5068), ('\u{ab9d}', 5069),
+        ('\u{ab9e}', 5070), ('\u{ab9f}', 5071), ('\u{aba0}', 5072), ('\u{aba1}', 5073),
+        ('\u{aba2}', 5074), ('\u{aba3}', 5075), ('\u{aba4}', 5076), ('\u{aba5}', 5077),
+        ('\u{aba6}', 5078), ('\u{aba7}', 5079), ('\u{aba8}', 5080), ('\u{aba9}', 5081),
+        ('\u{abaa}', 5082), ('\u{abab}', 5083), ('\u{abac}', 5084), ('\u{abad}', 5085),
+        ('\u{abae}', 5086), ('\u{abaf}', 5087), ('\u{abb0}', 5088), ('\u{abb1}', 5089),
+        ('\u{abb2}', 5090), ('\u{abb3}', 5091), ('\u{abb4}', 5092), ('\u{abb5}', 5093),
+        ('\u{abb6}', 5094), ('\u{abb7}', 5095), ('\u{abb8}', 5096), ('\u{abb9}', 5097),
+        ('\u{abba}', 5098), ('\u{abbb}', 5099), ('\u{abbc}', 5100), ('\u{abbd}', 5101),
+        ('\u{abbe}', 5102), ('\u{abbf}', 5103), ('\u{fb00}', 4194394), ('\u{fb01}', 4194395),
+        ('\u{fb02}', 4194396), ('\u{fb03}', 4194397), ('\u{fb04}', 4194398), ('\u{fb05}', 4194399),
+        ('\u{fb06}', 4194400), ('\u{fb13}', 4194401), ('\u{fb14}', 4194402), ('\u{fb15}', 4194403),
+        ('\u{fb16}', 4194404), ('\u{fb17}', 4194405), ('\u{ff41}', 65313), ('\u{ff42}', 65314),
+        ('\u{ff43}', 65315), ('\u{ff44}', 65316), ('\u{ff45}', 65317), ('\u{ff46}', 65318),
+        ('\u{ff47}', 65319), ('\u{ff48}', 65320), ('\u{ff49}', 65321), ('\u{ff4a}', 65322),
+        ('\u{ff4b}', 65323), ('\u{ff4c}', 65324), ('\u{ff4d}', 65325), ('\u{ff4e}', 65326),
+        ('\u{ff4f}', 65327), ('\u{ff50}', 65328), ('\u{ff51}', 65329), ('\u{ff52}', 65330),
+        ('\u{ff53}', 65331), ('\u{ff54}', 65332), ('\u{ff55}', 65333), ('\u{ff56}', 65334),
+        ('\u{ff57}', 65335), ('\u{ff58}', 65336), ('\u{ff59}', 65337), ('\u{ff5a}', 65338),
+        ('\u{10428}', 66560), ('\u{10429}', 66561), ('\u{1042a}', 66562), ('\u{1042b}', 66563),
+        ('\u{1042c}', 66564), ('\u{1042d}', 66565), ('\u{1042e}', 66566), ('\u{1042f}', 66567),
+        ('\u{10430}', 66568), ('\u{10431}', 66569), ('\u{10432}', 66570), ('\u{10433}', 66571),
+        ('\u{10434}', 66572), ('\u{10435}', 66573), ('\u{10436}', 66574), ('\u{10437}', 66575),
+        ('\u{10438}', 66576), ('\u{10439}', 66577), ('\u{1043a}', 66578), ('\u{1043b}', 66579),
+        ('\u{1043c}', 66580), ('\u{1043d}', 66581), ('\u{1043e}', 66582), ('\u{1043f}', 66583),
+        ('\u{10440}', 66584), ('\u{10441}', 66585), ('\u{10442}', 66586), ('\u{10443}', 66587),
+        ('\u{10444}', 66588), ('\u{10445}', 66589), ('\u{10446}', 66590), ('\u{10447}', 66591),
+        ('\u{10448}', 66592), ('\u{10449}', 66593), ('\u{1044a}', 66594), ('\u{1044b}', 66595),
+        ('\u{1044c}', 66596), ('\u{1044d}', 66597), ('\u{1044e}', 66598), ('\u{1044f}', 66599),
+        ('\u{104d8}', 66736), ('\u{104d9}', 66737), ('\u{104da}', 66738), ('\u{104db}', 66739),
+        ('\u{104dc}', 66740), ('\u{104dd}', 66741), ('\u{104de}', 66742), ('\u{104df}', 66743),
+        ('\u{104e0}', 66744), ('\u{104e1}', 66745), ('\u{104e2}', 66746), ('\u{104e3}', 66747),
+        ('\u{104e4}', 66748), ('\u{104e5}', 66749), ('\u{104e6}', 66750), ('\u{104e7}', 66751),
+        ('\u{104e8}', 66752), ('\u{104e9}', 66753), ('\u{104ea}', 66754), ('\u{104eb}', 66755),
+        ('\u{104ec}', 66756), ('\u{104ed}', 66757), ('\u{104ee}', 66758), ('\u{104ef}', 66759),
+        ('\u{104f0}', 66760), ('\u{104f1}', 66761), ('\u{104f2}', 66762), ('\u{104f3}', 66763),
+        ('\u{104f4}', 66764), ('\u{104f5}', 66765), ('\u{104f6}', 66766), ('\u{104f7}', 66767),
+        ('\u{104f8}', 66768), ('\u{104f9}', 66769), ('\u{104fa}', 66770), ('\u{104fb}', 66771),
+        ('\u{10597}', 66928), ('\u{10598}', 66929), ('\u{10599}', 66930), ('\u{1059a}', 66931),
+        ('\u{1059b}', 66932), ('\u{1059c}', 66933), ('\u{1059d}', 66934), ('\u{1059e}', 66935),
+        ('\u{1059f}', 66936), ('\u{105a0}', 66937), ('\u{105a1}', 66938), ('\u{105a3}', 66940),
+        ('\u{105a4}', 66941), ('\u{105a5}', 66942), ('\u{105a6}', 66943), ('\u{105a7}', 66944),
+        ('\u{105a8}', 66945), ('\u{105a9}', 66946), ('\u{105aa}', 66947), ('\u{105ab}', 66948),
+        ('\u{105ac}', 66949), ('\u{105ad}', 66950), ('\u{105ae}', 66951), ('\u{105af}', 66952),
+        ('\u{105b0}', 66953), ('\u{105b1}', 66954), ('\u{105b3}', 66956), ('\u{105b4}', 66957),
+        ('\u{105b5}', 66958), ('\u{105b6}', 66959), ('\u{105b7}', 66960), ('\u{105b8}', 66961),
+        ('\u{105b9}', 66962), ('\u{105bb}', 66964), ('\u{105bc}', 66965), ('\u{10cc0}', 68736),
+        ('\u{10cc1}', 68737), ('\u{10cc2}', 68738), ('\u{10cc3}', 68739), ('\u{10cc4}', 68740),
+        ('\u{10cc5}', 68741), ('\u{10cc6}', 68742), ('\u{10cc7}', 68743), ('\u{10cc8}', 68744),
+        ('\u{10cc9}', 68745), ('\u{10cca}', 68746), ('\u{10ccb}', 68747), ('\u{10ccc}', 68748),
+        ('\u{10ccd}', 68749), ('\u{10cce}', 68750), ('\u{10ccf}', 68751), ('\u{10cd0}', 68752),
+        ('\u{10cd1}', 68753), ('\u{10cd2}', 68754), ('\u{10cd3}', 68755), ('\u{10cd4}', 68756),
+        ('\u{10cd5}', 68757), ('\u{10cd6}', 68758), ('\u{10cd7}', 68759), ('\u{10cd8}', 68760),
+        ('\u{10cd9}', 68761), ('\u{10cda}', 68762), ('\u{10cdb}', 68763), ('\u{10cdc}', 68764),
+        ('\u{10cdd}', 68765), ('\u{10cde}', 68766), ('\u{10cdf}', 68767), ('\u{10ce0}', 68768),
+        ('\u{10ce1}', 68769), ('\u{10ce2}', 68770), ('\u{10ce3}', 68771), ('\u{10ce4}', 68772),
+        ('\u{10ce5}', 68773), ('\u{10ce6}', 68774), ('\u{10ce7}', 68775), ('\u{10ce8}', 68776),
+        ('\u{10ce9}', 68777), ('\u{10cea}', 68778), ('\u{10ceb}', 68779), ('\u{10cec}', 68780),
+        ('\u{10ced}', 68781), ('\u{10cee}', 68782), ('\u{10cef}', 68783), ('\u{10cf0}', 68784),
+        ('\u{10cf1}', 68785), ('\u{10cf2}', 68786), ('\u{10d70}', 68944), ('\u{10d71}', 68945),
+        ('\u{10d72}', 68946), ('\u{10d73}', 68947), ('\u{10d74}', 68948), ('\u{10d75}', 68949),
+        ('\u{10d76}', 68950), ('\u{10d77}', 68951), ('\u{10d78}', 68952), ('\u{10d79}', 68953),
+        ('\u{10d7a}', 68954), ('\u{10d7b}', 68955), ('\u{10d7c}', 68956), ('\u{10d7d}', 68957),
+        ('\u{10d7e}', 68958), ('\u{10d7f}', 68959), ('\u{10d80}', 68960), ('\u{10d81}', 68961),
+        ('\u{10d82}', 68962), ('\u{10d83}', 68963), ('\u{10d84}', 68964), ('\u{10d85}', 68965),
+        ('\u{118c0}', 71840), ('\u{118c1}', 71841), ('\u{118c2}', 71842), ('\u{118c3}', 71843),
+        ('\u{118c4}', 71844), ('\u{118c5}', 71845), ('\u{118c6}', 71846), ('\u{118c7}', 71847),
+        ('\u{118c8}', 71848), ('\u{118c9}', 71849), ('\u{118ca}', 71850), ('\u{118cb}', 71851),
+        ('\u{118cc}', 71852), ('\u{118cd}', 71853), ('\u{118ce}', 71854), ('\u{118cf}', 71855),
+        ('\u{118d0}', 71856), ('\u{118d1}', 71857), ('\u{118d2}', 71858), ('\u{118d3}', 71859),
+        ('\u{118d4}', 71860), ('\u{118d5}', 71861), ('\u{118d6}', 71862), ('\u{118d7}', 71863),
+        ('\u{118d8}', 71864), ('\u{118d9}', 71865), ('\u{118da}', 71866), ('\u{118db}', 71867),
+        ('\u{118dc}', 71868), ('\u{118dd}', 71869), ('\u{118de}', 71870), ('\u{118df}', 71871),
+        ('\u{16e60}', 93760), ('\u{16e61}', 93761), ('\u{16e62}', 93762), ('\u{16e63}', 93763),
+        ('\u{16e64}', 93764), ('\u{16e65}', 93765), ('\u{16e66}', 93766), ('\u{16e67}', 93767),
+        ('\u{16e68}', 93768), ('\u{16e69}', 93769), ('\u{16e6a}', 93770), ('\u{16e6b}', 93771),
+        ('\u{16e6c}', 93772), ('\u{16e6d}', 93773), ('\u{16e6e}', 93774), ('\u{16e6f}', 93775),
+        ('\u{16e70}', 93776), ('\u{16e71}', 93777), ('\u{16e72}', 93778), ('\u{16e73}', 93779),
+        ('\u{16e74}', 93780), ('\u{16e75}', 93781), ('\u{16e76}', 93782), ('\u{16e77}', 93783),
+        ('\u{16e78}', 93784), ('\u{16e79}', 93785), ('\u{16e7a}', 93786), ('\u{16e7b}', 93787),
+        ('\u{16e7c}', 93788), ('\u{16e7d}', 93789), ('\u{16e7e}', 93790), ('\u{16e7f}', 93791),
+        ('\u{16ebb}', 93856), ('\u{16ebc}', 93857), ('\u{16ebd}', 93858), ('\u{16ebe}', 93859),
+        ('\u{16ebf}', 93860), ('\u{16ec0}', 93861), ('\u{16ec1}', 93862), ('\u{16ec2}', 93863),
+        ('\u{16ec3}', 93864), ('\u{16ec4}', 93865), ('\u{16ec5}', 93866), ('\u{16ec6}', 93867),
+        ('\u{16ec7}', 93868), ('\u{16ec8}', 93869), ('\u{16ec9}', 93870), ('\u{16eca}', 93871),
+        ('\u{16ecb}', 93872), ('\u{16ecc}', 93873), ('\u{16ecd}', 93874), ('\u{16ece}', 93875),
+        ('\u{16ecf}', 93876), ('\u{16ed0}', 93877), ('\u{16ed1}', 93878), ('\u{16ed2}', 93879),
+        ('\u{16ed3}', 93880), ('\u{1e922}', 125184), ('\u{1e923}', 125185), ('\u{1e924}', 125186),
         ('\u{1e925}', 125187), ('\u{1e926}', 125188), ('\u{1e927}', 125189), ('\u{1e928}', 125190),
         ('\u{1e929}', 125191), ('\u{1e92a}', 125192), ('\u{1e92b}', 125193), ('\u{1e92c}', 125194),
         ('\u{1e92d}', 125195), ('\u{1e92e}', 125196), ('\u{1e92f}', 125197), ('\u{1e930}', 125198),
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 7ff4af8ede8..dc0d11b07a9 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1,6 +1,8 @@
 #[doc(keyword = "as")]
 //
-/// Cast between types, or rename an import.
+/// Cast between types, rename an import, or qualify paths to associated items.
+///
+/// # Type casting
 ///
 /// `as` is most commonly used to turn primitive types into other primitive types, but it has other
 /// uses that include turning pointers into addresses, addresses into pointers, and pointers into
@@ -30,6 +32,8 @@
 /// `as *mut _` though the [`cast`][const-cast] method is recommended over `as *const _` and it is
 /// [the same][mut-cast] for `as *mut _`: those methods make the intent clearer.
 ///
+/// # Renaming imports
+///
 /// `as` is also used to rename imports in [`use`] and [`extern crate`][`crate`] statements:
 ///
 /// ```
@@ -37,9 +41,34 @@
 /// use std::{mem as memory, net as network};
 /// // Now you can use the names `memory` and `network` to refer to `std::mem` and `std::net`.
 /// ```
-/// For more information on what `as` is capable of, see the [Reference].
 ///
-/// [Reference]: ../reference/expressions/operator-expr.html#type-cast-expressions
+/// # Qualifying paths
+///
+/// You'll also find with `From` and `Into`, and indeed all traits, that `as` is used for the
+/// _fully qualified path_, a means of disambiguating associated items, i.e. functions,
+/// constants, and types.  For example, if you have a type which implements two traits with identical
+/// method names (e.g. `Into::<u32>::into` and `Into::<u64>::into`), you can clarify which method
+/// you'll use with `<MyThing as Into<u32>>::into(my_thing)`[^as-use-from].  This is quite verbose,
+/// but fortunately, Rust's type inference usually saves you from needing this, although it is
+/// occasionally necessary, especially with methods that return a generic type like `Into::into` or
+/// methods that don't take `self`.  It's more common to use in macros where it can provide necessary
+/// hygiene.
+///
+/// [^as-use-from]: You should probably never use this syntax with `Into` and instead write
+/// `T::from(my_thing)`.  It just happens that there aren't any great examples for this syntax in
+/// the standard library.  Also, at time of writing, the compiler tends to suggest fully-qualified
+/// paths to fix ambiguous `Into::into` calls, so the example should hopefully be familiar.
+///
+/// # Further reading
+///
+/// For more information on what `as` is capable of, see the Reference on [type cast expressions],
+/// [renaming imported entities], [renaming `extern` crates]
+/// and [qualified paths].
+///
+/// [type cast expressions]: ../reference/expressions/operator-expr.html#type-cast-expressions
+/// [renaming imported entities]: https://doc.rust-lang.org/reference/items/use-declarations.html#as-renames
+/// [renaming `extern` crates]: https://doc.rust-lang.org/reference/items/extern-crates.html#r-items.extern-crate.as
+/// [qualified paths]: ../reference/paths.html#qualified-paths
 /// [`crate`]: keyword.crate.html
 /// [`use`]: keyword.use.html
 /// [const-cast]: pointer::cast
diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs
index 5d206c4b7da..40061d08928 100644
--- a/library/std/src/num/f128.rs
+++ b/library/std/src/num/f128.rs
@@ -557,10 +557,12 @@ impl f128 {
 
     /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
     ///
-    /// * `x = 0`, `y = 0`: `0`
-    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
-    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
-    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///  | `x`     | `y`     | Piecewise Definition | Range         |
+    ///  |---------|---------|----------------------|---------------|
+    ///  | `>= +0` | `>= +0` | `arctan(y/x)`        | `[+0, +pi/2]` |
+    ///  | `>= +0` | `<= -0` | `arctan(y/x)`        | `[-pi/2, -0]` |
+    ///  | `<= -0` | `>= +0` | `arctan(y/x) + pi`   | `[+pi/2, +pi]`|
+    ///  | `<= -0` | `<= -0` | `arctan(y/x) - pi`   | `[-pi, -pi/2]`|
     ///
     /// # Unspecified precision
     ///
diff --git a/library/std/src/num/f16.rs b/library/std/src/num/f16.rs
index 2565ef0f9f2..0d43b60a62f 100644
--- a/library/std/src/num/f16.rs
+++ b/library/std/src/num/f16.rs
@@ -522,10 +522,12 @@ impl f16 {
 
     /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
     ///
-    /// * `x = 0`, `y = 0`: `0`
-    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
-    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
-    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///  | `x`     | `y`     | Piecewise Definition | Range         |
+    ///  |---------|---------|----------------------|---------------|
+    ///  | `>= +0` | `>= +0` | `arctan(y/x)`        | `[+0, +pi/2]` |
+    ///  | `>= +0` | `<= -0` | `arctan(y/x)`        | `[-pi/2, -0]` |
+    ///  | `<= -0` | `>= +0` | `arctan(y/x) + pi`   | `[+pi/2, +pi]`|
+    ///  | `<= -0` | `<= -0` | `arctan(y/x) - pi`   | `[-pi, -pi/2]`|
     ///
     /// # Unspecified precision
     ///
diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs
index e7810e77e76..c9e192201af 100644
--- a/library/std/src/num/f32.rs
+++ b/library/std/src/num/f32.rs
@@ -827,10 +827,12 @@ impl f32 {
 
     /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
     ///
-    /// * `x = 0`, `y = 0`: `0`
-    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
-    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
-    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///  | `x`     | `y`     | Piecewise Definition | Range         |
+    ///  |---------|---------|----------------------|---------------|
+    ///  | `>= +0` | `>= +0` | `arctan(y/x)`        | `[+0, +pi/2]` |
+    ///  | `>= +0` | `<= -0` | `arctan(y/x)`        | `[-pi/2, -0]` |
+    ///  | `<= -0` | `>= +0` | `arctan(y/x) + pi`   | `[+pi/2, +pi]`|
+    ///  | `<= -0` | `<= -0` | `arctan(y/x) - pi`   | `[-pi, -pi/2]`|
     ///
     /// # Unspecified precision
     ///
diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs
index cbebbfb1be1..11874f9280f 100644
--- a/library/std/src/num/f64.rs
+++ b/library/std/src/num/f64.rs
@@ -827,10 +827,12 @@ impl f64 {
 
     /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
     ///
-    /// * `x = 0`, `y = 0`: `0`
-    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
-    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
-    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///  | `x`     | `y`     | Piecewise Definition | Range         |
+    ///  |---------|---------|----------------------|---------------|
+    ///  | `>= +0` | `>= +0` | `arctan(y/x)`        | `[+0, +pi/2]` |
+    ///  | `>= +0` | `<= -0` | `arctan(y/x)`        | `[-pi/2, -0]` |
+    ///  | `<= -0` | `>= +0` | `arctan(y/x) + pi`   | `[+pi/2, +pi]`|
+    ///  | `<= -0` | `<= -0` | `arctan(y/x) - pi`   | `[-pi, -pi/2]`|
     ///
     /// # Unspecified precision
     ///
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index 469bfbb0d83..163267be1e5 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -159,7 +159,7 @@ impl UnixDatagram {
     /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn unbound() -> io::Result<UnixDatagram> {
-        let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
+        let inner = Socket::new(libc::AF_UNIX, libc::SOCK_DGRAM)?;
         Ok(UnixDatagram(inner))
     }
 
diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs
index 27428c9eb28..5b4659e2618 100644
--- a/library/std/src/os/unix/net/listener.rs
+++ b/library/std/src/os/unix/net/listener.rs
@@ -71,7 +71,7 @@ impl UnixListener {
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
         unsafe {
-            let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+            let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
             let (addr, len) = sockaddr_un(path.as_ref())?;
             #[cfg(any(
                 target_os = "windows",
@@ -136,7 +136,7 @@ impl UnixListener {
     #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
     pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixListener> {
         unsafe {
-            let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+            let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
             #[cfg(target_os = "linux")]
             const backlog: core::ffi::c_int = -1;
             #[cfg(not(target_os = "linux"))]
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index ea4171a7d28..851ff7f0879 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -105,7 +105,7 @@ impl UnixStream {
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
         unsafe {
-            let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+            let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
             let (addr, len) = sockaddr_un(path.as_ref())?;
 
             cvt(libc::connect(inner.as_raw_fd(), (&raw const addr) as *const _, len))?;
@@ -139,7 +139,7 @@ impl UnixStream {
     #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
     pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
         unsafe {
-            let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+            let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
             cvt(libc::connect(
                 inner.as_raw_fd(),
                 (&raw const socket_addr.addr) as *const _,
diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs
index 5200eaa5786..2f5c6fa31d4 100644
--- a/library/std/src/sys/net/connection/socket/hermit.rs
+++ b/library/std/src/sys/net/connection/socket/hermit.rs
@@ -37,15 +37,7 @@ pub fn init() {}
 pub struct Socket(FileDesc);
 
 impl Socket {
-    pub fn new(addr: &SocketAddr, ty: i32) -> io::Result<Socket> {
-        let fam = match *addr {
-            SocketAddr::V4(..) => netc::AF_INET,
-            SocketAddr::V6(..) => netc::AF_INET6,
-        };
-        Socket::new_raw(fam, ty)
-    }
-
-    pub fn new_raw(fam: i32, ty: i32) -> io::Result<Socket> {
+    pub fn new(fam: i32, ty: i32) -> io::Result<Socket> {
         let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?;
         Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) }))
     }
@@ -242,11 +234,11 @@ impl Socket {
             None => netc::timeval { tv_sec: 0, tv_usec: 0 },
         };
 
-        setsockopt(self, netc::SOL_SOCKET, kind, timeout)
+        unsafe { setsockopt(self, netc::SOL_SOCKET, kind, timeout) }
     }
 
     pub fn timeout(&self, kind: i32) -> io::Result<Option<Duration>> {
-        let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?;
+        let raw: netc::timeval = unsafe { getsockopt(self, netc::SOL_SOCKET, kind)? };
         if raw.tv_sec == 0 && raw.tv_usec == 0 {
             Ok(None)
         } else {
@@ -272,22 +264,22 @@ impl Socket {
             l_linger: linger.unwrap_or_default().as_secs() as libc::c_int,
         };
 
-        setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger)
+        unsafe { setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) }
     }
 
     pub fn linger(&self) -> io::Result<Option<Duration>> {
-        let val: netc::linger = getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)?;
+        let val: netc::linger = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)? };
 
         Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
     }
 
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
         let value: i32 = if nodelay { 1 } else { 0 };
-        setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, value)
+        unsafe { setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, value) }
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        let raw: i32 = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?;
+        let raw: i32 = unsafe { getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)? };
         Ok(raw != 0)
     }
 
@@ -304,7 +296,7 @@ impl Socket {
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
+        let raw: c_int = unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)? };
         if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
     }
 
diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs
index 1dd06e97bba..d0a4a2fab49 100644
--- a/library/std/src/sys/net/connection/socket/mod.rs
+++ b/library/std/src/sys/net/connection/socket/mod.rs
@@ -3,6 +3,7 @@ mod tests;
 
 use crate::ffi::{c_int, c_void};
 use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut};
+use crate::mem::MaybeUninit;
 use crate::net::{
     Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs,
 };
@@ -177,6 +178,18 @@ fn socket_addr_to_c(addr: &SocketAddr) -> (SocketAddrCRepr, c::socklen_t) {
     }
 }
 
+fn addr_family(addr: &SocketAddr) -> c_int {
+    match addr {
+        SocketAddr::V4(..) => c::AF_INET,
+        SocketAddr::V6(..) => c::AF_INET6,
+    }
+}
+
+/// Converts the C socket address stored in `storage` to a Rust `SocketAddr`.
+///
+/// # Safety
+/// * `storage` must contain a valid C socket address whose length is no larger
+///   than `len`.
 unsafe fn socket_addr_from_c(
     storage: *const c::sockaddr_storage,
     len: usize,
@@ -202,49 +215,85 @@ unsafe fn socket_addr_from_c(
 // sockaddr and misc bindings
 ////////////////////////////////////////////////////////////////////////////////
 
-pub fn setsockopt<T>(
+/// Sets the value of a socket option.
+///
+/// # Safety
+/// `T` must be the type associated with the given socket option.
+pub unsafe fn setsockopt<T>(
     sock: &Socket,
     level: c_int,
     option_name: c_int,
     option_value: T,
 ) -> io::Result<()> {
-    unsafe {
-        cvt(c::setsockopt(
+    let option_len = size_of::<T>() as c::socklen_t;
+    // SAFETY:
+    // * `sock` is opened for the duration of this call, as `sock` owns the socket.
+    // * the pointer to `option_value` is readable at a size of `size_of::<T>`
+    //   bytes
+    // * the value of `option_value` has a valid type for the given socket option
+    //   (guaranteed by caller).
+    cvt(unsafe {
+        c::setsockopt(
             sock.as_raw(),
             level,
             option_name,
             (&raw const option_value) as *const _,
-            size_of::<T>() as c::socklen_t,
-        ))?;
-        Ok(())
-    }
+            option_len,
+        )
+    })?;
+    Ok(())
 }
 
-pub fn getsockopt<T: Copy>(sock: &Socket, level: c_int, option_name: c_int) -> io::Result<T> {
-    unsafe {
-        let mut option_value: T = mem::zeroed();
-        let mut option_len = size_of::<T>() as c::socklen_t;
-        cvt(c::getsockopt(
+/// Gets the value of a socket option.
+///
+/// # Safety
+/// `T` must be the type associated with the given socket option.
+pub unsafe fn getsockopt<T: Copy>(
+    sock: &Socket,
+    level: c_int,
+    option_name: c_int,
+) -> io::Result<T> {
+    let mut option_value = MaybeUninit::<T>::zeroed();
+    let mut option_len = size_of::<T>() as c::socklen_t;
+
+    // SAFETY:
+    // * `sock` is opened for the duration of this call, as `sock` owns the socket.
+    // * the pointer to `option_value` is writable and the stack allocation has
+    //   space for `size_of::<T>` bytes.
+    cvt(unsafe {
+        c::getsockopt(
             sock.as_raw(),
             level,
             option_name,
-            (&raw mut option_value) as *mut _,
+            option_value.as_mut_ptr().cast(),
             &mut option_len,
-        ))?;
-        Ok(option_value)
-    }
-}
-
-fn sockname<F>(f: F) -> io::Result<SocketAddr>
+        )
+    })?;
+
+    // SAFETY: the `getsockopt` call succeeded and the caller guarantees that
+    //         `T` is the type of this option, thus `option_value` must have
+    //         been initialized by the system.
+    Ok(unsafe { option_value.assume_init() })
+}
+
+/// Wraps a call to a platform function that returns a socket address.
+///
+/// # Safety
+/// * if `f` returns a success (i.e. `cvt` returns `Ok` when called on the
+///   return value), the buffer provided to `f` must have been initialized
+///   with a valid C socket address, the length of which must be written
+///   to the second argument.
+unsafe fn sockname<F>(f: F) -> io::Result<SocketAddr>
 where
     F: FnOnce(*mut c::sockaddr, *mut c::socklen_t) -> c_int,
 {
-    unsafe {
-        let mut storage: c::sockaddr_storage = mem::zeroed();
-        let mut len = size_of_val(&storage) as c::socklen_t;
-        cvt(f((&raw mut storage) as *mut _, &mut len))?;
-        socket_addr_from_c(&storage, len as usize)
-    }
+    let mut storage = MaybeUninit::<c::sockaddr_storage>::zeroed();
+    let mut len = size_of::<c::sockaddr_storage>() as c::socklen_t;
+    cvt(f(storage.as_mut_ptr().cast(), &mut len))?;
+    // SAFETY:
+    // The caller guarantees that the storage has been successfully initialized
+    // and its size written to `len` if `f` returns a success.
+    unsafe { socket_addr_from_c(storage.as_ptr(), len as usize) }
 }
 
 #[cfg(target_os = "android")]
@@ -322,7 +371,7 @@ impl TcpStream {
         return each_addr(addr, inner);
 
         fn inner(addr: &SocketAddr) -> io::Result<TcpStream> {
-            let sock = Socket::new(addr, c::SOCK_STREAM)?;
+            let sock = Socket::new(addr_family(addr), c::SOCK_STREAM)?;
             sock.connect(addr)?;
             Ok(TcpStream { inner: sock })
         }
@@ -331,7 +380,7 @@ impl TcpStream {
     pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
         init();
 
-        let sock = Socket::new(addr, c::SOCK_STREAM)?;
+        let sock = Socket::new(addr_family(addr), c::SOCK_STREAM)?;
         sock.connect_timeout(addr, timeout)?;
         Ok(TcpStream { inner: sock })
     }
@@ -400,11 +449,11 @@ impl TcpStream {
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        sockname(|buf, len| unsafe { c::getpeername(self.inner.as_raw(), buf, len) })
+        unsafe { sockname(|buf, len| c::getpeername(self.inner.as_raw(), buf, len)) }
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        sockname(|buf, len| unsafe { c::getsockname(self.inner.as_raw(), buf, len) })
+        unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) }
     }
 
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
@@ -432,11 +481,11 @@ impl TcpStream {
     }
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
-        setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) }
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
+        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? };
         Ok(raw as u32)
     }
 
@@ -493,7 +542,7 @@ impl TcpListener {
         return each_addr(addr, inner);
 
         fn inner(addr: &SocketAddr) -> io::Result<TcpListener> {
-            let sock = Socket::new(addr, c::SOCK_STREAM)?;
+            let sock = Socket::new(addr_family(addr), c::SOCK_STREAM)?;
 
             // On platforms with Berkeley-derived sockets, this allows to quickly
             // rebind a socket, without needing to wait for the OS to clean up the
@@ -503,7 +552,9 @@ impl TcpListener {
             // which allows “socket hijacking”, so we explicitly don't set it here.
             // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
             #[cfg(not(windows))]
-            setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR, 1 as c_int)?;
+            unsafe {
+                setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR, 1 as c_int)?
+            };
 
             // Bind our new socket
             let (addr, len) = socket_addr_to_c(addr);
@@ -539,15 +590,15 @@ impl TcpListener {
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        sockname(|buf, len| unsafe { c::getsockname(self.inner.as_raw(), buf, len) })
+        unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) }
     }
 
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
         // The `accept` function will fill in the storage with the address,
         // so we don't need to zero it here.
         // reference: https://linux.die.net/man/2/accept4
-        let mut storage: mem::MaybeUninit<c::sockaddr_storage> = mem::MaybeUninit::uninit();
-        let mut len = size_of_val(&storage) as c::socklen_t;
+        let mut storage = MaybeUninit::<c::sockaddr_storage>::uninit();
+        let mut len = size_of::<c::sockaddr_storage>() as c::socklen_t;
         let sock = self.inner.accept(storage.as_mut_ptr() as *mut _, &mut len)?;
         let addr = unsafe { socket_addr_from_c(storage.as_ptr(), len as usize)? };
         Ok((TcpStream { inner: sock }, addr))
@@ -558,20 +609,20 @@ impl TcpListener {
     }
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
-        setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) }
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
+        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? };
         Ok(raw as u32)
     }
 
     pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
-        setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int) }
     }
 
     pub fn only_v6(&self) -> io::Result<bool> {
-        let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY)?;
+        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY)? };
         Ok(raw != 0)
     }
 
@@ -617,7 +668,7 @@ impl UdpSocket {
         return each_addr(addr, inner);
 
         fn inner(addr: &SocketAddr) -> io::Result<UdpSocket> {
-            let sock = Socket::new(addr, c::SOCK_DGRAM)?;
+            let sock = Socket::new(addr_family(addr), c::SOCK_DGRAM)?;
             let (addr, len) = socket_addr_to_c(addr);
             cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
             Ok(UdpSocket { inner: sock })
@@ -634,11 +685,11 @@ impl UdpSocket {
     }
 
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        sockname(|buf, len| unsafe { c::getpeername(self.inner.as_raw(), buf, len) })
+        unsafe { sockname(|buf, len| c::getpeername(self.inner.as_raw(), buf, len)) }
     }
 
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-        sockname(|buf, len| unsafe { c::getsockname(self.inner.as_raw(), buf, len) })
+        unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) }
     }
 
     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
@@ -686,48 +737,62 @@ impl UdpSocket {
     }
 
     pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
-        setsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST, broadcast as c_int)
+        unsafe { setsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST, broadcast as c_int) }
     }
 
     pub fn broadcast(&self) -> io::Result<bool> {
-        let raw: c_int = getsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST)?;
+        let raw: c_int = unsafe { getsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST)? };
         Ok(raw != 0)
     }
 
     pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
-        setsockopt(
-            &self.inner,
-            c::IPPROTO_IP,
-            c::IP_MULTICAST_LOOP,
-            multicast_loop_v4 as IpV4MultiCastType,
-        )
+        unsafe {
+            setsockopt(
+                &self.inner,
+                c::IPPROTO_IP,
+                c::IP_MULTICAST_LOOP,
+                multicast_loop_v4 as IpV4MultiCastType,
+            )
+        }
     }
 
     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
-        let raw: IpV4MultiCastType = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?;
+        let raw: IpV4MultiCastType =
+            unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)? };
         Ok(raw != 0)
     }
 
     pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
-        setsockopt(
-            &self.inner,
-            c::IPPROTO_IP,
-            c::IP_MULTICAST_TTL,
-            multicast_ttl_v4 as IpV4MultiCastType,
-        )
+        unsafe {
+            setsockopt(
+                &self.inner,
+                c::IPPROTO_IP,
+                c::IP_MULTICAST_TTL,
+                multicast_ttl_v4 as IpV4MultiCastType,
+            )
+        }
     }
 
     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
-        let raw: IpV4MultiCastType = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?;
+        let raw: IpV4MultiCastType =
+            unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)? };
         Ok(raw as u32)
     }
 
     pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
-        setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int)
+        unsafe {
+            setsockopt(
+                &self.inner,
+                c::IPPROTO_IPV6,
+                c::IPV6_MULTICAST_LOOP,
+                multicast_loop_v6 as c_int,
+            )
+        }
     }
 
     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
-        let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP)?;
+        let raw: c_int =
+            unsafe { getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP)? };
         Ok(raw != 0)
     }
 
@@ -736,7 +801,7 @@ impl UdpSocket {
             imr_multiaddr: ip_v4_addr_to_c(multiaddr),
             imr_interface: ip_v4_addr_to_c(interface),
         };
-        setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) }
     }
 
     pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
@@ -744,7 +809,7 @@ impl UdpSocket {
             ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr),
             ipv6mr_interface: to_ipv6mr_interface(interface),
         };
-        setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq) }
     }
 
     pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
@@ -752,7 +817,7 @@ impl UdpSocket {
             imr_multiaddr: ip_v4_addr_to_c(multiaddr),
             imr_interface: ip_v4_addr_to_c(interface),
         };
-        setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) }
     }
 
     pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
@@ -760,15 +825,15 @@ impl UdpSocket {
             ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr),
             ipv6mr_interface: to_ipv6mr_interface(interface),
         };
-        setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq) }
     }
 
     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
-        setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
+        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) }
     }
 
     pub fn ttl(&self) -> io::Result<u32> {
-        let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
+        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? };
         Ok(raw as u32)
     }
 
diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs
index 94bb605c100..14cf75adcc0 100644
--- a/library/std/src/sys/net/connection/socket/solid.rs
+++ b/library/std/src/sys/net/connection/socket/solid.rs
@@ -115,19 +115,9 @@ pub fn init() {}
 pub struct Socket(OwnedFd);
 
 impl Socket {
-    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match *addr {
-            SocketAddr::V4(..) => netc::AF_INET,
-            SocketAddr::V6(..) => netc::AF_INET6,
-        };
-        Socket::new_raw(fam, ty)
-    }
-
-    pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
-        unsafe {
-            let fd = cvt(netc::socket(fam, ty, 0))?;
-            Ok(Self::from_raw_fd(fd))
-        }
+    pub fn new(fam: c_int, ty: c_int) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?;
+        Ok(unsafe { Self::from_raw_fd(fd) })
     }
 
     pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
@@ -303,11 +293,11 @@ impl Socket {
             }
             None => netc::timeval { tv_sec: 0, tv_usec: 0 },
         };
-        setsockopt(self, netc::SOL_SOCKET, kind, timeout)
+        unsafe { setsockopt(self, netc::SOL_SOCKET, kind, timeout) }
     }
 
     pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
-        let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?;
+        let raw: netc::timeval = unsafe { getsockopt(self, netc::SOL_SOCKET, kind)? };
         if raw.tv_sec == 0 && raw.tv_usec == 0 {
             Ok(None)
         } else {
@@ -333,21 +323,21 @@ impl Socket {
             l_linger: linger.unwrap_or_default().as_secs() as netc::c_int,
         };
 
-        setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger)
+        unsafe { setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) }
     }
 
     pub fn linger(&self) -> io::Result<Option<Duration>> {
-        let val: netc::linger = getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)?;
+        let val: netc::linger = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)? };
 
         Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
     }
 
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
-        setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int)
+        unsafe { setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int) }
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        let raw: c_int = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?;
+        let raw: c_int = unsafe { getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)? };
         Ok(raw != 0)
     }
 
@@ -360,7 +350,7 @@ impl Socket {
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        let raw: c_int = getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)?;
+        let raw: c_int = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)? };
         if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
     }
 
diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs
index a191576d93b..559e27604a9 100644
--- a/library/std/src/sys/net/connection/socket/unix.rs
+++ b/library/std/src/sys/net/connection/socket/unix.rs
@@ -63,56 +63,46 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
 }
 
 impl Socket {
-    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match *addr {
-            SocketAddr::V4(..) => libc::AF_INET,
-            SocketAddr::V6(..) => libc::AF_INET6,
-        };
-        Socket::new_raw(fam, ty)
-    }
-
-    pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
-        unsafe {
-            cfg_select! {
-                any(
-                    target_os = "android",
-                    target_os = "dragonfly",
-                    target_os = "freebsd",
-                    target_os = "illumos",
-                    target_os = "hurd",
-                    target_os = "linux",
-                    target_os = "netbsd",
-                    target_os = "openbsd",
-                    target_os = "cygwin",
-                    target_os = "nto",
-                    target_os = "solaris",
-                ) => {
-                    // On platforms that support it we pass the SOCK_CLOEXEC
-                    // flag to atomically create the socket and set it as
-                    // CLOEXEC. On Linux this was added in 2.6.27.
-                    let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?;
-                    let socket = Socket(FileDesc::from_raw_fd(fd));
-
-                    // DragonFlyBSD, FreeBSD and NetBSD use `SO_NOSIGPIPE` as a `setsockopt`
-                    // flag to disable `SIGPIPE` emission on socket.
-                    #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly"))]
-                    setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?;
-
-                    Ok(socket)
-                }
-                _ => {
-                    let fd = cvt(libc::socket(fam, ty, 0))?;
-                    let fd = FileDesc::from_raw_fd(fd);
-                    fd.set_cloexec()?;
-                    let socket = Socket(fd);
+    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
+        cfg_select! {
+            any(
+                target_os = "android",
+                target_os = "dragonfly",
+                target_os = "freebsd",
+                target_os = "illumos",
+                target_os = "hurd",
+                target_os = "linux",
+                target_os = "netbsd",
+                target_os = "openbsd",
+                target_os = "cygwin",
+                target_os = "nto",
+                target_os = "solaris",
+            ) => {
+                // On platforms that support it we pass the SOCK_CLOEXEC
+                // flag to atomically create the socket and set it as
+                // CLOEXEC. On Linux this was added in 2.6.27.
+                let fd = cvt(unsafe { libc::socket(family, ty | libc::SOCK_CLOEXEC, 0) })?;
+                let socket = Socket(unsafe { FileDesc::from_raw_fd(fd) });
+
+                // DragonFlyBSD, FreeBSD and NetBSD use `SO_NOSIGPIPE` as a `setsockopt`
+                // flag to disable `SIGPIPE` emission on socket.
+                #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly"))]
+                unsafe { setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)? };
+
+                Ok(socket)
+            }
+            _ => {
+                let fd = cvt(unsafe { libc::socket(family, ty, 0) })?;
+                let fd = unsafe { FileDesc::from_raw_fd(fd) };
+                fd.set_cloexec()?;
+                let socket = Socket(fd);
 
-                    // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt`
-                    // flag to disable `SIGPIPE` emission on socket.
-                    #[cfg(target_vendor = "apple")]
-                    setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?;
+                // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt`
+                // flag to disable `SIGPIPE` emission on socket.
+                #[cfg(target_vendor = "apple")]
+                unsafe { setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)? };
 
-                    Ok(socket)
-                }
+                Ok(socket)
             }
         }
     }
@@ -413,11 +403,11 @@ impl Socket {
             }
             None => libc::timeval { tv_sec: 0, tv_usec: 0 },
         };
-        setsockopt(self, libc::SOL_SOCKET, kind, timeout)
+        unsafe { setsockopt(self, libc::SOL_SOCKET, kind, timeout) }
     }
 
     pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> {
-        let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?;
+        let raw: libc::timeval = unsafe { getsockopt(self, libc::SOL_SOCKET, kind)? };
         if raw.tv_sec == 0 && raw.tv_usec == 0 {
             Ok(None)
         } else {
@@ -444,7 +434,7 @@ impl Socket {
             l_linger: linger.unwrap_or_default().as_secs() as libc::c_int,
         };
 
-        setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger)
+        unsafe { setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) }
     }
 
     #[cfg(target_os = "cygwin")]
@@ -454,32 +444,32 @@ impl Socket {
             l_linger: linger.unwrap_or_default().as_secs() as libc::c_ushort,
         };
 
-        setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger)
+        unsafe { setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) }
     }
 
     pub fn linger(&self) -> io::Result<Option<Duration>> {
-        let val: libc::linger = getsockopt(self, libc::SOL_SOCKET, SO_LINGER)?;
+        let val: libc::linger = unsafe { getsockopt(self, libc::SOL_SOCKET, SO_LINGER)? };
 
         Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
     }
 
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
-        setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int)
+        unsafe { setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int) }
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?;
+        let raw: c_int = unsafe { getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)? };
         Ok(raw != 0)
     }
 
     #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn set_quickack(&self, quickack: bool) -> io::Result<()> {
-        setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int)
+        unsafe { setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int) }
     }
 
     #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn quickack(&self) -> io::Result<bool> {
-        let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?;
+        let raw: c_int = unsafe { getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)? };
         Ok(raw != 0)
     }
 
@@ -487,12 +477,12 @@ impl Socket {
     #[cfg(target_os = "linux")]
     pub fn set_deferaccept(&self, accept: Duration) -> io::Result<()> {
         let val = cmp::min(accept.as_secs(), c_int::MAX as u64) as c_int;
-        setsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT, val)
+        unsafe { setsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT, val) }
     }
 
     #[cfg(target_os = "linux")]
     pub fn deferaccept(&self) -> io::Result<Duration> {
-        let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT)?;
+        let raw: c_int = unsafe { getsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT)? };
         Ok(Duration::from_secs(raw as _))
     }
 
@@ -506,21 +496,23 @@ impl Socket {
             }
             let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() };
             arg.af_name = buf;
-            setsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER, &mut arg)
+            unsafe { setsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER, &mut arg) }
         } else {
-            setsockopt(
-                self,
-                libc::SOL_SOCKET,
-                libc::SO_ACCEPTFILTER,
-                core::ptr::null_mut() as *mut c_void,
-            )
+            unsafe {
+                setsockopt(
+                    self,
+                    libc::SOL_SOCKET,
+                    libc::SO_ACCEPTFILTER,
+                    core::ptr::null_mut() as *mut c_void,
+                )
+            }
         }
     }
 
     #[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
     pub fn acceptfilter(&self) -> io::Result<&CStr> {
         let arg: libc::accept_filter_arg =
-            getsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER)?;
+            unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER)? };
         let s: &[u8] =
             unsafe { core::slice::from_raw_parts(arg.af_name.as_ptr() as *const u8, 16) };
         let name = CStr::from_bytes_with_nul(s).unwrap();
@@ -531,53 +523,57 @@ impl Socket {
     pub fn set_exclbind(&self, excl: bool) -> io::Result<()> {
         // not yet on libc crate
         const SO_EXCLBIND: i32 = 0x1015;
-        setsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND, excl)
+        unsafe { setsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND, excl) }
     }
 
     #[cfg(any(target_os = "solaris", target_os = "illumos"))]
     pub fn exclbind(&self) -> io::Result<bool> {
         // not yet on libc crate
         const SO_EXCLBIND: i32 = 0x1015;
-        let raw: c_int = getsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND)?;
+        let raw: c_int = unsafe { getsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND)? };
         Ok(raw != 0)
     }
 
     #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
-        setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)
+        unsafe { setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int) }
     }
 
     #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn passcred(&self) -> io::Result<bool> {
-        let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?;
+        let passcred: libc::c_int =
+            unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)? };
         Ok(passcred != 0)
     }
 
     #[cfg(target_os = "netbsd")]
     pub fn set_local_creds(&self, local_creds: bool) -> io::Result<()> {
-        setsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS, local_creds as libc::c_int)
+        unsafe { setsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS, local_creds as libc::c_int) }
     }
 
     #[cfg(target_os = "netbsd")]
     pub fn local_creds(&self) -> io::Result<bool> {
-        let local_creds: libc::c_int = getsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS)?;
+        let local_creds: libc::c_int =
+            unsafe { getsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS)? };
         Ok(local_creds != 0)
     }
 
     #[cfg(target_os = "freebsd")]
     pub fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> {
-        setsockopt(
-            self,
-            libc::AF_LOCAL,
-            libc::LOCAL_CREDS_PERSISTENT,
-            local_creds_persistent as libc::c_int,
-        )
+        unsafe {
+            setsockopt(
+                self,
+                libc::AF_LOCAL,
+                libc::LOCAL_CREDS_PERSISTENT,
+                local_creds_persistent as libc::c_int,
+            )
+        }
     }
 
     #[cfg(target_os = "freebsd")]
     pub fn local_creds_persistent(&self) -> io::Result<bool> {
         let local_creds_persistent: libc::c_int =
-            getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)?;
+            unsafe { getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)? };
         Ok(local_creds_persistent != 0)
     }
 
@@ -590,7 +586,7 @@ impl Socket {
     #[cfg(target_os = "vita")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         let option = nonblocking as libc::c_int;
-        setsockopt(self, libc::SOL_SOCKET, libc::SO_NONBLOCK, option)
+        unsafe { setsockopt(self, libc::SOL_SOCKET, libc::SO_NONBLOCK, option) }
     }
 
     #[cfg(any(target_os = "solaris", target_os = "illumos"))]
@@ -608,11 +604,11 @@ impl Socket {
         let option = libc::SO_USER_COOKIE;
         #[cfg(target_os = "openbsd")]
         let option = libc::SO_RTABLE;
-        setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int)
+        unsafe { setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) }
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
+        let raw: c_int = unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)? };
         if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
     }
 
diff --git a/library/std/src/sys/net/connection/socket/wasip2.rs b/library/std/src/sys/net/connection/socket/wasip2.rs
index c77c50fece1..a1b08609eb0 100644
--- a/library/std/src/sys/net/connection/socket/wasip2.rs
+++ b/library/std/src/sys/net/connection/socket/wasip2.rs
@@ -74,16 +74,8 @@ pub struct WasiSocket(OwnedFd);
 pub struct Socket(WasiSocket);
 
 impl Socket {
-    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match *addr {
-            SocketAddr::V4(..) => netc::AF_INET,
-            SocketAddr::V6(..) => netc::AF_INET6,
-        };
-        Socket::new_raw(fam, ty)
-    }
-
-    pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
-        let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?;
+    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
+        let fd = cvt(unsafe { netc::socket(family, ty, 0) })?;
         Ok(unsafe { Self::from_raw_fd(fd) })
     }
 
@@ -270,11 +262,11 @@ impl Socket {
             }
             None => netc::timeval { tv_sec: 0, tv_usec: 0 },
         };
-        setsockopt(self, netc::SOL_SOCKET, kind, timeout)
+        unsafe { setsockopt(self, netc::SOL_SOCKET, kind, timeout) }
     }
 
     pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
-        let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?;
+        let raw: netc::timeval = unsafe { getsockopt(self, netc::SOL_SOCKET, kind)? };
         if raw.tv_sec == 0 && raw.tv_usec == 0 {
             Ok(None)
         } else {
@@ -303,11 +295,11 @@ impl Socket {
     }
 
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
-        setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int)
+        unsafe { setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int) }
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        let raw: c_int = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?;
+        let raw: c_int = unsafe { getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)? };
         Ok(raw != 0)
     }
 
@@ -317,7 +309,7 @@ impl Socket {
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        let raw: c_int = getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)?;
+        let raw: c_int = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)? };
         if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
     }
 
diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs
index 5b6f4cedf1b..6dbebc5e276 100644
--- a/library/std/src/sys/net/connection/socket/windows.rs
+++ b/library/std/src/sys/net/connection/socket/windows.rs
@@ -111,17 +111,13 @@ pub(super) mod netc {
     }
 }
 
-pub use crate::sys::pal::winsock::{cleanup, cvt, cvt_gai, cvt_r, startup as init};
+pub use crate::sys::pal::winsock::{cvt, cvt_gai, cvt_r, startup as init};
 
 #[expect(missing_debug_implementations)]
 pub struct Socket(OwnedSocket);
 
 impl Socket {
-    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let family = match *addr {
-            SocketAddr::V4(..) => netc::AF_INET,
-            SocketAddr::V6(..) => netc::AF_INET6,
-        };
+    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
         let socket = unsafe {
             c::WSASocketW(
                 family,
@@ -384,11 +380,11 @@ impl Socket {
             }
             None => 0,
         };
-        setsockopt(self, c::SOL_SOCKET, kind, timeout)
+        unsafe { setsockopt(self, c::SOL_SOCKET, kind, timeout) }
     }
 
     pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
-        let raw: u32 = getsockopt(self, c::SOL_SOCKET, kind)?;
+        let raw: u32 = unsafe { getsockopt(self, c::SOL_SOCKET, kind)? };
         if raw == 0 {
             Ok(None)
         } else {
@@ -421,26 +417,26 @@ impl Socket {
             l_linger: linger.unwrap_or_default().as_secs() as c_ushort,
         };
 
-        setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger)
+        unsafe { setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger) }
     }
 
     pub fn linger(&self) -> io::Result<Option<Duration>> {
-        let val: c::LINGER = getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
+        let val: c::LINGER = unsafe { getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)? };
 
         Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
     }
 
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
-        setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL)
+        unsafe { setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL) }
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        let raw: c::BOOL = getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
+        let raw: c::BOOL = unsafe { getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)? };
         Ok(raw != 0)
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        let raw: c_int = getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?;
+        let raw: c_int = unsafe { getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)? };
         if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
     }
 
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 18ab3498267..a5f06008013 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -58,7 +58,7 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: 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() {
-    crate::sys::net::cleanup();
+    winsock::cleanup();
 }
 
 #[inline]
diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs
index a79978d036c..dab6850e0d6 100644
--- a/src/tools/compiletest/src/directives.rs
+++ b/src/tools/compiletest/src/directives.rs
@@ -15,6 +15,7 @@ use crate::directives::auxiliary::{AuxProps, parse_and_update_aux};
 use crate::directives::directive_names::{
     KNOWN_DIRECTIVE_NAMES, KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, KNOWN_JSONDOCCK_DIRECTIVE_NAMES,
 };
+use crate::directives::line::{DirectiveLine, line_directive};
 use crate::directives::needs::CachedNeedsConditions;
 use crate::edition::{Edition, parse_edition};
 use crate::errors::ErrorKind;
@@ -25,6 +26,7 @@ use crate::{fatal, help};
 pub(crate) mod auxiliary;
 mod cfg;
 mod directive_names;
+mod line;
 mod needs;
 #[cfg(test)]
 mod tests;
@@ -824,70 +826,6 @@ impl TestProps {
     }
 }
 
-/// If the given line begins with the appropriate comment prefix for a directive,
-/// returns a struct containing various parts of the directive.
-fn line_directive<'line>(
-    line_number: usize,
-    original_line: &'line str,
-) -> Option<DirectiveLine<'line>> {
-    // Ignore lines that don't start with the comment prefix.
-    let after_comment =
-        original_line.trim_start().strip_prefix(COMPILETEST_DIRECTIVE_PREFIX)?.trim_start();
-
-    let revision;
-    let raw_directive;
-
-    if let Some(after_open_bracket) = after_comment.strip_prefix('[') {
-        // A comment like `//@[foo]` only applies to revision `foo`.
-        let Some((line_revision, after_close_bracket)) = after_open_bracket.split_once(']') else {
-            panic!(
-                "malformed condition directive: expected `{COMPILETEST_DIRECTIVE_PREFIX}[foo]`, found `{original_line}`"
-            )
-        };
-
-        revision = Some(line_revision);
-        raw_directive = after_close_bracket.trim_start();
-    } else {
-        revision = None;
-        raw_directive = after_comment;
-    };
-
-    Some(DirectiveLine { line_number, revision, raw_directive })
-}
-
-/// The (partly) broken-down contents of a line containing a test directive,
-/// which [`iter_directives`] passes to its callback function.
-///
-/// For example:
-///
-/// ```text
-/// //@ compile-flags: -O
-///     ^^^^^^^^^^^^^^^^^ raw_directive
-///
-/// //@ [foo] compile-flags: -O
-///      ^^^                    revision
-///           ^^^^^^^^^^^^^^^^^ raw_directive
-/// ```
-struct DirectiveLine<'ln> {
-    line_number: usize,
-    /// Some test directives start with a revision name in square brackets
-    /// (e.g. `[foo]`), and only apply to that revision of the test.
-    /// If present, this field contains the revision name (e.g. `foo`).
-    revision: Option<&'ln str>,
-    /// The main part of the directive, after removing the comment prefix
-    /// and the optional revision specifier.
-    ///
-    /// This is "raw" because the directive's name and colon-separated value
-    /// (if present) have not yet been extracted or checked.
-    raw_directive: &'ln str,
-}
-
-impl<'ln> DirectiveLine<'ln> {
-    fn applies_to_test_revision(&self, test_revision: Option<&str>) -> bool {
-        self.revision.is_none() || self.revision == test_revision
-    }
-}
-
 pub(crate) struct CheckDirectiveResult<'ln> {
     is_known_directive: bool,
     trailing_directive: Option<&'ln str>,
@@ -897,9 +835,7 @@ fn check_directive<'a>(
     directive_ln: &DirectiveLine<'a>,
     mode: TestMode,
 ) -> CheckDirectiveResult<'a> {
-    let &DirectiveLine { raw_directive: directive_ln, .. } = directive_ln;
-
-    let (directive_name, post) = directive_ln.split_once([':', ' ']).unwrap_or((directive_ln, ""));
+    let &DirectiveLine { name: directive_name, .. } = directive_ln;
 
     let is_known_directive = KNOWN_DIRECTIVE_NAMES.contains(&directive_name)
         || match mode {
@@ -908,20 +844,17 @@ fn check_directive<'a>(
             _ => false,
         };
 
-    let trailing = post.trim().split_once(' ').map(|(pre, _)| pre).unwrap_or(post);
-    let trailing_directive = {
-        // 1. is the directive name followed by a space? (to exclude `:`)
-        directive_ln.get(directive_name.len()..).is_some_and(|s| s.starts_with(' '))
-            // 2. is what is after that directive also a directive (ex: "only-x86 only-arm")
-            && KNOWN_DIRECTIVE_NAMES.contains(&trailing)
-    }
-    .then_some(trailing);
+    // If it looks like the user tried to put two directives on the same line
+    // (e.g. `//@ only-linux only-x86_64`), signal an error, because the
+    // second "directive" would actually be ignored with no effect.
+    let trailing_directive = directive_ln
+        .remark_after_space()
+        .map(|remark| remark.trim_start().split(' ').next().unwrap())
+        .filter(|token| KNOWN_DIRECTIVE_NAMES.contains(token));
 
     CheckDirectiveResult { is_known_directive, trailing_directive }
 }
 
-const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@";
-
 fn iter_directives(
     mode: TestMode,
     poisoned: &mut bool,
@@ -939,15 +872,17 @@ fn iter_directives(
     // FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later.
     if mode == TestMode::CoverageRun {
         let extra_directives: &[&str] = &[
-            "needs-profiler-runtime",
+            "//@ needs-profiler-runtime",
             // FIXME(pietroalbini): this test currently does not work on cross-compiled targets
             // because remote-test is not capable of sending back the *.profraw files generated by
             // the LLVM instrumentation.
-            "ignore-cross-compile",
+            "//@ ignore-cross-compile",
         ];
         // Process the extra implied directives, with a dummy line number of 0.
-        for raw_directive in extra_directives {
-            it(DirectiveLine { line_number: 0, revision: None, raw_directive });
+        for directive_str in extra_directives {
+            let directive_line = line_directive(0, directive_str)
+                .unwrap_or_else(|| panic!("bad extra-directive line: {directive_str:?}"));
+            it(directive_line);
         }
     }
 
@@ -977,7 +912,7 @@ fn iter_directives(
 
                 error!(
                     "{testfile}:{line_number}: detected unknown compiletest test directive `{}`",
-                    directive_line.raw_directive,
+                    directive_line.display(),
                 );
 
                 return;
@@ -1073,13 +1008,9 @@ impl Config {
     }
 
     fn parse_custom_normalization(&self, line: &DirectiveLine<'_>) -> Option<NormalizeRule> {
-        let &DirectiveLine { raw_directive, .. } = line;
-
-        // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine`
-        // instead of doing it here.
-        let (directive_name, raw_value) = raw_directive.split_once(':')?;
+        let &DirectiveLine { name, .. } = line;
 
-        let kind = match directive_name {
+        let kind = match name {
             "normalize-stdout" => NormalizeKind::Stdout,
             "normalize-stderr" => NormalizeKind::Stderr,
             "normalize-stderr-32bit" => NormalizeKind::Stderr32bit,
@@ -1087,21 +1018,20 @@ impl Config {
             _ => return None,
         };
 
-        let Some((regex, replacement)) = parse_normalize_rule(raw_value) else {
-            error!("couldn't parse custom normalization rule: `{raw_directive}`");
-            help!("expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`");
+        let Some((regex, replacement)) = line.value_after_colon().and_then(parse_normalize_rule)
+        else {
+            error!("couldn't parse custom normalization rule: `{}`", line.display());
+            help!("expected syntax is: `{name}: \"REGEX\" -> \"REPLACEMENT\"`");
             panic!("invalid normalization rule detected");
         };
         Some(NormalizeRule { kind, regex, replacement })
     }
 
     fn parse_name_directive(&self, line: &DirectiveLine<'_>, directive: &str) -> bool {
-        let &DirectiveLine { raw_directive: line, .. } = line;
-
-        // Ensure the directive is a whole word. Do not match "ignore-x86" when
-        // the line says "ignore-x86_64".
-        line.starts_with(directive)
-            && matches!(line.as_bytes().get(directive.len()), None | Some(&b' ') | Some(&b':'))
+        // FIXME(Zalathar): Ideally, this should raise an error if a name-only
+        // directive is followed by a colon, since that's the wrong syntax.
+        // But we would need to fix tests that rely on the current behaviour.
+        line.name == directive
     }
 
     fn parse_name_value_directive(
@@ -1110,22 +1040,26 @@ impl Config {
         directive: &str,
         testfile: &Utf8Path,
     ) -> Option<String> {
-        let &DirectiveLine { line_number, raw_directive: line, .. } = line;
-
-        let colon = directive.len();
-        if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') {
-            let value = line[(colon + 1)..].to_owned();
-            debug!("{}: {}", directive, value);
-            let value = expand_variables(value, self);
-            if value.is_empty() {
-                error!("{testfile}:{line_number}: empty value for directive `{directive}`");
-                help!("expected syntax is: `{directive}: value`");
-                panic!("empty directive value detected");
-            }
-            Some(value)
-        } else {
-            None
+        let &DirectiveLine { line_number, .. } = line;
+
+        if line.name != directive {
+            return None;
+        };
+
+        // FIXME(Zalathar): This silently discards directives with a matching
+        // name but no colon. Unfortunately, some directives (e.g. "pp-exact")
+        // currently rely on _not_ panicking here.
+        let value = line.value_after_colon()?;
+        debug!("{}: {}", directive, value);
+        let value = expand_variables(value.to_owned(), self);
+
+        if value.is_empty() {
+            error!("{testfile}:{line_number}: empty value for directive `{directive}`");
+            help!("expected syntax is: `{directive}: value`");
+            panic!("empty directive value detected");
         }
+
+        Some(value)
     }
 
     fn set_name_directive(&self, line: &DirectiveLine<'_>, directive: &str, value: &mut bool) {
@@ -1515,14 +1449,14 @@ pub(crate) fn make_test_description<R: Read>(
 }
 
 fn ignore_cdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
-    let &DirectiveLine { raw_directive: line, .. } = line;
-
     if config.debugger != Some(Debugger::Cdb) {
         return IgnoreDecision::Continue;
     }
 
     if let Some(actual_version) = config.cdb_version {
-        if let Some(rest) = line.strip_prefix("min-cdb-version:").map(str::trim) {
+        if line.name == "min-cdb-version"
+            && let Some(rest) = line.value_after_colon().map(str::trim)
+        {
             let min_version = extract_cdb_version(rest).unwrap_or_else(|| {
                 panic!("couldn't parse version range: {:?}", rest);
             });
@@ -1540,14 +1474,14 @@ fn ignore_cdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
 }
 
 fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
-    let &DirectiveLine { raw_directive: line, .. } = line;
-
     if config.debugger != Some(Debugger::Gdb) {
         return IgnoreDecision::Continue;
     }
 
     if let Some(actual_version) = config.gdb_version {
-        if let Some(rest) = line.strip_prefix("min-gdb-version:").map(str::trim) {
+        if line.name == "min-gdb-version"
+            && let Some(rest) = line.value_after_colon().map(str::trim)
+        {
             let (start_ver, end_ver) = extract_version_range(rest, extract_gdb_version)
                 .unwrap_or_else(|| {
                     panic!("couldn't parse version range: {:?}", rest);
@@ -1563,7 +1497,9 @@ fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
                     reason: format!("ignored when the GDB version is lower than {rest}"),
                 };
             }
-        } else if let Some(rest) = line.strip_prefix("ignore-gdb-version:").map(str::trim) {
+        } else if line.name == "ignore-gdb-version"
+            && let Some(rest) = line.value_after_colon().map(str::trim)
+        {
             let (min_version, max_version) = extract_version_range(rest, extract_gdb_version)
                 .unwrap_or_else(|| {
                     panic!("couldn't parse version range: {:?}", rest);
@@ -1590,14 +1526,14 @@ fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
 }
 
 fn ignore_lldb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
-    let &DirectiveLine { raw_directive: line, .. } = line;
-
     if config.debugger != Some(Debugger::Lldb) {
         return IgnoreDecision::Continue;
     }
 
     if let Some(actual_version) = config.lldb_version {
-        if let Some(rest) = line.strip_prefix("min-lldb-version:").map(str::trim) {
+        if line.name == "min-lldb-version"
+            && let Some(rest) = line.value_after_colon().map(str::trim)
+        {
             let min_version = rest.parse().unwrap_or_else(|e| {
                 panic!("Unexpected format of LLDB version string: {}\n{:?}", rest, e);
             });
diff --git a/src/tools/compiletest/src/directives/auxiliary.rs b/src/tools/compiletest/src/directives/auxiliary.rs
index 0675a6feac3..7cf98178e73 100644
--- a/src/tools/compiletest/src/directives/auxiliary.rs
+++ b/src/tools/compiletest/src/directives/auxiliary.rs
@@ -50,9 +50,7 @@ pub(super) fn parse_and_update_aux(
     testfile: &Utf8Path,
     aux: &mut AuxProps,
 ) {
-    let &DirectiveLine { raw_directive: ln, .. } = directive_line;
-
-    if !(ln.starts_with("aux-") || ln.starts_with("proc-macro")) {
+    if !(directive_line.name.starts_with("aux-") || directive_line.name == "proc-macro") {
         return;
     }
 
diff --git a/src/tools/compiletest/src/directives/cfg.rs b/src/tools/compiletest/src/directives/cfg.rs
index 62a4b88a33a..3855ba7ac5f 100644
--- a/src/tools/compiletest/src/directives/cfg.rs
+++ b/src/tools/compiletest/src/directives/cfg.rs
@@ -6,8 +6,8 @@ use crate::directives::{DirectiveLine, IgnoreDecision};
 const EXTRA_ARCHS: &[&str] = &["spirv"];
 
 pub(super) fn handle_ignore(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
-    let parsed = parse_cfg_name_directive(config, line, "ignore");
-    let &DirectiveLine { raw_directive: line, .. } = line;
+    let parsed = parse_cfg_name_directive(config, line, "ignore-");
+    let line = line.display();
 
     match parsed.outcome {
         MatchOutcome::NoMatch => IgnoreDecision::Continue,
@@ -24,8 +24,8 @@ pub(super) fn handle_ignore(config: &Config, line: &DirectiveLine<'_>) -> Ignore
 }
 
 pub(super) fn handle_only(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
-    let parsed = parse_cfg_name_directive(config, line, "only");
-    let &DirectiveLine { raw_directive: line, .. } = line;
+    let parsed = parse_cfg_name_directive(config, line, "only-");
+    let line = line.display();
 
     match parsed.outcome {
         MatchOutcome::Match => IgnoreDecision::Continue,
@@ -50,18 +50,14 @@ fn parse_cfg_name_directive<'a>(
     line: &'a DirectiveLine<'a>,
     prefix: &str,
 ) -> ParsedNameDirective<'a> {
-    let &DirectiveLine { raw_directive: line, .. } = line;
-
-    if !line.as_bytes().starts_with(prefix.as_bytes()) {
-        return ParsedNameDirective::not_a_directive();
-    }
-    if line.as_bytes().get(prefix.len()) != Some(&b'-') {
+    let Some(name) = line.name.strip_prefix(prefix) else {
         return ParsedNameDirective::not_a_directive();
-    }
-    let line = &line[prefix.len() + 1..];
+    };
 
-    let (name, comment) =
-        line.split_once(&[':', ' ']).map(|(l, c)| (l, Some(c))).unwrap_or((line, None));
+    // FIXME(Zalathar): This currently allows either a space or a colon, and
+    // treats any "value" after a colon as though it were a remark.
+    // We should instead forbid the colon syntax for these directives.
+    let comment = line.remark_after_space().or_else(|| line.value_after_colon());
 
     // Some of the matchers might be "" depending on what the target information is. To avoid
     // problems we outright reject empty directives.
@@ -269,7 +265,7 @@ fn parse_cfg_name_directive<'a>(
         message: "when performing tests on dist toolchain"
     }
 
-    if prefix == "ignore" && outcome == MatchOutcome::Invalid {
+    if prefix == "ignore-" && outcome == MatchOutcome::Invalid {
         // Don't error out for ignore-tidy-* diretives, as those are not handled by compiletest.
         if name.starts_with("tidy-") {
             outcome = MatchOutcome::External;
diff --git a/src/tools/compiletest/src/directives/line.rs b/src/tools/compiletest/src/directives/line.rs
new file mode 100644
index 00000000000..e81806d6082
--- /dev/null
+++ b/src/tools/compiletest/src/directives/line.rs
@@ -0,0 +1,108 @@
+use std::fmt;
+
+const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@";
+
+/// If the given line begins with the appropriate comment prefix for a directive,
+/// returns a struct containing various parts of the directive.
+pub(crate) fn line_directive<'line>(
+    line_number: usize,
+    original_line: &'line str,
+) -> Option<DirectiveLine<'line>> {
+    // Ignore lines that don't start with the comment prefix.
+    let after_comment =
+        original_line.trim_start().strip_prefix(COMPILETEST_DIRECTIVE_PREFIX)?.trim_start();
+
+    let revision;
+    let raw_directive;
+
+    if let Some(after_open_bracket) = after_comment.strip_prefix('[') {
+        // A comment like `//@[foo]` only applies to revision `foo`.
+        let Some((line_revision, after_close_bracket)) = after_open_bracket.split_once(']') else {
+            panic!(
+                "malformed condition directive: expected `{COMPILETEST_DIRECTIVE_PREFIX}[foo]`, found `{original_line}`"
+            )
+        };
+
+        revision = Some(line_revision);
+        raw_directive = after_close_bracket.trim_start();
+    } else {
+        revision = None;
+        raw_directive = after_comment;
+    };
+
+    // The directive name ends at the first occurrence of colon, space, or end-of-string.
+    let name = raw_directive.split([':', ' ']).next().expect("split is never empty");
+
+    Some(DirectiveLine { line_number, revision, raw_directive, name })
+}
+
+/// The (partly) broken-down contents of a line containing a test directive,
+/// which [`iter_directives`] passes to its callback function.
+///
+/// For example:
+///
+/// ```text
+/// //@ compile-flags: -O
+///     ^^^^^^^^^^^^^^^^^ raw_directive
+///     ^^^^^^^^^^^^^     name
+///
+/// //@ [foo] compile-flags: -O
+///      ^^^                    revision
+///           ^^^^^^^^^^^^^^^^^ raw_directive
+///           ^^^^^^^^^^^^^     name
+/// ```
+pub(crate) struct DirectiveLine<'ln> {
+    pub(crate) line_number: usize,
+
+    /// Some test directives start with a revision name in square brackets
+    /// (e.g. `[foo]`), and only apply to that revision of the test.
+    /// If present, this field contains the revision name (e.g. `foo`).
+    pub(crate) revision: Option<&'ln str>,
+
+    /// The main part of the directive, after removing the comment prefix
+    /// and the optional revision specifier.
+    ///
+    /// This is "raw" because the directive's name and colon-separated value
+    /// (if present) have not yet been extracted or checked.
+    raw_directive: &'ln str,
+
+    /// Name of the directive.
+    ///
+    /// Invariant: `self.raw_directive.starts_with(self.name)`
+    pub(crate) name: &'ln str,
+}
+
+impl<'ln> DirectiveLine<'ln> {
+    pub(crate) fn applies_to_test_revision(&self, test_revision: Option<&str>) -> bool {
+        self.revision.is_none() || self.revision == test_revision
+    }
+
+    /// Helper method used by `value_after_colon` and `remark_after_space`.
+    /// Don't call this directly.
+    fn rest_after_separator(&self, separator: u8) -> Option<&'ln str> {
+        let n = self.name.len();
+        if self.raw_directive.as_bytes().get(n) != Some(&separator) {
+            return None;
+        }
+
+        Some(&self.raw_directive[n + 1..])
+    }
+
+    /// If this directive uses `name: value` syntax, returns the part after
+    /// the colon character.
+    pub(crate) fn value_after_colon(&self) -> Option<&'ln str> {
+        self.rest_after_separator(b':')
+    }
+
+    /// If this directive uses `name remark` syntax, returns the part after
+    /// the separating space.
+    pub(crate) fn remark_after_space(&self) -> Option<&'ln str> {
+        self.rest_after_separator(b' ')
+    }
+
+    /// Allows callers to print `raw_directive` if necessary,
+    /// without accessing the field directly.
+    pub(crate) fn display(&self) -> impl fmt::Display {
+        self.raw_directive
+    }
+}
diff --git a/src/tools/compiletest/src/directives/needs.rs b/src/tools/compiletest/src/directives/needs.rs
index c8a729d8aab..5e9fe59d8d1 100644
--- a/src/tools/compiletest/src/directives/needs.rs
+++ b/src/tools/compiletest/src/directives/needs.rs
@@ -181,17 +181,10 @@ pub(super) fn handle_needs(
         },
     ];
 
-    let &DirectiveLine { raw_directive: ln, .. } = ln;
+    let &DirectiveLine { name, .. } = ln;
 
-    let (name, rest) = match ln.split_once([':', ' ']) {
-        Some((name, rest)) => (name, Some(rest)),
-        None => (ln, None),
-    };
-
-    // FIXME(jieyouxu): tighten up this parsing to reject using both `:` and ` ` as means to
-    // delineate value.
     if name == "needs-target-has-atomic" {
-        let Some(rest) = rest else {
+        let Some(rest) = ln.value_after_colon() else {
             return IgnoreDecision::Error {
                 message: "expected `needs-target-has-atomic` to have a comma-separated list of atomic widths".to_string(),
             };
@@ -233,7 +226,7 @@ pub(super) fn handle_needs(
 
     // FIXME(jieyouxu): share multi-value directive logic with `needs-target-has-atomic` above.
     if name == "needs-crate-type" {
-        let Some(rest) = rest else {
+        let Some(rest) = ln.value_after_colon() else {
             return IgnoreDecision::Error {
                 message:
                     "expected `needs-crate-type` to have a comma-separated list of crate types"
@@ -281,10 +274,7 @@ pub(super) fn handle_needs(
 
     // Handled elsewhere.
     if name == "needs-llvm-components" {
-        if config.default_codegen_backend.is_llvm() {
-            return IgnoreDecision::Continue;
-        }
-        return IgnoreDecision::Ignore { reason: "LLVM specific test".into() };
+        return IgnoreDecision::Continue;
     }
 
     let mut found_valid = false;
@@ -295,7 +285,7 @@ pub(super) fn handle_needs(
                 break;
             } else {
                 return IgnoreDecision::Ignore {
-                    reason: if let Some(comment) = rest {
+                    reason: if let Some(comment) = ln.remark_after_space() {
                         format!("{} ({})", need.ignore_reason, comment.trim())
                     } else {
                         need.ignore_reason.into()
diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs
index 93621192d4b..95dd46532ba 100644
--- a/src/tools/compiletest/src/directives/tests.rs
+++ b/src/tools/compiletest/src/directives/tests.rs
@@ -3,12 +3,11 @@ use std::io::Read;
 use camino::Utf8Path;
 use semver::Version;
 
-use super::{
+use crate::common::{Config, Debugger, TestMode};
+use crate::directives::{
     DirectivesCache, EarlyProps, Edition, EditionRange, extract_llvm_version,
-    extract_version_range, iter_directives, parse_normalize_rule,
+    extract_version_range, iter_directives, line_directive, parse_edition, parse_normalize_rule,
 };
-use crate::common::{Config, Debugger, TestMode};
-use crate::directives::parse_edition;
 use crate::executor::{CollectedTestDesc, ShouldPanic};
 
 fn make_test_description<R: Read>(
@@ -955,7 +954,9 @@ fn test_needs_target_std() {
 
 fn parse_edition_range(line: &str) -> Option<EditionRange> {
     let config = cfg().build();
-    let line = super::DirectiveLine { line_number: 0, revision: None, raw_directive: line };
+
+    let line_with_comment = format!("//@ {line}");
+    let line = line_directive(0, &line_with_comment).unwrap();
 
     super::parse_edition_range(&config, &line, "tmp.rs".into())
 }
diff --git a/tests/codegen-llvm/autodiff/batched.rs b/tests/codegen-llvm/autodiff/batched.rs
index dc82403212f..0ff6134bc07 100644
--- a/tests/codegen-llvm/autodiff/batched.rs
+++ b/tests/codegen-llvm/autodiff/batched.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3  -Clto=fat
+//@ compile-flags: -Zautodiff=Enable,NoTT,NoPostopt -C opt-level=3  -Clto=fat
 //@ no-prefer-dynamic
 //@ needs-enzyme
 //
@@ -23,7 +23,7 @@ fn square(x: &f32) -> f32 {
 }
 
 // d_square2
-// CHECK: define internal fastcc [4 x float] @fwddiffe4square(float %x.0.val, [4 x ptr] %"x'")
+// CHECK: define internal [4 x float] @fwddiffe4square(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'")
 // CHECK-NEXT: start:
 // CHECK-NEXT:   %0 = extractvalue [4 x ptr] %"x'", 0
 // CHECK-NEXT:   %"_2'ipl" = load float, ptr %0, align 4
@@ -33,23 +33,28 @@ fn square(x: &f32) -> f32 {
 // CHECK-NEXT:   %"_2'ipl2" = load float, ptr %2, align 4
 // CHECK-NEXT:   %3 = extractvalue [4 x ptr] %"x'", 3
 // CHECK-NEXT:   %"_2'ipl3" = load float, ptr %3, align 4
-// CHECK-NEXT:   %4 = fmul float %"_2'ipl", 2.000000e+00
-// CHECK-NEXT:   %5 = fmul fast float %4, %x.0.val
-// CHECK-NEXT:   %6 = insertvalue [4 x float] undef, float %5, 0
-// CHECK-NEXT:   %7 = fmul float %"_2'ipl1", 2.000000e+00
-// CHECK-NEXT:   %8 = fmul fast float %7, %x.0.val
-// CHECK-NEXT:   %9 = insertvalue [4 x float] %6, float %8, 1
-// CHECK-NEXT:   %10 = fmul float %"_2'ipl2", 2.000000e+00
-// CHECK-NEXT:   %11 = fmul fast float %10, %x.0.val
-// CHECK-NEXT:   %12 = insertvalue [4 x float] %9, float %11, 2
-// CHECK-NEXT:   %13 = fmul float %"_2'ipl3", 2.000000e+00
-// CHECK-NEXT:   %14 = fmul fast float %13, %x.0.val
-// CHECK-NEXT:   %15 = insertvalue [4 x float] %12, float %14, 3
-// CHECK-NEXT:   ret [4 x float] %15
+// CHECK-NEXT:   %_2 = load float, ptr %x, align 4
+// CHECK-NEXT:   %4 = fmul fast float %"_2'ipl", %_2
+// CHECK-NEXT:   %5 = fmul fast float %"_2'ipl1", %_2
+// CHECK-NEXT:   %6 = fmul fast float %"_2'ipl2", %_2
+// CHECK-NEXT:   %7 = fmul fast float %"_2'ipl3", %_2
+// CHECK-NEXT:   %8 = fmul fast float %"_2'ipl", %_2
+// CHECK-NEXT:   %9 = fmul fast float %"_2'ipl1", %_2
+// CHECK-NEXT:   %10 = fmul fast float %"_2'ipl2", %_2
+// CHECK-NEXT:   %11 = fmul fast float %"_2'ipl3", %_2
+// CHECK-NEXT:   %12 = fadd fast float %4, %8
+// CHECK-NEXT:   %13 = insertvalue [4 x float] undef, float %12, 0
+// CHECK-NEXT:   %14 = fadd fast float %5, %9
+// CHECK-NEXT:   %15 = insertvalue [4 x float] %13, float %14, 1
+// CHECK-NEXT:   %16 = fadd fast float %6, %10
+// CHECK-NEXT:   %17 = insertvalue [4 x float] %15, float %16, 2
+// CHECK-NEXT:   %18 = fadd fast float %7, %11
+// CHECK-NEXT:   %19 = insertvalue [4 x float] %17, float %18, 3
+// CHECK-NEXT:   ret [4 x float] %19
 // CHECK-NEXT:   }
 
 // d_square3, the extra float is the original return value (x * x)
-// CHECK: define internal fastcc { float, [4 x float] } @fwddiffe4square.1(float %x.0.val, [4 x ptr] %"x'")
+// CHECK: define internal { float, [4 x float] } @fwddiffe4square.1(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'")
 // CHECK-NEXT: start:
 // CHECK-NEXT:   %0 = extractvalue [4 x ptr] %"x'", 0
 // CHECK-NEXT:   %"_2'ipl" = load float, ptr %0, align 4
@@ -59,22 +64,27 @@ fn square(x: &f32) -> f32 {
 // CHECK-NEXT:   %"_2'ipl2" = load float, ptr %2, align 4
 // CHECK-NEXT:   %3 = extractvalue [4 x ptr] %"x'", 3
 // CHECK-NEXT:   %"_2'ipl3" = load float, ptr %3, align 4
-// CHECK-NEXT:   %_0 = fmul float %x.0.val, %x.0.val
-// CHECK-NEXT:   %4 = fmul float %"_2'ipl", 2.000000e+00
-// CHECK-NEXT:   %5 = fmul fast float %4, %x.0.val
-// CHECK-NEXT:   %6 = insertvalue [4 x float] undef, float %5, 0
-// CHECK-NEXT:   %7 = fmul float %"_2'ipl1", 2.000000e+00
-// CHECK-NEXT:   %8 = fmul fast float %7, %x.0.val
-// CHECK-NEXT:   %9 = insertvalue [4 x float] %6, float %8, 1
-// CHECK-NEXT:   %10 = fmul float %"_2'ipl2", 2.000000e+00
-// CHECK-NEXT:   %11 = fmul fast float %10, %x.0.val
-// CHECK-NEXT:   %12 = insertvalue [4 x float] %9, float %11, 2
-// CHECK-NEXT:   %13 = fmul float %"_2'ipl3", 2.000000e+00
-// CHECK-NEXT:   %14 = fmul fast float %13, %x.0.val
-// CHECK-NEXT:   %15 = insertvalue [4 x float] %12, float %14, 3
-// CHECK-NEXT:   %16 = insertvalue { float, [4 x float] } undef, float %_0, 0
-// CHECK-NEXT:   %17 = insertvalue { float, [4 x float] } %16, [4 x float] %15, 1
-// CHECK-NEXT:   ret { float, [4 x float] } %17
+// CHECK-NEXT:   %_2 = load float, ptr %x, align 4
+// CHECK-NEXT:   %_0 = fmul float %_2, %_2
+// CHECK-NEXT:   %4 = fmul fast float %"_2'ipl", %_2
+// CHECK-NEXT:   %5 = fmul fast float %"_2'ipl1", %_2
+// CHECK-NEXT:   %6 = fmul fast float %"_2'ipl2", %_2
+// CHECK-NEXT:   %7 = fmul fast float %"_2'ipl3", %_2
+// CHECK-NEXT:   %8 = fmul fast float %"_2'ipl", %_2
+// CHECK-NEXT:   %9 = fmul fast float %"_2'ipl1", %_2
+// CHECK-NEXT:   %10 = fmul fast float %"_2'ipl2", %_2
+// CHECK-NEXT:   %11 = fmul fast float %"_2'ipl3", %_2
+// CHECK-NEXT:   %12 = fadd fast float %4, %8
+// CHECK-NEXT:   %13 = insertvalue [4 x float] undef, float %12, 0
+// CHECK-NEXT:   %14 = fadd fast float %5, %9
+// CHECK-NEXT:   %15 = insertvalue [4 x float] %13, float %14, 1
+// CHECK-NEXT:   %16 = fadd fast float %6, %10
+// CHECK-NEXT:   %17 = insertvalue [4 x float] %15, float %16, 2
+// CHECK-NEXT:   %18 = fadd fast float %7, %11
+// CHECK-NEXT:   %19 = insertvalue [4 x float] %17, float %18, 3
+// CHECK-NEXT:   %20 = insertvalue { float, [4 x float] } undef, float %_0, 0
+// CHECK-NEXT:   %21 = insertvalue { float, [4 x float] } %20, [4 x float] %19, 1
+// CHECK-NEXT:   ret { float, [4 x float] } %21
 // CHECK-NEXT:   }
 
 fn main() {
diff --git a/tests/ui/consts/std/conjure_zst.rs b/tests/ui/consts/std/conjure_zst.rs
new file mode 100644
index 00000000000..c04deae502b
--- /dev/null
+++ b/tests/ui/consts/std/conjure_zst.rs
@@ -0,0 +1,10 @@
+#![feature(mem_conjure_zst)]
+
+use std::{convert::Infallible, mem};
+
+const INVALID: Infallible = unsafe { mem::conjure_zst() };
+//~^ ERROR attempted to instantiate uninhabited type
+
+const VALID: () = unsafe { mem::conjure_zst() };
+
+fn main() {}
diff --git a/tests/ui/consts/std/conjure_zst.stderr b/tests/ui/consts/std/conjure_zst.stderr
new file mode 100644
index 00000000000..0c4a978b81e
--- /dev/null
+++ b/tests/ui/consts/std/conjure_zst.stderr
@@ -0,0 +1,12 @@
+error[E0080]: evaluation panicked: aborted execution: attempted to instantiate uninhabited type `Infallible`
+  --> $DIR/conjure_zst.rs:5:38
+   |
+LL | const INVALID: Infallible = unsafe { mem::conjure_zst() };
+   |                                      ^^^^^^^^^^^^^^^^^^ evaluation of `INVALID` failed inside this call
+   |
+note: inside `conjure_zst::<Infallible>`
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.current.stderr
index f69be60133e..55564e8f231 100644
--- a/tests/ui/delegation/unsupported.stderr
+++ b/tests/ui/delegation/unsupported.current.stderr
@@ -1,43 +1,43 @@
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::opaque_ret::{anon_assoc#0}`
-  --> $DIR/unsupported.rs:22:25
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`
+  --> $DIR/unsupported.rs:30:25
    |
 LL |         reuse to_reuse::opaque_ret;
    |                         ^^^^^^^^^^
    |
 note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
-  --> $DIR/unsupported.rs:22:25
+  --> $DIR/unsupported.rs:30:25
    |
 LL |         reuse to_reuse::opaque_ret;
    |                         ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
-note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::opaque_ret` is compatible with trait definition
-  --> $DIR/unsupported.rs:22:25
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
+note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret` is compatible with trait definition
+  --> $DIR/unsupported.rs:30:25
    |
 LL |         reuse to_reuse::opaque_ret;
    |                         ^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::opaque_ret::{anon_assoc#0}`
-  --> $DIR/unsupported.rs:25:24
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`
+  --> $DIR/unsupported.rs:33:24
    |
 LL |         reuse ToReuse::opaque_ret;
    |                        ^^^^^^^^^^
    |
 note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
-  --> $DIR/unsupported.rs:25:24
+  --> $DIR/unsupported.rs:33:24
    |
 LL |         reuse ToReuse::opaque_ret;
    |                        ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
-note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::opaque_ret` is compatible with trait definition
-  --> $DIR/unsupported.rs:25:24
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
+note: cycle used when checking assoc item `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret` is compatible with trait definition
+  --> $DIR/unsupported.rs:33:24
    |
 LL |         reuse ToReuse::opaque_ret;
    |                        ^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: recursive delegation is not supported yet
-  --> $DIR/unsupported.rs:38:22
+  --> $DIR/unsupported.rs:46:22
    |
 LL |         pub reuse to_reuse2::foo;
    |                              --- callee defined here
@@ -46,7 +46,7 @@ LL |     reuse to_reuse1::foo;
    |                      ^^^
 
 error[E0283]: type annotations needed
-  --> $DIR/unsupported.rs:48:18
+  --> $DIR/unsupported.rs:56:18
    |
 LL |     reuse Trait::foo;
    |                  ^^^ cannot infer type
diff --git a/tests/ui/delegation/unsupported.next.stderr b/tests/ui/delegation/unsupported.next.stderr
new file mode 100644
index 00000000000..606a25d4269
--- /dev/null
+++ b/tests/ui/delegation/unsupported.next.stderr
@@ -0,0 +1,51 @@
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`
+  --> $DIR/unsupported.rs:30:25
+   |
+LL |         reuse to_reuse::opaque_ret;
+   |                         ^^^^^^^^^^
+   |
+note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
+  --> $DIR/unsupported.rs:30:25
+   |
+LL |         reuse to_reuse::opaque_ret;
+   |                         ^^^^^^^^^^
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
+   = note: cycle used when computing implied outlives bounds for `<u8 as opaque::ToReuse>::opaque_ret::{anon_assoc#0}` (hack disabled = false)
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`
+  --> $DIR/unsupported.rs:33:24
+   |
+LL |         reuse ToReuse::opaque_ret;
+   |                        ^^^^^^^^^^
+   |
+note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
+  --> $DIR/unsupported.rs:33:24
+   |
+LL |         reuse ToReuse::opaque_ret;
+   |                        ^^^^^^^^^^
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:32:5: 32:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
+   = note: cycle used when computing implied outlives bounds for `<u16 as opaque::ToReuse>::opaque_ret::{anon_assoc#0}` (hack disabled = false)
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: recursive delegation is not supported yet
+  --> $DIR/unsupported.rs:46:22
+   |
+LL |         pub reuse to_reuse2::foo;
+   |                              --- callee defined here
+...
+LL |     reuse to_reuse1::foo;
+   |                      ^^^
+
+error[E0283]: type annotations needed
+  --> $DIR/unsupported.rs:56:18
+   |
+LL |     reuse Trait::foo;
+   |                  ^^^ cannot infer type
+   |
+   = note: cannot satisfy `_: effects::Trait`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0283, E0391.
+For more information about an error, try `rustc --explain E0283`.
diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs
index af1c20976d7..79bab342da0 100644
--- a/tests/ui/delegation/unsupported.rs
+++ b/tests/ui/delegation/unsupported.rs
@@ -1,3 +1,11 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@ check-fail
+
+// Next solver revision included because of trait-system-refactor-initiative#234.
+// If we end up in a query cycle, it should be okay as long as results are the same.
+
 #![feature(const_trait_impl)]
 #![feature(c_variadic)]
 #![feature(fn_delegation)]