From 13ee69ddfbe477a9b515479b61a596bcfcd47abd Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 29 May 2024 04:46:57 +0200 Subject: [PATCH 01/45] Update bundled musl to 1.2.5 --- src/ci/docker/scripts/musl-toolchain.sh | 10 +++--- src/ci/docker/scripts/musl.sh | 2 +- src/doc/rustc/src/platform-support.md | 48 ++++++++++++------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index bc1b30e2d31ae..c52c5ea7953c8 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -4,7 +4,7 @@ # # Versions of the toolchain components are configurable in `musl-cross-make/Makefile` and # musl unlike GLIBC is forward compatible so upgrading it shouldn't break old distributions. -# Right now we have: Binutils 2.31.1, GCC 9.2.0, musl 1.2.3. +# Right now we have: Binutils 2.31.1, GCC 9.2.0, musl 1.2.5. # ignore-tidy-linelength @@ -45,11 +45,11 @@ export CFLAGS="-fPIC -g1 $CFLAGS" git clone https://github.com/richfelker/musl-cross-make # -b v0.9.9 cd musl-cross-make -# A version that includes support for building musl 1.2.3 -git checkout fe915821b652a7fa37b34a596f47d8e20bc72338 +# A version that includes support for building musl 1.2.5 +git checkout e149c31c48b4f4a4c9349ddf7bc0027b90245afc -hide_output make -j$(nproc) TARGET=$TARGET MUSL_VER=1.2.3 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER -hide_output make install TARGET=$TARGET MUSL_VER=1.2.3 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER OUTPUT=$OUTPUT +hide_output make -j$(nproc) TARGET=$TARGET MUSL_VER=1.2.5 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER +hide_output make install TARGET=$TARGET MUSL_VER=1.2.5 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER OUTPUT=$OUTPUT cd - diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh index 9878bec6fbe8c..7e293d748ce16 100644 --- a/src/ci/docker/scripts/musl.sh +++ b/src/ci/docker/scripts/musl.sh @@ -25,7 +25,7 @@ shift # Apparently applying `-fPIC` everywhere allows them to link successfully. export CFLAGS="-fPIC $CFLAGS" -MUSL=musl-1.2.3 +MUSL=musl-1.2.5 # may have been downloaded in a previous run if [ ! -d $MUSL ]; then diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 263ea1ddb4250..e56e933da5567 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -89,7 +89,7 @@ so Rustup may install the documentation for a similar tier 1 target instead. target | notes -------|------- [`aarch64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ARM64 MinGW (Windows 10+), LLVM ABI -[`aarch64-unknown-linux-musl`](platform-support/aarch64-unknown-linux-musl.md) | ARM64 Linux with musl 1.2.3 +[`aarch64-unknown-linux-musl`](platform-support/aarch64-unknown-linux-musl.md) | ARM64 Linux with musl 1.2.5 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony `arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2+, glibc 2.17) `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2+, glibc 2.17) @@ -101,14 +101,14 @@ target | notes `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2+, glibc 2.17) `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2+, glibc 2.17) [`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10+, glibc 2.17) -[`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19+, musl 1.2.3) +[`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19+, musl 1.2.5) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20+, glibc 2.29) [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2+, glibc 2.17) [`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+) [`x86_64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | 64-bit x86 MinGW (Windows 10+), LLVM ABI [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit x86 FreeBSD [`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos -`x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3 +`x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.5 [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | x86_64 OpenHarmony [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 [`x86_64-pc-solaris`](platform-support/solaris.md) | 64-bit x86 Solaris 11.4 @@ -153,24 +153,24 @@ target | std | notes [`aarch64-unknown-none-softfloat`](platform-support/aarch64-unknown-none.md) | * | Bare ARM64, softfloat [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI [`arm-linux-androideabi`](platform-support/android.md) | ✓ | Armv6 Android -`arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.3 -`arm-unknown-linux-musleabihf` | ✓ | Armv6 Linux with musl 1.2.3, hardfloat +`arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.5 +`arm-unknown-linux-musleabihf` | ✓ | Armv6 Linux with musl 1.2.5, hardfloat [`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ✓ | Arm64EC Windows MSVC [`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4+, glibc 2.23) -`armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3 +`armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.5 [`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android [`armv7-unknown-linux-gnueabi`](platform-support/armv7-unknown-linux-gnueabi.md) | ✓ | Armv7-A Linux (kernel 4.15+, glibc 2.27) -`armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.3 -`armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat +`armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.5 +`armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.5, hardfloat [`armv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | Bare Armv7-A [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat `i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2+, glibc 2.17, original Pentium) [^x86_32-floats-x87] -`i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87] +`i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.5, original Pentium) [^x86_32-floats-x87] [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI] [`i686-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI] [`i686-unknown-freebsd`](platform-support/freebsd.md) | ✓ | 32-bit x86 FreeBSD (Pentium 4) [^x86_32-floats-return-ABI] -`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 (Pentium 4) [^x86_32-floats-return-ABI] +`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.5 (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI (Pentium 4, softfloat) [^win32-msvc-alignment] [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) @@ -180,7 +180,7 @@ target | std | notes [`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) -[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.3) +[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.5) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23) @@ -312,7 +312,7 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) `csky-unknown-linux-gnuabiv2hf` | ✓ | | C-SKY abiv2 Linux, hardfloat (little endian) -[`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.3 +[`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.5 [`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] @@ -334,17 +334,17 @@ target | std | host | notes [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux [`m68k-unknown-none-elf`](platform-support/m68k-unknown-none-elf.md) | | | Motorola 680x0 `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23) -`mips-unknown-linux-musl` | ✓ | | MIPS Linux with musl 1.2.3 +`mips-unknown-linux-musl` | ✓ | | MIPS Linux with musl 1.2.5 `mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc -[`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux musl 1.2.3 +[`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux musl 1.2.5 `mips64-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 Linux, N64 ABI (kernel 4.4, glibc 2.23) -[`mips64-unknown-linux-muslabi64`](platform-support/mips64-unknown-linux-muslabi64.md) | ✓ | ✓ | MIPS64 Linux, N64 ABI, musl 1.2.3 +[`mips64-unknown-linux-muslabi64`](platform-support/mips64-unknown-linux-muslabi64.md) | ✓ | ✓ | MIPS64 Linux, N64 ABI, musl 1.2.5 `mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (little endian) Linux, N64 ABI (kernel 4.4, glibc 2.23) -`mips64el-unknown-linux-muslabi64` | ✓ | | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.3 +`mips64el-unknown-linux-muslabi64` | ✓ | | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.5 `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) [`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) [`mipsel-unknown-linux-gnu`](platform-support/mipsel-unknown-linux-gnu.md) | ✓ | ✓ | MIPS (little endian) Linux (kernel 4.4, glibc 2.23) -`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.3 +`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.5 `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc [`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat @@ -357,15 +357,15 @@ target | std | host | notes `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers [`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD [`powerpc-unknown-linux-gnuspe`](platform-support/powerpc-unknown-linux-gnuspe.md) | ✓ | | PowerPC SPE Linux -`powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3 -[`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux with musl 1.2.3 +`powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.5 +[`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux with musl 1.2.5 [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | | [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | [`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer) [`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2) -[`powerpc64-unknown-linux-musl`](platform-support/powerpc64-unknown-linux-musl.md) | ✓ | ✓ | PPC64 Linux (kernel 4.19, musl 1.2.3) +[`powerpc64-unknown-linux-musl`](platform-support/powerpc64-unknown-linux-musl.md) | ✓ | ✓ | PPC64 Linux (kernel 4.19, musl 1.2.5) [`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 [`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD @@ -374,7 +374,7 @@ target | std | host | notes [`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) [`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) `riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) -`riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.3 + RISCV32 support patches) +`riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.5 + RISCV32 support patches) [`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA) [`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA) [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF @@ -395,7 +395,7 @@ target | std | host | notes [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 [`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX [`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39) -[`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.3) +[`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.5) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ [`sparc64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/sparc64 @@ -410,7 +410,7 @@ target | std | host | notes [`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX [`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX, hardfloat [`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7M with NuttX -`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3 +`thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.5 [`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Baseline with NuttX [`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX [`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat @@ -423,7 +423,7 @@ target | std | host | notes [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | [`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS | -[`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3 +[`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.5 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku [`x86_64-unknown-hermit`](platform-support/hermit.md) | ✓ | | x86_64 Hermit From a014a9b0ed396f1ff5b9937a8d80675f3136e0d7 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Wed, 18 Jun 2025 11:19:46 -0400 Subject: [PATCH 02/45] update all other references to musl 1.2.3 to 1.2.5 --- .../rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs | 2 +- .../rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs | 2 +- .../src/spec/targets/arm_unknown_linux_musleabihf.rs | 2 +- .../src/spec/targets/armv5te_unknown_linux_musleabi.rs | 2 +- .../src/spec/targets/armv7_unknown_linux_musleabi.rs | 2 +- .../src/spec/targets/armv7_unknown_linux_musleabihf.rs | 2 +- .../rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs | 2 +- .../rustc_target/src/spec/targets/i686_unknown_linux_musl.rs | 2 +- .../rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs | 2 +- .../src/spec/targets/mips64_unknown_linux_muslabi64.rs | 2 +- .../src/spec/targets/mips64el_unknown_linux_muslabi64.rs | 2 +- .../rustc_target/src/spec/targets/mips_unknown_linux_musl.rs | 2 +- .../rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs | 2 +- .../src/spec/targets/powerpc64_unknown_linux_musl.rs | 2 +- .../src/spec/targets/powerpc64le_unknown_linux_musl.rs | 2 +- .../rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs | 2 +- .../src/spec/targets/riscv32gc_unknown_linux_musl.rs | 2 +- .../src/spec/targets/riscv64gc_unknown_linux_musl.rs | 2 +- .../rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs | 2 +- .../src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs | 2 +- .../rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs | 2 +- .../rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs | 2 +- src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs index 478726fbef699..158b38e514016 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "aarch64-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("ARM64 Linux with musl 1.2.3".into()), + description: Some("ARM64 Linux with musl 1.2.5".into()), tier: Some(2), host_tools: Some(true), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs index 3919a5e0771b7..d05f4c79b01fe 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabi.rs @@ -4,7 +4,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "arm-unknown-linux-musleabi".into(), metadata: TargetMetadata { - description: Some("Armv6 Linux with musl 1.2.3".into()), + description: Some("Armv6 Linux with musl 1.2.5".into()), tier: Some(2), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs index ca52e5b3ca6c7..9ce752efd6aa2 100644 --- a/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/arm_unknown_linux_musleabihf.rs @@ -4,7 +4,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "arm-unknown-linux-musleabihf".into(), metadata: TargetMetadata { - description: Some("Armv6 Linux with musl 1.2.3, hardfloat".into()), + description: Some("Armv6 Linux with musl 1.2.5, hardfloat".into()), tier: Some(2), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs index e675739629b59..0240450b61d30 100644 --- a/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv5te_unknown_linux_musleabi.rs @@ -4,7 +4,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "armv5te-unknown-linux-musleabi".into(), metadata: TargetMetadata { - description: Some("Armv5TE Linux with musl 1.2.3".into()), + description: Some("Armv5TE Linux with musl 1.2.5".into()), tier: Some(2), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs index 42fbf6f486197..dd8a97bf77f65 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabi.rs @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "armv7-unknown-linux-musleabi".into(), metadata: TargetMetadata { - description: Some("Armv7-A Linux with musl 1.2.3".into()), + description: Some("Armv7-A Linux with musl 1.2.5".into()), tier: Some(2), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs index a3ac0223c84bf..c3b7ac5f994c2 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_unknown_linux_musleabihf.rs @@ -6,7 +6,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "armv7-unknown-linux-musleabihf".into(), metadata: TargetMetadata { - description: Some("Armv7-A Linux with musl 1.2.3, hardfloat".into()), + description: Some("Armv7-A Linux with musl 1.2.5, hardfloat".into()), tier: Some(2), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs index 1abf0537cda77..74a7eab1e0c48 100644 --- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "hexagon-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("Hexagon Linux with musl 1.2.3".into()), + description: Some("Hexagon Linux with musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs index 47a7eb3d597b4..b6b85f5236d80 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs @@ -31,7 +31,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "i686-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("32-bit Linux with musl 1.2.3".into()), + description: Some("32-bit Linux with musl 1.2.5".into()), tier: Some(2), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs index 508abc0101841..eb1148d5e8fa1 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_openwrt_linux_musl.rs @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { // LLVM doesn't recognize "muslabi64" yet. llvm_target: "mips64-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("MIPS64 for OpenWrt Linux musl 1.2.3".into()), + description: Some("MIPS64 for OpenWrt Linux musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs index 94ecd3590a93a..e54628acb1ad2 100644 --- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { // LLVM doesn't recognize "muslabi64" yet. llvm_target: "mips64-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("MIPS64 Linux, N64 ABI, musl 1.2.3".into()), + description: Some("MIPS64 Linux, N64 ABI, musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs index 38c3c7dfaa1bb..a256733734f7f 100644 --- a/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/targets/mips64el_unknown_linux_muslabi64.rs @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target { // LLVM doesn't recognize "muslabi64" yet. llvm_target: "mips64el-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("MIPS64 Linux, N64 ABI, musl 1.2.3".into()), + description: Some("MIPS64 Linux, N64 ABI, musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs index 82f2fda7fff0a..2d258d7e438ff 100644 --- a/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mips_unknown_linux_musl.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "mips-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("MIPS Linux with musl 1.2.3".into()), + description: Some("MIPS Linux with musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs index d008bb55189be..f4fb6be332166 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_unknown_linux_musl.rs @@ -8,7 +8,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "mipsel-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("MIPS (little endian) Linux with musl 1.2.3".into()), + description: Some("MIPS (little endian) Linux with musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs index 482b6790dadcd..8fb991d0bd1a7 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "powerpc64-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("64-bit PowerPC Linux with musl 1.2.3".into()), + description: Some("64-bit PowerPC Linux with musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs index 26ee6a68c6a8b..0f8b78fa7307d 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "powerpc64le-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("64-bit PowerPC Linux with musl 1.2.3, Little Endian".into()), + description: Some("64-bit PowerPC Linux with musl 1.2.5, Little Endian".into()), tier: Some(2), host_tools: Some(true), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs index f39142d01018b..f5c7cb061988a 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "powerpc-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("PowerPC Linux with musl 1.2.3".into()), + description: Some("PowerPC Linux with musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs index eb592cca1c81d..7183f0a866280 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs @@ -7,7 +7,7 @@ pub(crate) fn target() -> Target { llvm_target: "riscv32-unknown-linux-musl".into(), metadata: TargetMetadata { description: Some( - "RISC-V Linux (kernel 5.4, musl 1.2.3 + RISCV32 support patches".into(), + "RISC-V Linux (kernel 5.4, musl 1.2.5 + RISCV32 support patches".into(), ), tier: Some(3), host_tools: Some(false), diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs index 70c19952af063..83fd4e2cfa9ee 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs @@ -6,7 +6,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "riscv64-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("RISC-V Linux (kernel 4.20, musl 1.2.3)".into()), + description: Some("RISC-V Linux (kernel 4.20, musl 1.2.5)".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs index 0cdbb626739d0..509105afedcd2 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "s390x-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("S390x Linux (kernel 3.2, musl 1.2.3)".into()), + description: Some("S390x Linux (kernel 3.2, musl 1.2.5)".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs index e026595439f48..d58339bc38c29 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "armv7-unknown-linux-musleabihf".into(), metadata: TargetMetadata { - description: Some("Thumb2-mode ARMv7-A Linux with NEON, musl 1.2.3".into()), + description: Some("Thumb2-mode ARMv7-A Linux with NEON, musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs index a5723341fe64c..f5bc3ab707db6 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unikraft_linux_musl.rs @@ -6,7 +6,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "x86_64-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("64-bit Unikraft with musl 1.2.3".into()), + description: Some("64-bit Unikraft with musl 1.2.5".into()), tier: Some(3), host_tools: Some(false), std: Some(true), diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs index cc5f88862400e..3cb2a962a5624 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "x86_64-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some("64-bit Linux with musl 1.2.3".into()), + description: Some("64-bit Linux with musl 1.2.5".into()), tier: Some(2), host_tools: Some(true), std: Some(true), diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md index c604b487c2c26..b8bee11055fe5 100644 --- a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md @@ -13,7 +13,7 @@ IBM z/Architecture (s390x) targets (including IBM Z and LinuxONE) running Linux. This target requires: * Linux Kernel version 3.2 or later -* musl 1.2.3 or later +* musl 1.2.5 or later Code generated by the target uses the z/Architecture ISA assuming a minimum architecture level of z10 (Eighth Edition of the z/Architecture Principles From 52513ab435721229c779e64bc6f0f7e6d7814d6a Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Wed, 1 Oct 2025 21:42:18 -0400 Subject: [PATCH 03/45] bump powerpc64le-unknown-linux-musl's musl to 1.2.5 --- .../powerpc64le-unknown-linux-musl.defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig index c6cde30b2a4e5..d8fa8ec4d5e82 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig @@ -11,6 +11,5 @@ CT_ARCH_ARCH="powerpc64le" CT_KERNEL_LINUX=y CT_LINUX_V_4_19=y CT_LIBC_MUSL=y -CT_MUSL_V_1_2_3=y CT_CC_LANG_CXX=y CT_GETTEXT_NEEDED=y From 303a82853355956baa82ac2d1cb77e90b0aaf449 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Mon, 6 Oct 2025 21:21:07 -0400 Subject: [PATCH 04/45] pin all musl deconfigs to 1.2.5 --- .../host-x86_64/dist-arm-linux-musl/arm-linux-musl.defconfig | 1 + .../dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig | 1 + .../powerpc64le-unknown-linux-musl.defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/src/ci/docker/host-x86_64/dist-arm-linux-musl/arm-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-arm-linux-musl/arm-linux-musl.defconfig index e7afdbe9d4dea..014930052b4ac 100644 --- a/src/ci/docker/host-x86_64/dist-arm-linux-musl/arm-linux-musl.defconfig +++ b/src/ci/docker/host-x86_64/dist-arm-linux-musl/arm-linux-musl.defconfig @@ -11,3 +11,4 @@ CT_BINUTILS_V_2_32=y CT_GLIBC_V_2_17=y CT_GCC_V_8=y CT_CC_LANG_CXX=y +CT_MUSL_V_1_2_5=y diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig index 01fe493a9fecd..f5f3cfd4b49f3 100644 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.defconfig @@ -12,3 +12,4 @@ CT_BINUTILS_EXTRA_CONFIG_ARRAY="--enable-compressed-debug-sections=none" CT_GLIBC_V_2_17=y CT_GCC_V_8=y CT_CC_LANG_CXX=y +CT_MUSL_V_1_2_5=y diff --git a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig index d8fa8ec4d5e82..db2b5533947cd 100644 --- a/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig +++ b/src/ci/docker/host-x86_64/dist-powerpc64le-linux-musl/powerpc64le-unknown-linux-musl.defconfig @@ -11,5 +11,6 @@ CT_ARCH_ARCH="powerpc64le" CT_KERNEL_LINUX=y CT_LINUX_V_4_19=y CT_LIBC_MUSL=y +CT_MUSL_V_1_2_5=y CT_CC_LANG_CXX=y CT_GETTEXT_NEEDED=y From 22e6656c2108c9af819221e325a797a10ed0d806 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Mon, 6 Oct 2025 21:21:37 -0400 Subject: [PATCH 05/45] remove references to upstreamed patches --- .../src/spec/targets/riscv32gc_unknown_linux_musl.rs | 2 +- src/doc/rustc/src/platform-support.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs index 7183f0a866280..bd18d80a107b7 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs @@ -7,7 +7,7 @@ pub(crate) fn target() -> Target { llvm_target: "riscv32-unknown-linux-musl".into(), metadata: TargetMetadata { description: Some( - "RISC-V Linux (kernel 5.4, musl 1.2.5 + RISCV32 support patches".into(), + "RISC-V Linux (kernel 5.4, musl 1.2.5)".into(), ), tier: Some(3), host_tools: Some(false), diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e56e933da5567..b2e9cf7c868ea 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -374,7 +374,7 @@ target | std | host | notes [`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) [`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) `riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) -`riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.5 + RISCV32 support patches) +`riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.5) [`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA) [`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA) [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF From b64cdd0f59f4bbc98dc5e3c1a64c09ca4d999906 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Mon, 6 Oct 2025 21:24:49 -0400 Subject: [PATCH 06/45] bump musl-cross-make commit to get fixes --- src/ci/docker/scripts/musl-toolchain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh index c52c5ea7953c8..511521a2b49da 100644 --- a/src/ci/docker/scripts/musl-toolchain.sh +++ b/src/ci/docker/scripts/musl-toolchain.sh @@ -46,7 +46,7 @@ export CFLAGS="-fPIC -g1 $CFLAGS" git clone https://github.com/richfelker/musl-cross-make # -b v0.9.9 cd musl-cross-make # A version that includes support for building musl 1.2.5 -git checkout e149c31c48b4f4a4c9349ddf7bc0027b90245afc +git checkout 3635262e4524c991552789af6f36211a335a77b3 hide_output make -j$(nproc) TARGET=$TARGET MUSL_VER=1.2.5 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER hide_output make install TARGET=$TARGET MUSL_VER=1.2.5 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER OUTPUT=$OUTPUT From 010b69011761443d1450b6b37d551afe2262b477 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Mon, 6 Oct 2025 21:59:04 -0400 Subject: [PATCH 07/45] fmt --- .../src/spec/targets/riscv32gc_unknown_linux_musl.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs index bd18d80a107b7..a13bb173e2483 100644 --- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs @@ -6,9 +6,7 @@ pub(crate) fn target() -> Target { Target { llvm_target: "riscv32-unknown-linux-musl".into(), metadata: TargetMetadata { - description: Some( - "RISC-V Linux (kernel 5.4, musl 1.2.5)".into(), - ), + description: Some("RISC-V Linux (kernel 5.4, musl 1.2.5)".into()), tier: Some(3), host_tools: Some(false), std: Some(true), From 60a7cab12ecae8324652093c3b09b930850efbb6 Mon Sep 17 00:00:00 2001 From: Jesse Schalken Date: Thu, 23 Oct 2025 00:03:48 +1100 Subject: [PATCH 08/45] Use fstatat() in DirEntry::metadata on Apple platforms --- library/std/src/sys/fs/unix.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index d9a7fcb0e2d39..aa06955b16e0c 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -14,9 +14,10 @@ use libc::c_char; target_os = "fuchsia", target_os = "hurd", target_os = "illumos", + target_vendor = "apple", ))] use libc::dirfd; -#[cfg(any(target_os = "fuchsia", target_os = "illumos"))] +#[cfg(any(target_os = "fuchsia", target_os = "illumos", target_vendor = "apple")] use libc::fstatat as fstatat64; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::fstatat64; @@ -907,6 +908,7 @@ impl DirEntry { target_os = "fuchsia", target_os = "hurd", target_os = "illumos", + target_vendor = "apple", ), not(miri) // no dirfd on Miri ))] @@ -937,6 +939,7 @@ impl DirEntry { target_os = "fuchsia", target_os = "hurd", target_os = "illumos", + target_vendor = "apple", )), miri ))] From fe4c2a202d585c950c4d5812a0202fd8dd5f1df7 Mon Sep 17 00:00:00 2001 From: Jesse Schalken Date: Thu, 23 Oct 2025 00:37:40 +1100 Subject: [PATCH 09/45] typo --- library/std/src/sys/fs/unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index aa06955b16e0c..32dc1a5e89766 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -17,7 +17,7 @@ use libc::c_char; target_vendor = "apple", ))] use libc::dirfd; -#[cfg(any(target_os = "fuchsia", target_os = "illumos", target_vendor = "apple")] +#[cfg(any(target_os = "fuchsia", target_os = "illumos", target_vendor = "apple"))] use libc::fstatat as fstatat64; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::fstatat64; From 63bb238e5da42890f88402e724ad480552d7ef43 Mon Sep 17 00:00:00 2001 From: Antoni Spaanderman <56turtle56@gmail.com> Date: Thu, 23 Oct 2025 13:52:55 +0200 Subject: [PATCH 10/45] implement VecDeque extend_from_within and prepend_from_within, add tests --- .../alloc/src/collections/vec_deque/mod.rs | 288 ++++++++++++++++++ library/alloctests/tests/lib.rs | 1 + library/alloctests/tests/vec_deque.rs | 232 ++++++++++++++ 3 files changed, 521 insertions(+) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index ac619a42d356d..2ef7f047e034b 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -227,6 +227,78 @@ impl VecDeque { wrap_index(idx.wrapping_sub(subtrahend).wrapping_add(self.capacity()), self.capacity()) } + /// Get source, destination and count (like the arguments to [`ptr::copy_nonoverlapping`]) + /// for copying `count` values from index `src` to index `dst`. + /// One of the ranges can wrap around the physical buffer, for this reason 2 triples are returned. + /// + /// Use of the word "ranges" specifically refers to `src..src + count` and `dst..dst + count`. + /// + /// # Safety + /// + /// - Ranges must not overlap: `src.abs_diff(dst) >= count`. + /// - Ranges must be in bounds of the logical buffer: `src + count <= self.capacity()` and `dst + count <= self.capacity()`. + /// - `head` must be in bounds: `head < self.capacity()`. + #[cfg(not(no_global_oom_handling))] + unsafe fn nonoverlapping_ranges( + &mut self, + src: usize, + dst: usize, + count: usize, + head: usize, + ) -> [(*const T, *mut T, usize); 2] { + // "`src` and `dst` must be at least as far apart as `count`" + debug_assert!( + src.abs_diff(dst) >= count, + "`src` and `dst` must not overlap. src={src} dst={dst} count={count}", + ); + debug_assert!( + src.max(dst) + count <= self.capacity(), + "ranges must be in bounds. src={src} dst={dst} count={count} cap={}", + self.capacity(), + ); + + let wrapped_src = self.wrap_add(head, src); + let wrapped_dst = self.wrap_add(head, dst); + + let room_after_src = self.capacity() - wrapped_src; + let room_after_dst = self.capacity() - wrapped_dst; + + let src_wraps = room_after_src < count; + let dst_wraps = room_after_dst < count; + + // Wrapping occurs if `capacity` is contained within `wrapped_src..wrapped_src + count` or `wrapped_dst..wrapped_dst + count`. + // Since these two ranges must not overlap as per the safety invariants of this function, only one range can wrap. + debug_assert!( + !(src_wraps && dst_wraps), + "BUG: at most one of src and dst can wrap. src={src} dst={dst} count={count} cap={}", + self.capacity(), + ); + + unsafe { + let ptr = self.ptr(); + let src_ptr = ptr.add(wrapped_src); + let dst_ptr = ptr.add(wrapped_dst); + + if src_wraps { + [ + (src_ptr, dst_ptr, room_after_src), + (ptr, dst_ptr.add(room_after_src), count - room_after_src), + ] + } else if dst_wraps { + [ + (src_ptr, dst_ptr, room_after_dst), + (src_ptr.add(room_after_dst), ptr, count - room_after_dst), + ] + } else { + [ + (src_ptr, dst_ptr, count), + // null pointers are fine as long as the count is 0 + (ptr::null(), ptr::null_mut(), 0), + ] + } + } + } + /// Copies a contiguous block of memory len long from src to dst #[inline] unsafe fn copy(&mut self, src: usize, dst: usize, len: usize) { @@ -2971,6 +3043,222 @@ impl VecDeque { self.truncate(new_len); } } + + /// Clones the elements at the range `src` and appends them to the end. + /// + /// # Panics + /// + /// Panics if the starting index is greater than the end index + /// or if either index is greater than the length of the vector. + /// + /// # Examples + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut characters = VecDeque::from(['a', 'b', 'c', 'd', 'e']); + /// characters.extend_from_within(2..); + /// assert_eq!(characters, ['a', 'b', 'c', 'd', 'e', 'c', 'd', 'e']); + /// + /// let mut numbers = VecDeque::from([0, 1, 2, 3, 4]); + /// numbers.extend_from_within(..2); + /// assert_eq!(numbers, [0, 1, 2, 3, 4, 0, 1]); + /// + /// let mut strings = VecDeque::from([String::from("hello"), String::from("world"), String::from("!")]); + /// strings.extend_from_within(1..=2); + /// assert_eq!(strings, ["hello", "world", "!", "world", "!"]); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "deque_extend_front", issue = "146975")] + pub fn extend_from_within(&mut self, src: R) + where + R: RangeBounds, + { + let range = slice::range(src, ..self.len()); + self.reserve(range.len()); + + // SAFETY: + // - `slice::range` guarantees that the given range is valid for indexing self + // - at least `range.len()` additional space is available + unsafe { + self.spec_extend_from_within(range); + } + } + + /// Clones the elements at the range `src` and prepends them to the front. + /// + /// # Panics + /// + /// Panics if the starting index is greater than the end index + /// or if either index is greater than the length of the vector. + /// + /// # Examples + /// + /// ``` + /// #![feature(deque_extend_front)] + /// use std::collections::VecDeque; + /// + /// let mut characters = VecDeque::from(['a', 'b', 'c', 'd', 'e']); + /// characters.prepend_from_within(2..); + /// assert_eq!(characters, ['c', 'd', 'e', 'a', 'b', 'c', 'd', 'e']); + /// + /// let mut numbers = VecDeque::from([0, 1, 2, 3, 4]); + /// numbers.prepend_from_within(..2); + /// assert_eq!(numbers, [0, 1, 0, 1, 2, 3, 4]); + /// + /// let mut strings = VecDeque::from([String::from("hello"), String::from("world"), String::from("!")]); + /// strings.prepend_from_within(1..=2); + /// assert_eq!(strings, ["world", "!", "hello", "world", "!"]); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "deque_extend_front", issue = "146975")] + pub fn prepend_from_within(&mut self, src: R) + where + R: RangeBounds, + { + let range = slice::range(src, ..self.len()); + self.reserve(range.len()); + + // SAFETY: + // - `slice::range` guarantees that the given range is valid for indexing self + // - at least `range.len()` additional space is available + unsafe { + self.spec_prepend_from_within(range); + } + } +} + +/// Associated functions have the following preconditions: +/// +/// - `src` needs to be a valid range: `src.start <= src.end <= self.len()`. +/// - The buffer must have enough spare capacity: `self.capacity() - self.len() >= src.len()`. +#[cfg(not(no_global_oom_handling))] +trait SpecExtendFromWithin { + unsafe fn spec_extend_from_within(&mut self, src: Range); + + unsafe fn spec_prepend_from_within(&mut self, src: Range); +} + +#[cfg(not(no_global_oom_handling))] +impl SpecExtendFromWithin for VecDeque { + default unsafe fn spec_extend_from_within(&mut self, src: Range) { + let dst = self.len(); + let count = src.end - src.start; + let src = src.start; + + unsafe { + // SAFETY: + // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. + // - Ranges are in bounds: guaranteed by the caller. + let ranges = self.nonoverlapping_ranges(src, dst, count, self.head); + + // `len` is updated after every clone to prevent leaking and + // leave the deque in the right state when a clone implementation panics + + for (src, dst, count) in ranges { + for offset in 0..count { + dst.add(offset).write((*src.add(offset)).clone()); + self.len += 1; + } + } + } + } + + default unsafe fn spec_prepend_from_within(&mut self, src: Range) { + let dst = 0; + let count = src.end - src.start; + let src = src.start + count; + + let new_head = self.wrap_sub(self.head, count); + let cap = self.capacity(); + + unsafe { + // SAFETY: + // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. + // - Ranges are in bounds: guaranteed by the caller. + let ranges = self.nonoverlapping_ranges(src, dst, count, new_head); + + // Cloning is done in reverse because we prepend to the front of the deque, + // we can't get holes in the *logical* buffer. + // `head` and `len` are updated after every clone to prevent leaking and + // leave the deque in the right state when a clone implementation panics + + // Clone the first range + let (src, dst, count) = ranges[1]; + for offset in (0..count).rev() { + dst.add(offset).write((*src.add(offset)).clone()); + self.head -= 1; + self.len += 1; + } + + // Clone the second range + let (src, dst, count) = ranges[0]; + let mut iter = (0..count).rev(); + if let Some(offset) = iter.next() { + dst.add(offset).write((*src.add(offset)).clone()); + // After the first clone of the second range, wrap `head` around + if self.head == 0 { + self.head = cap; + } + self.head -= 1; + self.len += 1; + + // Continue like normal + for offset in iter { + dst.add(offset).write((*src.add(offset)).clone()); + self.head -= 1; + self.len += 1; + } + } + } + } +} + +#[cfg(not(no_global_oom_handling))] +impl SpecExtendFromWithin for VecDeque { + unsafe fn spec_extend_from_within(&mut self, src: Range) { + let dst = self.len(); + let count = src.end - src.start; + let src = src.start; + + unsafe { + // SAFETY: + // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. + // - Ranges are in bounds: guaranteed by the caller. + let ranges = self.nonoverlapping_ranges(src, dst, count, self.head); + for (src, dst, count) in ranges { + ptr::copy_nonoverlapping(src, dst, count); + } + } + + // SAFETY: + // - The elements were just initialized by `copy_nonoverlapping` + self.len += count; + } + + unsafe fn spec_prepend_from_within(&mut self, src: Range) { + let dst = 0; + let count = src.end - src.start; + let src = src.start + count; + + let new_head = self.wrap_sub(self.head, count); + + unsafe { + // SAFETY: + // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. + // - Ranges are in bounds: guaranteed by the caller. + let ranges = self.nonoverlapping_ranges(src, dst, count, new_head); + for (src, dst, count) in ranges { + ptr::copy_nonoverlapping(src, dst, count); + } + } + + // SAFETY: + // - The elements were just initialized by `copy_nonoverlapping` + self.head = new_head; + self.len += count; + } } /// Returns the index in the underlying buffer for a given logical element index. diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index f94f92397bb18..c2649be0558a1 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -6,6 +6,7 @@ #![feature(char_max_len)] #![feature(cow_is_borrowed)] #![feature(core_intrinsics)] +#![feature(deque_extend_front)] #![feature(downcast_unchecked)] #![feature(exact_size_is_empty)] #![feature(hashmap_internals)] diff --git a/library/alloctests/tests/vec_deque.rs b/library/alloctests/tests/vec_deque.rs index a82906d55e5d0..0a4a0e0cac4d7 100644 --- a/library/alloctests/tests/vec_deque.rs +++ b/library/alloctests/tests/vec_deque.rs @@ -1,3 +1,4 @@ +use core::cell::Cell; use core::num::NonZero; use std::assert_matches::assert_matches; use std::collections::TryReserveErrorKind::*; @@ -1849,3 +1850,234 @@ fn test_truncate_front() { v.truncate_front(5); assert_eq!(v.as_slices(), ([2, 3, 4, 5, 6].as_slice(), [].as_slice())); } + +#[test] +fn test_extend_from_within() { + let mut v = VecDeque::with_capacity(8); + v.extend(0..6); + v.truncate_front(4); + assert_eq!(v, [2, 3, 4, 5]); + v.extend_from_within(1..4); + assert_eq!(v, [2, 3, 4, 5, 3, 4, 5]); + // check it really wrapped + assert_eq!(v.as_slices(), ([2, 3, 4, 5, 3, 4].as_slice(), [5].as_slice())); + v.extend_from_within(1..=2); + assert_eq!(v, [2, 3, 4, 5, 3, 4, 5, 3, 4]); + v.extend_from_within(..3); + assert_eq!(v, [2, 3, 4, 5, 3, 4, 5, 3, 4, 2, 3, 4]); +} + +/// Struct that allows tracking clone and drop calls and can be set to panic on calling clone. +struct CloneTracker<'a> { + id: usize, + // Counters can be set to None if not needed. + clone: Option<&'a Cell>, + drop: Option<&'a Cell>, + panic: bool, +} + +impl<'a> CloneTracker<'a> { + pub const DUMMY: Self = Self { id: 999, clone: None, drop: None, panic: false }; +} + +impl<'a> Clone for CloneTracker<'a> { + fn clone(&self) -> Self { + if self.panic { + panic!(); + } + + if let Some(clone_count) = self.clone { + clone_count.update(|c| c + 1); + } + + Self { id: self.id, clone: self.clone, drop: self.drop, panic: false } + } +} + +impl<'a> Drop for CloneTracker<'a> { + fn drop(&mut self) { + if let Some(drop_count) = self.drop { + drop_count.update(|c| c + 1); + } + } +} + +#[test] +fn test_extend_from_within_clone() { + let clone_counts = [const { Cell::new(0) }; 4]; + let mut v = VecDeque::with_capacity(10); + // insert 2 dummy elements to have the buffer wrap later + v.extend([CloneTracker::DUMMY; 2]); + v.extend(clone_counts.iter().enumerate().map(|(id, clone_count)| CloneTracker { + id, + clone: Some(clone_count), + drop: None, + panic: false, + })); + // remove the dummy elements + v.truncate_front(4); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 2, 3]); + + v.extend_from_within(2..); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 2, 3, 2, 3]); + // elements at index 2 and 3 should have been cloned once + assert_eq!(clone_counts.each_ref().map(Cell::get), [0, 0, 1, 1]); + // it is important that the deque wraps because of this operation, we want to test if wrapping is handled correctly + v.extend_from_within(1..5); + // total length is 10, 8 in the first part and 2 in the second part + assert_eq!(v.as_slices().0.len(), 8); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 2, 3, 2, 3, 1, 2, 3, 2]); + // the new elements are from indices 1, 2, 3 and 2, those elements should have their clone count + // incremented (clone count at index 2 gets incremented twice so ends up at 3) + assert_eq!(clone_counts.each_ref().map(Cell::get), [0, 1, 3, 2]); +} + +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn test_extend_from_within_clone_panic() { + let clone_counts = [const { Cell::new(0) }; 4]; + let drop_count = Cell::new(0); + let mut v = VecDeque::with_capacity(8); + // insert 2 dummy elements to have the buffer wrap later + v.extend([CloneTracker::DUMMY; 2]); + v.extend(clone_counts.iter().enumerate().map(|(id, clone_count)| CloneTracker { + id, + clone: Some(clone_count), + drop: Some(&drop_count), + panic: false, + })); + // remove the dummy elements + v.truncate_front(4); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 2, 3]); + + // panic after wrapping + v[2].panic = true; + catch_unwind(AssertUnwindSafe(|| { + v.extend_from_within(..); + })) + .unwrap_err(); + v[2].panic = false; + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 2, 3, 0, 1]); + // the first 2 elements were cloned + assert_eq!(clone_counts.each_ref().map(Cell::get), [1, 1, 0, 0]); + // nothing should have been dropped + assert_eq!(drop_count.get(), 0); + + v.truncate_front(2); + assert_eq!(drop_count.get(), 4); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1]); + + // panic before wrapping + v[1].panic = true; + catch_unwind(AssertUnwindSafe(|| { + v.extend_from_within(..); + })) + .unwrap_err(); + v[1].panic = false; + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 0]); + // only the first element was cloned + assert_eq!(clone_counts.each_ref().map(Cell::get), [2, 1, 0, 0]); + // nothing more should have been dropped + assert_eq!(drop_count.get(), 4); +} + +#[test] +fn test_prepend_from_within() { + let mut v = VecDeque::with_capacity(8); + v.extend(0..6); + v.truncate_front(4); + v.prepend_from_within(..=0); + assert_eq!(v.as_slices(), ([2, 2, 3, 4, 5].as_slice(), [].as_slice())); + v.prepend_from_within(2..); + assert_eq!(v.as_slices(), ([3, 4].as_slice(), [5, 2, 2, 3, 4, 5].as_slice())); + v.prepend_from_within(..); + assert_eq!(v, [[3, 4, 5, 2, 2, 3, 4, 5]; 2].as_flattened()); +} + +#[test] +fn test_prepend_from_within_clone() { + let clone_counts = [const { Cell::new(0) }; 4]; + // insert 2 dummy elements to have the buffer wrap later + let mut v = VecDeque::with_capacity(10); + v.extend([CloneTracker::DUMMY; 2]); + v.extend(clone_counts.iter().enumerate().map(|(id, clone_count)| CloneTracker { + id, + clone: Some(clone_count), + drop: None, + panic: false, + })); + // remove the dummy elements + v.truncate_front(4); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 2, 3]); + + v.prepend_from_within(..2); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 0, 1, 2, 3]); + v.prepend_from_within(1..5); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [1, 0, 1, 2, 0, 1, 0, 1, 2, 3]); + // count the number of each element and subtract one (clone should have been called n-1 times if we have n elements) + // example: 0 appears 3 times so should have been cloned twice, 1 appears 4 times so cloned 3 times, etc + assert_eq!(clone_counts.each_ref().map(Cell::get), [2, 3, 1, 0]); +} + +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn test_prepend_from_within_clone_panic() { + let clone_counts = [const { Cell::new(0) }; 4]; + let drop_count = Cell::new(0); + let mut v = VecDeque::with_capacity(8); + // insert 2 dummy elements to have the buffer wrap later + v.extend([CloneTracker::DUMMY; 2]); + v.extend(clone_counts.iter().enumerate().map(|(id, clone_count)| CloneTracker { + id, + clone: Some(clone_count), + drop: Some(&drop_count), + panic: false, + })); + // remove the dummy elements + v.truncate_front(4); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [0, 1, 2, 3]); + + // panic after wrapping + v[1].panic = true; + catch_unwind(AssertUnwindSafe(|| { + v.prepend_from_within(..); + })) + .unwrap_err(); + v[1].panic = false; + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [2, 3, 0, 1, 2, 3]); + // the last 2 elements were cloned + assert_eq!(clone_counts.each_ref().map(Cell::get), [0, 0, 1, 1]); + // nothing should have been dropped + assert_eq!(drop_count.get(), 0); + + v.truncate_front(2); + assert_eq!(drop_count.get(), 4); + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [2, 3]); + + // panic before wrapping + v[0].panic = true; + catch_unwind(AssertUnwindSafe(|| { + v.prepend_from_within(..); + })) + .unwrap_err(); + v[0].panic = false; + assert_eq!(v.iter().map(|tr| tr.id).collect::>(), [3, 2, 3]); + // only the first element was cloned + assert_eq!(clone_counts.each_ref().map(Cell::get), [0, 0, 1, 2]); + // nothing more should have been dropped + assert_eq!(drop_count.get(), 4); +} + +#[test] +fn test_extend_and_prepend_from_within() { + let mut v = ('0'..='9').map(String::from).collect::>(); + v.truncate_front(5); + v.extend_from_within(4..); + v.prepend_from_within(..2); + assert_eq!(v.iter().map(|s| &**s).collect::(), "56567899"); + v.clear(); + v.extend(['1', '2', '3'].map(String::from)); + v.prepend_from_within(..); + v.extend_from_within(..); + assert_eq!(v.iter().map(|s| &**s).collect::(), "123123123123"); +} From 73b734bf637ab1c14ec73823b3c536108cef5437 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 23 Oct 2025 18:20:41 +1100 Subject: [PATCH 11/45] Pass `debuginfo_compression` through FFI as an enum --- .../src/back/owned_target_machine.rs | 4 +- compiler/rustc_codegen_llvm/src/back/write.rs | 25 +++++------ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 16 +++++-- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 42 ++++++++++++++----- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 4 +- compiler/rustc_session/src/config.rs | 11 ----- 6 files changed, 60 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index 2972f3d5201ed..f88932d43d2af 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -36,7 +36,7 @@ impl OwnedTargetMachine { use_init_array: bool, split_dwarf_file: &CStr, output_obj_file: &CStr, - debug_info_compression: &CStr, + debug_info_compression: llvm::CompressionKind, use_emulated_tls: bool, use_wasm_eh: bool, ) -> Result> { @@ -62,7 +62,7 @@ impl OwnedTargetMachine { use_init_array, split_dwarf_file.as_ptr(), output_obj_file.as_ptr(), - debug_info_compression.as_ptr(), + debug_info_compression, use_emulated_tls, use_wasm_eh, ) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index d18030b1574c5..cfbb9541ecd2d 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -6,9 +6,6 @@ use std::sync::Arc; use std::{fs, slice, str}; use libc::{c_char, c_int, c_void, size_t}; -use llvm::{ - LLVMRustLLVMHasZlibCompressionForDebugSymbols, LLVMRustLLVMHasZstdCompressionForDebugSymbols, -}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::back::write::{ @@ -252,21 +249,25 @@ pub(crate) fn target_machine_factory( let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated); - let debuginfo_compression = sess.opts.debuginfo_compression.to_string(); - match sess.opts.debuginfo_compression { - rustc_session::config::DebugInfoCompression::Zlib => { - if !unsafe { LLVMRustLLVMHasZlibCompressionForDebugSymbols() } { + let debuginfo_compression = match sess.opts.debuginfo_compression { + config::DebugInfoCompression::None => llvm::CompressionKind::None, + config::DebugInfoCompression::Zlib => { + if llvm::LLVMRustLLVMHasZlibCompression() { + llvm::CompressionKind::Zlib + } else { sess.dcx().emit_warn(UnknownCompression { algorithm: "zlib" }); + llvm::CompressionKind::None } } - rustc_session::config::DebugInfoCompression::Zstd => { - if !unsafe { LLVMRustLLVMHasZstdCompressionForDebugSymbols() } { + config::DebugInfoCompression::Zstd => { + if llvm::LLVMRustLLVMHasZstdCompression() { + llvm::CompressionKind::Zstd + } else { sess.dcx().emit_warn(UnknownCompression { algorithm: "zstd" }); + llvm::CompressionKind::None } } - rustc_session::config::DebugInfoCompression::None => {} }; - let debuginfo_compression = SmallCStr::new(&debuginfo_compression); let file_name_display_preference = sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO); @@ -310,7 +311,7 @@ pub(crate) fn target_machine_factory( use_init_array, &split_dwarf_file, &output_obj_file, - &debuginfo_compression, + debuginfo_compression, use_emulated_tls, use_wasm_eh, ) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 2456ed2e46d67..5a00199d61171 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -677,6 +677,15 @@ pub(crate) enum Opcode { CatchSwitch = 65, } +/// Must match the layout of `LLVMRustCompressionKind`. +#[derive(Copy, Clone)] +#[repr(C)] +pub(crate) enum CompressionKind { + None = 0, + Zlib = 1, + Zstd = 2, +} + unsafe extern "C" { type Opaque; } @@ -2328,7 +2337,7 @@ unsafe extern "C" { UseInitArray: bool, SplitDwarfFile: *const c_char, OutputObjFile: *const c_char, - DebugInfoCompression: *const c_char, + DebugInfoCompression: CompressionKind, UseEmulatedTls: bool, UseWasmEH: bool, ) -> *mut TargetMachine; @@ -2516,9 +2525,8 @@ unsafe extern "C" { pub(crate) fn LLVMRustGetElementTypeArgIndex(CallSite: &Value) -> i32; - pub(crate) fn LLVMRustLLVMHasZlibCompressionForDebugSymbols() -> bool; - - pub(crate) fn LLVMRustLLVMHasZstdCompressionForDebugSymbols() -> bool; + pub(crate) safe fn LLVMRustLLVMHasZlibCompression() -> bool; + pub(crate) safe fn LLVMRustLLVMHasZstdCompression() -> bool; pub(crate) fn LLVMRustGetSymbols( buf_ptr: *const u8, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 616c8a17dd66d..178b43c93ef6b 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -224,6 +224,31 @@ static FloatABI::ABIType fromRust(LLVMRustFloatABI RustFloatAbi) { report_fatal_error("Bad FloatABI."); } +// Must match the layout of `rustc_codegen_llvm::llvm::ffi::CompressionKind`. +enum class LLVMRustCompressionKind { + None = 0, + Zlib = 1, + Zstd = 2, +}; + +static llvm::DebugCompressionType fromRust(LLVMRustCompressionKind Kind) { + switch (Kind) { + case LLVMRustCompressionKind::None: + return llvm::DebugCompressionType::None; + case LLVMRustCompressionKind::Zlib: + if (!llvm::compression::zlib::isAvailable()) { + report_fatal_error("LLVMRustCompressionKind::Zlib not available"); + } + return llvm::DebugCompressionType::Zlib; + case LLVMRustCompressionKind::Zstd: + if (!llvm::compression::zstd::isAvailable()) { + report_fatal_error("LLVMRustCompressionKind::Zstd not available"); + } + return llvm::DebugCompressionType::Zstd; + } + report_fatal_error("bad LLVMRustCompressionKind"); +} + extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, RustStringRef OutStr) { ArrayRef CPUTable = @@ -271,7 +296,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool TrapUnreachable, bool Singlethread, bool VerboseAsm, bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, const char *SplitDwarfFile, const char *OutputObjFile, - const char *DebugInfoCompression, bool UseEmulatedTls, bool UseWasmEH) { + LLVMRustCompressionKind DebugInfoCompression, bool UseEmulatedTls, + bool UseWasmEH) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -307,16 +333,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( if (OutputObjFile) { Options.ObjectFilenameForDebug = OutputObjFile; } - if (!strcmp("zlib", DebugInfoCompression) && - llvm::compression::zlib::isAvailable()) { - Options.MCOptions.CompressDebugSections = DebugCompressionType::Zlib; - } else if (!strcmp("zstd", DebugInfoCompression) && - llvm::compression::zstd::isAvailable()) { - Options.MCOptions.CompressDebugSections = DebugCompressionType::Zstd; - } else if (!strcmp("none", DebugInfoCompression)) { - Options.MCOptions.CompressDebugSections = DebugCompressionType::None; - } - + // To avoid fatal errors, make sure the Rust-side code only passes a + // compression kind that is known to be supported by this build of LLVM, via + // `LLVMRustLLVMHasZlibCompression` and `LLVMRustLLVMHasZstdCompression`. + Options.MCOptions.CompressDebugSections = fromRust(DebugInfoCompression); Options.MCOptions.X86RelaxRelocations = RelaxELFRelocations; Options.UseInitArray = UseInitArray; Options.EmulatedTLS = UseEmulatedTls; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 6b4f8a6dba79f..55a90baf8cc09 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1640,11 +1640,11 @@ extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) { return false; } -extern "C" bool LLVMRustLLVMHasZlibCompressionForDebugSymbols() { +extern "C" bool LLVMRustLLVMHasZlibCompression() { return llvm::compression::zlib::isAvailable(); } -extern "C" bool LLVMRustLLVMHasZstdCompressionForDebugSymbols() { +extern "C" bool LLVMRustLLVMHasZstdCompression() { return llvm::compression::zstd::isAvailable(); } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8ff6d567422b9..54317ee6fbb87 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -583,17 +583,6 @@ pub enum DebugInfoCompression { Zstd, } -impl ToString for DebugInfoCompression { - fn to_string(&self) -> String { - match self { - DebugInfoCompression::None => "none", - DebugInfoCompression::Zlib => "zlib", - DebugInfoCompression::Zstd => "zstd", - } - .to_owned() - } -} - #[derive(Clone, Copy, Debug, PartialEq, Hash)] pub enum MirStripDebugInfo { None, From 26f35ae269f99c3067993bf4a08eeac88cc8493c Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 13 Apr 2025 22:57:37 +0800 Subject: [PATCH 12/45] Implement pattern matching for `&pin mut|const T` --- compiler/rustc_ast/src/ast.rs | 25 +- compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_ir/src/lib.rs | 7 + compiler/rustc_ast_pretty/src/pprust/state.rs | 7 +- .../src/diagnostics/mutability_errors.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 10 + compiler/rustc_hir/src/hir.rs | 2 +- .../rustc_hir_analysis/src/check/region.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 7 +- .../rustc_hir_typeck/src/expr_use_visitor.rs | 30 +- compiler/rustc_hir_typeck/src/pat.rs | 101 ++++- compiler/rustc_lint/src/static_mut_refs.rs | 2 +- compiler/rustc_middle/src/ty/adjustment.rs | 3 + compiler/rustc_middle/src/ty/adt.rs | 11 + compiler/rustc_middle/src/ty/sty.rs | 7 + .../rustc_middle/src/ty/typeck_results.rs | 5 +- .../src/builder/matches/match_pair.rs | 22 +- .../src/builder/matches/mod.rs | 71 ++- .../rustc_mir_build/src/check_unsafety.rs | 2 +- .../src/thir/pattern/check_match.rs | 6 +- .../src/thir/pattern/migration.rs | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 33 +- compiler/rustc_parse/src/parser/mod.rs | 11 +- compiler/rustc_parse/src/parser/pat.rs | 11 +- .../rustc_pattern_analysis/src/constructor.rs | 2 +- .../clippy_lints/src/index_refutable_slice.rs | 2 +- .../clippy_lints/src/matches/match_as_ref.rs | 2 +- .../src/matches/needless_match.rs | 2 +- .../src/matches/redundant_guards.rs | 2 +- .../clippy_lints/src/methods/clone_on_copy.rs | 2 +- .../clippy/clippy_lints/src/question_mark.rs | 8 +- .../clippy_lints/src/toplevel_ref_arg.rs | 4 +- .../clippy/clippy_lints/src/utils/author.rs | 4 + .../clippy/clippy_utils/src/eager_or_lazy.rs | 7 +- src/tools/clippy/clippy_utils/src/lib.rs | 4 +- src/tools/rustfmt/src/patterns.rs | 3 +- ...ct_pattern_match.bar_const.built.after.mir | 33 ++ ...ject_pattern_match.bar_mut.built.after.mir | 33 ++ ...attern_match.baz_baz_const.built.after.mir | 422 ++++++++++++++++++ ..._pattern_match.baz_baz_mut.built.after.mir | 422 ++++++++++++++++++ ...ct_pattern_match.baz_const.built.after.mir | 76 ++++ ...ject_pattern_match.baz_mut.built.after.mir | 76 ++++ ...attern_match.foo_bar_const.built.after.mir | 47 ++ ..._pattern_match.foo_bar_mut.built.after.mir | 47 ++ ...ct_pattern_match.foo_const.built.after.mir | 33 ++ ...ject_pattern_match.foo_mut.built.after.mir | 33 ++ .../pin-ergonomics/project_pattern_match.rs | 95 ++++ .../pattern-matching-deref-pattern.rs | 91 ++++ ...n-matching-mix-deref-pattern.normal.stderr | 66 +++ ...ng-mix-deref-pattern.pin_ergonomics.stderr | 130 ++++++ .../pattern-matching-mix-deref-pattern.rs | 113 +++++ .../pattern-matching.normal.stderr | 313 +++++++++++++ tests/ui/pin-ergonomics/pattern-matching.rs | 186 ++++++++ 53 files changed, 2552 insertions(+), 86 deletions(-) create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir create mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.rs create mode 100644 tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs create mode 100644 tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr create mode 100644 tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr create mode 100644 tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs create mode 100644 tests/ui/pin-ergonomics/pattern-matching.normal.stderr create mode 100644 tests/ui/pin-ergonomics/pattern-matching.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index e93351bcf7125..9f444670d91a1 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -789,14 +789,14 @@ pub struct PatField { #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Encodable, Decodable, HashStable_Generic, Walkable)] pub enum ByRef { - Yes(Mutability), + Yes(Pinnedness, Mutability), No, } impl ByRef { #[must_use] pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self { - if let ByRef::Yes(old_mutbl) = &mut self { + if let ByRef::Yes(_, old_mutbl) = &mut self { *old_mutbl = cmp::min(*old_mutbl, mutbl); } self @@ -814,20 +814,33 @@ pub struct BindingMode(pub ByRef, pub Mutability); impl BindingMode { pub const NONE: Self = Self(ByRef::No, Mutability::Not); - pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not); + pub const REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Not); + pub const REF_PIN: Self = + Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Not); pub const MUT: Self = Self(ByRef::No, Mutability::Mut); - pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not); - pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut); - pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut); + pub const REF_MUT: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Not); + pub const REF_PIN_MUT: Self = + Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Not); + pub const MUT_REF: Self = Self(ByRef::Yes(Pinnedness::Not, Mutability::Not), Mutability::Mut); + pub const MUT_REF_PIN: Self = + Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Not), Mutability::Mut); + pub const MUT_REF_MUT: Self = + Self(ByRef::Yes(Pinnedness::Not, Mutability::Mut), Mutability::Mut); + pub const MUT_REF_PIN_MUT: Self = + Self(ByRef::Yes(Pinnedness::Pinned, Mutability::Mut), Mutability::Mut); pub fn prefix_str(self) -> &'static str { match self { Self::NONE => "", Self::REF => "ref ", + Self::REF_PIN => "ref pin const ", Self::MUT => "mut ", Self::REF_MUT => "ref mut ", + Self::REF_PIN_MUT => "ref pin mut ", Self::MUT_REF => "mut ref ", + Self::MUT_REF_PIN => "mut ref pin ", Self::MUT_REF_MUT => "mut ref mut ", + Self::MUT_REF_PIN_MUT => "mut ref pin mut ", } } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 03e5a6edeece5..c60407c419c14 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -368,6 +368,7 @@ macro_rules! common_visitor_and_walkers { crate::tokenstream::TokenStream, Movability, Mutability, + Pinnedness, Result<(), rustc_span::ErrorGuaranteed>, rustc_data_structures::fx::FxHashMap, rustc_span::ErrorGuaranteed, diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index 44837b1b49407..0f63fad157431 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -311,3 +311,10 @@ pub enum Pinnedness { Not, Pinned, } + +impl Pinnedness { + /// Return `true` if self is pinned + pub fn is_pinned(self) -> bool { + matches!(self, Self::Pinned) + } +} diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index a5e2bcaa3bd06..93f4e47342f14 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1712,10 +1712,15 @@ impl<'a> State<'a> { if mutbl.is_mut() { self.word_nbsp("mut"); } - if let ByRef::Yes(rmutbl) = by_ref { + if let ByRef::Yes(pinnedness, rmutbl) = by_ref { self.word_nbsp("ref"); + if pinnedness.is_pinned() { + self.word_nbsp("pin"); + } if rmutbl.is_mut() { self.word_nbsp("mut"); + } else if pinnedness.is_pinned() { + self.word_nbsp("const"); } } self.print_ident(*ident); diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index b4990ffc7739c..e23c7eebeca1e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1188,7 +1188,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm { - binding_mode: BindingMode(ByRef::Yes(_), _), + binding_mode: BindingMode(ByRef::Yes(..), _), .. })) => { let pattern_span: Span = local_decl.source_info.span; diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a57689a45b67b..0b098d1fafde3 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2584,6 +2584,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { _ => bug!("Deref of unexpected type: {:?}", base_ty), } } + // Check as the inner reference type if it is a field projection + // from the `&pin` pattern + ProjectionElem::Field(FieldIdx::ZERO, _) + if let Some(adt) = + place_base.ty(self.body(), self.infcx.tcx).ty.ty_adt_def() + && adt.is_pin() + && self.infcx.tcx.features().pin_ergonomics() => + { + self.is_mutable(place_base, is_local_mutation_allowed) + } // All other projections are owned by their base path, so mutable if // base path is mutable ProjectionElem::Field(..) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 8b55a0d732994..cf950023b4f14 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -13,7 +13,7 @@ use rustc_ast::{ pub use rustc_ast::{ AssignOp, AssignOpKind, AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto, - MetaItemInner, MetaItemLit, Movability, Mutability, UnOp, + MetaItemInner, MetaItemLit, Movability, Mutability, Pinnedness, UnOp, }; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index f99fefcf56ace..bac34454b3b7a 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -575,7 +575,7 @@ fn resolve_local<'tcx>( // & expression, and its lifetime would be extended to the end of the block (due // to a different rule, not the below code). match pat.kind { - PatKind::Binding(hir::BindingMode(hir::ByRef::Yes(_), _), ..) => true, + PatKind::Binding(hir::BindingMode(hir::ByRef::Yes(..), _), ..) => true, PatKind::Struct(_, field_pats, _) => field_pats.iter().any(|fp| is_binding_pat(fp.pat)), diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index ed5f61b3c69ab..935b2e7a1bdb9 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1928,10 +1928,15 @@ impl<'a> State<'a> { if mutbl.is_mut() { self.word_nbsp("mut"); } - if let ByRef::Yes(rmutbl) = by_ref { + if let ByRef::Yes(pinnedness, rmutbl) = by_ref { self.word_nbsp("ref"); + if pinnedness.is_pinned() { + self.word_nbsp("pin"); + } if rmutbl.is_mut() { self.word_nbsp("mut"); + } else if pinnedness.is_pinned() { + self.word_nbsp("const"); } } self.print_ident(ident); diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 2034131882820..b9f1463d8007d 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -986,7 +986,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // of the pattern, as this just looks confusing, instead use the span // of the discriminant. match bm.0 { - hir::ByRef::Yes(m) => { + hir::ByRef::Yes(_, m) => { let bk = ty::BorrowKind::from_mutbl(m); self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); } @@ -1004,7 +1004,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // Deref patterns on boxes don't borrow, so we ignore them here. // HACK: this could be a fake pattern corresponding to a deref inserted by match // ergonomics, in which case `pat.hir_id` will be the id of the subpattern. - if let hir::ByRef::Yes(mutability) = + if let hir::ByRef::Yes(_, mutability) = self.cx.typeck_results().deref_pat_borrow_mode(place.place.ty(), subpattern) { let bk = ty::BorrowKind::from_mutbl(mutability); @@ -1256,7 +1256,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx .get(pat.hir_id) .expect("missing binding mode"); - if matches!(bm.0, hir::ByRef::Yes(_)) { + if let hir::ByRef::Yes(pinnedness, _) = bm.0 { + let base_ty = if pinnedness.is_pinned() { + base_ty.pinned_ty().ok_or_else(|| { + debug!("By-pin-ref binding of non-`Pin` type: {base_ty:?}"); + self.cx.report_bug(pat.span, "by-pin-ref binding of non-`Pin` type") + })? + } else { + base_ty + }; // a bind-by-ref means that the base_ty will be the type of the ident itself, // but what we want here is the type of the underlying value being borrowed. // So peel off one-level, turning the &T into T. @@ -1264,7 +1272,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx { Some(ty) => Ok(ty), None => { - debug!("By-ref binding of non-derefable type"); + debug!("By-ref binding of non-derefable type: {base_ty:?}"); Err(self .cx .report_bug(pat.span, "by-ref binding of non-derefable type")) @@ -1706,6 +1714,18 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx }; self.pat_deref_place(pat.hir_id, place_with_id, pat, target_ty)? } + adjustment::PatAdjust::PinDeref => { + debug!("`PinDeref` of non-pinned-reference type: {:?}", adjust.source); + let target_ty = adjust.source.pinned_ty().ok_or_else(|| { + self.cx.report_bug( + self.cx.tcx().hir_span(pat.hir_id), + "`PinDeref` of non-pinned-reference type", + ) + })?; + let kind = ProjectionKind::Field(FieldIdx::ZERO, FIRST_VARIANT); + place_with_id = self.cat_projection(pat.hir_id, place_with_id, target_ty, kind); + self.cat_deref(pat.hir_id, place_with_id)? + } }; } drop(typeck_results); // explicitly release borrow of typeck results, just in case. @@ -1877,7 +1897,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // Deref patterns on boxes are lowered using a built-in deref. hir::ByRef::No => self.cat_deref(hir_id, base_place), // For other types, we create a temporary to match on. - hir::ByRef::Yes(mutability) => { + hir::ByRef::Yes(_, mutability) => { let re_erased = self.cx.tcx().lifetimes.re_erased; let ty = Ty::new_ref(self.cx.tcx(), re_erased, target_ty, mutability); // A deref pattern stores the result of `Deref::deref` or `DerefMut::deref_mut` ... diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index d14463e44a03f..d2b3041ad7e1a 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -18,7 +18,7 @@ use rustc_hir::{ use rustc_hir_analysis::autoderef::report_autoderef_recursion_limit_error; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::traits::PatternOriginExpr; -use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::parse::feature_err; @@ -413,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat, derefed_tys.iter().filter_map(|adjust| match adjust.kind { PatAdjust::OverloadedDeref => Some(adjust.source), - PatAdjust::BuiltinDeref => None, + PatAdjust::BuiltinDeref | PatAdjust::PinDeref => None, }), ); } @@ -471,7 +471,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info: PatInfo<'tcx>, ) -> Ty<'tcx> { #[cfg(debug_assertions)] - if pat_info.binding_mode == ByRef::Yes(Mutability::Mut) + if matches!(pat_info.binding_mode, ByRef::Yes(_, Mutability::Mut)) && pat_info.max_ref_mutbl != MutblCap::Mut && self.downgrade_mut_inside_shared() { @@ -489,12 +489,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let old_pat_info = pat_info; let pat_info = PatInfo { current_depth: old_pat_info.current_depth + 1, ..old_pat_info }; + let adjust_binding_mode = |inner_pinnedness, inner_mutability| { + match pat_info.binding_mode { + // If default binding mode is by value, make it `ref`, `ref mut`, `ref pin const` + // or `ref pin mut` (depending on whether we observe `&`, `&mut`, `&pin const` or + // `&pin mut`). + ByRef::No => ByRef::Yes(inner_pinnedness, inner_mutability), + // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`). + // Pinnedness is preserved. + ByRef::Yes(pinnedness, Mutability::Mut) => ByRef::Yes(pinnedness, inner_mutability), + // Once a `ref`, always a `ref`. + // This is because a `& &mut` cannot mutate the underlying value. + // Pinnedness is preserved. + ByRef::Yes(pinnedness, Mutability::Not) => ByRef::Yes(pinnedness, Mutability::Not), + } + }; + match pat.kind { - // Peel off a `&` or `&mut` from the scrutinee type. See the examples in + // Peel off a `&` or `&mut`from the scrutinee type. See the examples in // `tests/ui/rfcs/rfc-2005-default-binding-mode`. _ if let AdjustMode::Peel { kind: peel_kind } = adjust_mode && pat.default_binding_modes - && let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() + && let &ty::Ref(_, inner_ty, inner_mutability) = expected.kind() && self.should_peel_ref(peel_kind, expected) => { debug!("inspecting {:?}", expected); @@ -508,22 +524,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .or_default() .push(PatAdjustment { kind: PatAdjust::BuiltinDeref, source: expected }); - let mut binding_mode = ByRef::Yes(match pat_info.binding_mode { - // If default binding mode is by value, make it `ref` or `ref mut` - // (depending on whether we observe `&` or `&mut`). - ByRef::No | - // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`). - ByRef::Yes(Mutability::Mut) => inner_mutability, - // Once a `ref`, always a `ref`. - // This is because a `& &mut` cannot mutate the underlying value. - ByRef::Yes(Mutability::Not) => Mutability::Not, - }); + let mut binding_mode = adjust_binding_mode(Pinnedness::Not, inner_mutability); let mut max_ref_mutbl = pat_info.max_ref_mutbl; if self.downgrade_mut_inside_shared() { binding_mode = binding_mode.cap_ref_mutability(max_ref_mutbl.as_mutbl()); } - if binding_mode == ByRef::Yes(Mutability::Not) { + if matches!(binding_mode, ByRef::Yes(_, Mutability::Not)) { max_ref_mutbl = MutblCap::Not; } debug!("default binding mode is now {:?}", binding_mode); @@ -533,6 +540,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Recurse with the new expected type. self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, new_pat_info) } + // If `pin_ergonomics` is enabled, peel the `&pin` from the pinned reference type. See the + // examples in `tests/ui/async-await/pin-ergonomics/`. + _ if self.tcx.features().pin_ergonomics() + && let AdjustMode::Peel { kind: peel_kind } = adjust_mode + && pat.default_binding_modes + && self.should_peel_smart_pointer(peel_kind, expected) + && let Some(pinned_ty) = expected.pinned_ty() + // Currently, only pinned reference is specially handled, leaving other + // pinned types (e.g. `Pin>` to deref patterns) handled as a + // deref pattern. + && let &ty::Ref(_, inner_ty, inner_mutability) = pinned_ty.kind() => + { + debug!("scrutinee ty {expected:?} is a pinned reference, inserting pin deref"); + // Preserve the pinned type. We'll need it later during THIR lowering. + self.typeck_results + .borrow_mut() + .pat_adjustments_mut() + .entry(pat.hir_id) + .or_default() + .push(PatAdjustment { kind: PatAdjust::PinDeref, source: expected }); + + let binding_mode = adjust_binding_mode(Pinnedness::Pinned, inner_mutability); + // If the pinnedness is `Not`, it means the pattern is unpinned + // and thus requires an `Unpin` bound. + if binding_mode == ByRef::Yes(Pinnedness::Not, Mutability::Mut) { + self.register_bound( + inner_ty, + self.tcx.require_lang_item(hir::LangItem::Unpin, pat.span), + self.misc(pat.span), + ); + } + // Use the old pat info to keep `current_depth` to its old value. + let new_pat_info = PatInfo { binding_mode, ..old_pat_info }; + // Recurse with the new expected type. + // using `break` instead of `return` in case where any shared codes are added + // after the `match pat.kind {}`. + self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, new_pat_info) + } // If `deref_patterns` is enabled, peel a smart pointer from the scrutinee type. See the // examples in `tests/ui/pattern/deref_patterns/`. _ if self.tcx.features().deref_patterns() @@ -1061,7 +1106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Determine the binding mode... let bm = match user_bind_annot { - BindingMode(ByRef::No, Mutability::Mut) if let ByRef::Yes(def_br_mutbl) = def_br => { + BindingMode(ByRef::No, Mutability::Mut) if let ByRef::Yes(_, def_br_mutbl) = def_br => { // Only mention the experimental `mut_ref` feature if if we're in edition 2024 and // using other experimental matching features compatible with it. if pat.span.at_least_rust_2024() @@ -1091,8 +1136,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), - BindingMode(ByRef::Yes(user_br_mutbl), _) => { - if let ByRef::Yes(def_br_mutbl) = def_br { + BindingMode(ByRef::Yes(_, user_br_mutbl), _) => { + if let ByRef::Yes(_, def_br_mutbl) = def_br { // `ref`/`ref mut` overrides the binding mode on edition <= 2021 self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, @@ -1108,7 +1153,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - if bm.0 == ByRef::Yes(Mutability::Mut) + if matches!(bm.0, ByRef::Yes(_, Mutability::Mut)) && let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl { let mut err = struct_span_code_err!( @@ -1136,7 +1181,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let local_ty = self.local_ty(pat.span, pat.hir_id); let eq_ty = match bm.0 { - ByRef::Yes(mutbl) => { + ByRef::Yes(Pinnedness::Not, mutbl) => { // If the binding is like `ref x | ref mut x`, // then `x` is assigned a value of type `&M T` where M is the // mutability and T is the expected type. @@ -1146,6 +1191,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // See (note_1) for an explanation. self.new_ref_ty(pat.span, mutbl, expected) } + // Wrapping the type into `Pin` if the binding is like `ref pin const|mut x` + ByRef::Yes(Pinnedness::Pinned, mutbl) => Ty::new_adt( + self.tcx, + self.tcx.adt_def(self.tcx.require_lang_item(hir::LangItem::Pin, pat.span)), + self.tcx.mk_args(&[self.new_ref_ty(pat.span, mutbl, expected).into()]), + ), // Otherwise, the type of x is the expected type `T`. ByRef::No => expected, // As above, `T <: typeof(x)` is required, but we use equality, see (note_1). }; @@ -2605,7 +2656,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected = self.try_structurally_resolve_type(pat.span, expected); // Determine whether we're consuming an inherited reference and resetting the default // binding mode, based on edition and enabled experimental features. - if let ByRef::Yes(inh_mut) = pat_info.binding_mode { + if let ByRef::Yes(_, inh_mut) = pat_info.binding_mode { match self.ref_pat_matches_inherited_ref(pat.span.edition()) { InheritedRefMatchRule::EatOuter => { // ref pattern attempts to consume inherited reference @@ -3126,8 +3177,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the user-provided binding modifier doesn't match the default binding mode, we'll // need to suggest reference patterns, which can affect other bindings. // For simplicity, we opt to suggest making the pattern fully explicit. - info.suggest_eliding_modes &= - user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not); + info.suggest_eliding_modes &= matches!( + user_bind_annot, + BindingMode(ByRef::Yes(_, mutbl), Mutability::Not) if mutbl == def_br_mutbl + ); if user_bind_annot == BindingMode(ByRef::No, Mutability::Mut) { info.bad_mut_modifiers = true; "`mut` binding modifier" diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 16e1fb0192b32..1c0df1f4234a2 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'_>) { if let hir::StmtKind::Let(loc) = stmt.kind && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind - && let hir::ByRef::Yes(m) = ba.0 + && let hir::ByRef::Yes(_, m) = ba.0 && let Some(init) = loc.init && let Some(err_span) = path_is_static_mut(init, init.span) { diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 74573455f531a..2920c9cb42ab4 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -232,4 +232,7 @@ pub enum PatAdjust { /// An implicit call to `Deref(Mut)::deref(_mut)` before matching, such as when matching the /// pattern `[..]` against a scrutinee of type `Vec`. OverloadedDeref, + /// An implicit dereference before matching a `&pin` reference (under feature `pin_ergonomics`), + /// which will be lowered as a builtin deref of the private field `__pointer` in `Pin` + PinDeref, } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index df82c7a826be9..be909a08e8dae 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -55,6 +55,8 @@ bitflags::bitflags! { const IS_UNSAFE_CELL = 1 << 9; /// Indicates whether the type is `UnsafePinned`. const IS_UNSAFE_PINNED = 1 << 10; + /// Indicates whether the type is `Pin`. + const IS_PIN = 1 << 11; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } @@ -313,6 +315,9 @@ impl AdtDefData { if tcx.is_lang_item(did, LangItem::UnsafePinned) { flags |= AdtFlags::IS_UNSAFE_PINNED; } + if tcx.is_lang_item(did, LangItem::Pin) { + flags |= AdtFlags::IS_PIN; + } AdtDefData { did, variants, flags, repr } } @@ -428,6 +433,12 @@ impl<'tcx> AdtDef<'tcx> { self.flags().contains(AdtFlags::IS_MANUALLY_DROP) } + /// Returns `true` if this is `Pin`. + #[inline] + pub fn is_pin(self) -> bool { + self.flags().contains(AdtFlags::IS_PIN) + } + /// Returns `true` if this type has a destructor. pub fn has_dtor(self, tcx: TyCtxt<'tcx>) -> bool { self.destructor(tcx).is_some() diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ad8b1fd0693b0..d883f63486040 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1349,6 +1349,13 @@ impl<'tcx> Ty<'tcx> { } } + pub fn pinned_ty(self) -> Option> { + match self.kind() { + Adt(def, args) if def.is_pin() => Some(args.type_at(0)), + _ => None, + } + } + /// Panics if called on any type other than `Box`. pub fn expect_boxed_ty(self) -> Ty<'tcx> { self.boxed_ty() diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index d1fb700913d91..6a6ed702373d1 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -11,6 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap}; use rustc_hir::hir_id::OwnerId; use rustc_hir::{ self as hir, BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability, + Pinnedness, }; use rustc_index::IndexVec; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; @@ -479,7 +480,7 @@ impl<'tcx> TypeckResults<'tcx> { let mut has_ref_mut = false; pat.walk(|pat| { if let hir::PatKind::Binding(_, id, _, _) = pat.kind - && let Some(BindingMode(ByRef::Yes(Mutability::Mut), _)) = + && let Some(BindingMode(ByRef::Yes(_, Mutability::Mut), _)) = self.pat_binding_modes().get(id) { has_ref_mut = true; @@ -503,7 +504,7 @@ impl<'tcx> TypeckResults<'tcx> { ByRef::No } else { let mutable = self.pat_has_ref_mut_binding(inner); - ByRef::Yes(if mutable { Mutability::Mut } else { Mutability::Not }) + ByRef::Yes(Pinnedness::Not, if mutable { Mutability::Mut } else { Mutability::Not }) } } diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index c3028b9b5c4ea..af565ef636993 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -1,9 +1,10 @@ use std::sync::Arc; +use rustc_abi::FieldIdx; use rustc_hir::ByRef; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt}; use crate::builder::Builder; use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder}; @@ -299,7 +300,24 @@ impl<'tcx> MatchPairTree<'tcx> { None } - PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(mutability) } => { + PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } => { + let Some(ref_ty) = pattern.ty.pinned_ty() else { + rustc_middle::bug!("RefPin pattern on non-`Pin` type {:?}", pattern.ty); + }; + MatchPairTree::for_pattern( + place_builder.field(FieldIdx::ZERO, ref_ty).deref(), + subpattern, + cx, + &mut subpairs, + extra_data, + ); + None + } + + PatKind::DerefPattern { + ref subpattern, + borrow: ByRef::Yes(Pinnedness::Not, mutability), + } => { // Create a new temporary for each deref pattern. // FIXME(deref_patterns): dedup temporaries to avoid multiple `deref()` calls? let temp = cx.temp( diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 82f12a969bb1c..96c58dc14e8cb 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -5,20 +5,21 @@ //! This also includes code for pattern bindings in `let` statements and //! function parameters. +use std::assert_matches::debug_assert_matches; use std::borrow::Borrow; use std::mem; use std::sync::Arc; use itertools::{Itertools, Position}; -use rustc_abi::VariantIdx; +use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_hir::{BindingMode, ByRef, LetStmt, LocalSource, Node}; -use rustc_middle::bug; +use rustc_hir::{BindingMode, ByRef, LangItem, LetStmt, LocalSource, Node, Pinnedness}; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{self, *}; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, ValTree, ValTreeKind}; +use rustc_middle::{bug, span_bug}; use rustc_pattern_analysis::constructor::RangeEnd; use rustc_pattern_analysis::rustc::{DeconstructedPat, RustcPatCtxt}; use rustc_span::{BytePos, Pos, Span, Symbol, sym}; @@ -917,6 +918,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visit_subpat(self, subpattern, &user_tys.deref(), f); } + PatKind::DerefPattern { ref subpattern, borrow: ByRef::Yes(Pinnedness::Pinned, _) } => { + visit_subpat(self, subpattern, &user_tys.leaf(FieldIdx::ZERO).deref(), f); + } + PatKind::DerefPattern { ref subpattern, .. } => { visit_subpat(self, subpattern, &ProjectedUserTypesNode::None, f); } @@ -2747,9 +2752,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source); self.cfg.push_assign(block, source_info, ref_for_guard, rvalue); } - ByRef::Yes(mutbl) => { - // The arm binding will be by reference, so eagerly create it now. Drops must - // be scheduled to emit `StorageDead` on the guard's failure/break branches. + ByRef::Yes(pinnedness, mutbl) => { + // The arm binding will be by reference, so eagerly create it now // be scheduled to emit `StorageDead` on the guard's failure/break branches. let value_for_arm = self.storage_live_binding( block, binding.var_id, @@ -2761,6 +2765,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let rvalue = Rvalue::Ref(re_erased, util::ref_pat_borrow_kind(mutbl), binding.source); + let rvalue = match pinnedness { + ty::Pinnedness::Not => rvalue, + ty::Pinnedness::Pinned => { + self.pin_borrowed_local(block, value_for_arm.local, rvalue, source_info) + } + }; self.cfg.push_assign(block, source_info, value_for_arm, rvalue); // For the guard binding, take a shared reference to that reference. let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, value_for_arm); @@ -2797,14 +2807,59 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let rvalue = match binding.binding_mode.0 { ByRef::No => Rvalue::Use(self.consume_by_copy_or_move(binding.source)), - ByRef::Yes(mutbl) => { - Rvalue::Ref(re_erased, util::ref_pat_borrow_kind(mutbl), binding.source) + ByRef::Yes(pinnedness, mutbl) => { + let rvalue = + Rvalue::Ref(re_erased, util::ref_pat_borrow_kind(mutbl), binding.source); + match pinnedness { + ty::Pinnedness::Not => rvalue, + ty::Pinnedness::Pinned => { + self.pin_borrowed_local(block, local.local, rvalue, source_info) + } + } } }; self.cfg.push_assign(block, source_info, local, rvalue); } } + /// Given an rvalue `&[mut]borrow` and a local `local`, generate the pinned borrow for it: + /// ```ignore (illustrative) + /// pinned_temp = &borrow; + /// local = Pin { __pointer: move pinned_temp }; + /// ``` + fn pin_borrowed_local( + &mut self, + block: BasicBlock, + local: Local, + borrow: Rvalue<'tcx>, + source_info: SourceInfo, + ) -> Rvalue<'tcx> { + debug_assert_matches!(borrow, Rvalue::Ref(..)); + + let local_ty = self.local_decls[local].ty; + + let pinned_ty = local_ty.pinned_ty().unwrap_or_else(|| { + span_bug!( + source_info.span, + "expect type `Pin` for a pinned binding, found type {:?}", + local_ty + ) + }); + let pinned_temp = + Place::from(self.local_decls.push(LocalDecl::new(pinned_ty, source_info.span))); + self.cfg.push_assign(block, source_info, pinned_temp, borrow); + Rvalue::Aggregate( + Box::new(AggregateKind::Adt( + self.tcx.require_lang_item(LangItem::Pin, source_info.span), + FIRST_VARIANT, + self.tcx.mk_args(&[pinned_ty.into()]), + None, + None, + )), + std::iter::once(Operand::Move(pinned_temp)).collect(), + ) + } + /// Each binding (`ref mut var`/`ref var`/`mut var`/`var`, where the bound /// `var` has type `T` in the arm body) in a pattern maps to 2 locals. The /// first local is a binding for occurrences of `var` in the guard, which diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 195d45c2c4c49..18e9543407764 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -383,7 +383,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } visit::walk_pat(self, pat); } - PatKind::Binding { mode: BindingMode(ByRef::Yes(rm), _), ty, .. } => { + PatKind::Binding { mode: BindingMode(ByRef::Yes(_, rm), _), ty, .. } => { if self.inside_adt { let ty::Ref(_, ty, _) = ty.kind() else { span_bug!( diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 3929a97eed8f2..2400d297c89cf 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -797,7 +797,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: // We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`. let mut conflicts_ref = Vec::new(); sub.each_binding(|_, mode, _, span| { - if matches!(mode, ByRef::Yes(_)) { + if matches!(mode, ByRef::Yes(..)) { conflicts_ref.push(span) } }); @@ -813,7 +813,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: return; } ByRef::No => return, - ByRef::Yes(m) => m, + ByRef::Yes(_, m) => m, }; // We now have `ref $mut_outer binding @ sub` (semantically). @@ -823,7 +823,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat: let mut conflicts_mut_ref = Vec::new(); sub.each_binding(|name, mode, ty, span| { match mode { - ByRef::Yes(mut_inner) => match (mut_outer, mut_inner) { + ByRef::Yes(_, mut_inner) => match (mut_outer, mut_inner) { // Both sides are `ref`. (Mutability::Not, Mutability::Not) => {} // 2x `ref mut`. diff --git a/compiler/rustc_mir_build/src/thir/pattern/migration.rs b/compiler/rustc_mir_build/src/thir/pattern/migration.rs index 8887308530506..095023a471b93 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/migration.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/migration.rs @@ -212,7 +212,7 @@ impl<'a> PatMigration<'a> { } if !self.info.suggest_eliding_modes && explicit_ba.0 == ByRef::No - && let ByRef::Yes(mutbl) = mode.0 + && let ByRef::Yes(_, mutbl) = mode.0 { // If we can't fix the pattern by eliding modifiers, we'll need to make the pattern // fully explicit. i.e. we'll need to suggest reference patterns for this. diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index dc6b958904497..404f410e22191 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -11,7 +11,7 @@ use rustc_abi::{FieldIdx, Integer}; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{self as hir, LangItem, RangeEnd}; +use rustc_hir::{self as hir, ByRef, LangItem, Mutability, Pinnedness, RangeEnd}; use rustc_index::Idx; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::LitToConstInput; @@ -114,6 +114,16 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let borrow = self.typeck_results.deref_pat_borrow_mode(adjust.source, pat); PatKind::DerefPattern { subpattern: thir_pat, borrow } } + PatAdjust::PinDeref => { + let mutable = self.typeck_results.pat_has_ref_mut_binding(pat); + PatKind::DerefPattern { + subpattern: thir_pat, + borrow: ByRef::Yes( + Pinnedness::Pinned, + if mutable { Mutability::Mut } else { Mutability::Not }, + ), + } + } }; Box::new(Pat { span, ty: adjust.source, kind }) }); @@ -354,11 +364,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // A ref x pattern is the same node used for x, and as such it has // x's type, which is &T, where we want T (the type being matched). let var_ty = ty; - if let hir::ByRef::Yes(_) = mode.0 { - if let ty::Ref(_, rty, _) = ty.kind() { - ty = *rty; - } else { - bug!("`ref {}` has wrong type {}", ident, ty); + if let hir::ByRef::Yes(pinnedness, _) = mode.0 { + match pinnedness { + hir::Pinnedness::Pinned + if let Some(pty) = ty.pinned_ty() + && let &ty::Ref(_, rty, _) = pty.kind() => + { + debug_assert!( + self.tcx.features().pin_ergonomics(), + "`pin_ergonomics` must be enabled to have a by-pin-ref binding" + ); + ty = rty; + } + hir::Pinnedness::Not if let &ty::Ref(_, rty, _) = ty.kind() => { + ty = rty; + } + _ => bug!("`ref {}` has wrong type {}", ident, ty), } }; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index ed4069dae933c..30870c810942f 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -36,8 +36,8 @@ use rustc_ast::tokenstream::{ use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID, - DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, - Visibility, VisibilityKind, + DelimArgs, Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Pinnedness, Recovered, + Safety, StrLit, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; @@ -1317,7 +1317,12 @@ impl<'a> Parser<'a> { /// Parses reference binding mode (`ref`, `ref mut`, or nothing). fn parse_byref(&mut self) -> ByRef { - if self.eat_keyword(exp!(Ref)) { ByRef::Yes(self.parse_mutability()) } else { ByRef::No } + if self.eat_keyword(exp!(Ref)) { + // FIXME(pin_ergonomics): support `ref pin const|mut` bindings + ByRef::Yes(Pinnedness::Not, self.parse_mutability()) + } else { + ByRef::No + } } /// Possibly parses mutability (`const` or `mut`). diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 4f522d57e4140..f964ecb90326f 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -7,7 +7,8 @@ use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{ self as ast, Arm, AttrVec, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall, Mutability, - Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, StmtKind, + Pat, PatField, PatFieldsRest, PatKind, Path, Pinnedness, QSelf, RangeEnd, RangeSyntax, Stmt, + StmtKind, }; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey}; @@ -778,7 +779,11 @@ impl<'a> Parser<'a> { } // Parse ref ident @ pat / ref mut ident @ pat let mutbl = self.parse_mutability(); - self.parse_pat_ident(BindingMode(ByRef::Yes(mutbl), Mutability::Not), syntax_loc)? + self.parse_pat_ident( + // FIXME(pin_ergonomics): support `ref pin const|mut` bindings + BindingMode(ByRef::Yes(Pinnedness::Not, mutbl), Mutability::Not), + syntax_loc, + )? } else if self.eat_keyword(exp!(Box)) { self.parse_pat_box()? } else if self.check_inline_const(0) { @@ -1093,7 +1098,7 @@ impl<'a> Parser<'a> { self.ban_mut_general_pat(mut_span, &pat, changed_any_binding); } - if matches!(pat.kind, PatKind::Ident(BindingMode(ByRef::Yes(_), Mutability::Mut), ..)) { + if matches!(pat.kind, PatKind::Ident(BindingMode(ByRef::Yes(..), Mutability::Mut), ..)) { self.psess.gated_spans.gate(sym::mut_ref, pat.span); } Ok(pat.kind) diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index 12f653a13371d..fb5292f48d2b0 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -981,7 +981,7 @@ pub enum ConstructorSet { /// This type has the following list of constructors. If `variants` is empty and /// `non_exhaustive` is false, don't use this; use `NoConstructors` instead. Variants { variants: IndexVec, non_exhaustive: bool }, - /// The type is `&T`. + /// The type is `&T` Ref, /// The type is a union. Union, diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 919702c5714ad..e95816353df61 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -94,7 +94,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap, arm: &Arm<'_>) -> Option { .qpath_res(qpath, arm.pat.hir_id) .ctor_parent(cx) .is_lang_item(cx, LangItem::OptionSome) - && let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., ident, _) = first_pat.kind + && let PatKind::Binding(BindingMode(ByRef::Yes(_, mutabl), _), .., ident, _) = first_pat.kind && let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind && e.res(cx).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome) && let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs index c9b6821ad98fd..9c6cf66019f01 100644 --- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs @@ -172,7 +172,7 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool { }, )), ) => { - return !matches!(annot, BindingMode(ByRef::Yes(_), _)) && pat_ident.name == first_seg.ident.name; + return !matches!(annot, BindingMode(ByRef::Yes(..), _)) && pat_ident.name == first_seg.ident.name; }, // Example: `Custom::TypeA => Custom::TypeB`, or `None => None` ( diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs index d39e315cae1f2..7a1dd94567b14 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs @@ -176,7 +176,7 @@ fn get_pat_binding<'tcx>( if let PatKind::Binding(bind_annot, hir_id, ident, _) = pat.kind && hir_id == local { - if matches!(bind_annot.0, rustc_ast::ByRef::Yes(_)) { + if matches!(bind_annot.0, rustc_ast::ByRef::Yes(..)) { let _ = byref_ident.insert(ident); } // the second call of `replace()` returns a `Some(span)`, meaning a multi-binding pattern diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs index 2a0ae14a4b088..9cdad980f238b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs +++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs @@ -56,7 +56,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) _ => false, }, // local binding capturing a reference - Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..)) => { + Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingMode(ByRef::Yes(..), _), ..)) => { return; }, _ => false, diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs index e67ea1f5e370d..928a4e02fa975 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark.rs @@ -150,7 +150,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { let init_expr_str = Sugg::hir_with_applicability(cx, init_expr, "..", &mut applicability).maybe_paren(); // Take care when binding is `ref` let sugg = if let PatKind::Binding( - BindingMode(ByRef::Yes(ref_mutability), binding_mutability), + BindingMode(ByRef::Yes(_,ref_mutability), binding_mutability), _hir_id, ident, subpattern, @@ -169,7 +169,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) { // Handle subpattern (@ subpattern) let maybe_subpattern = match subpattern { Some(Pat { - kind: PatKind::Binding(BindingMode(ByRef::Yes(_), _), _, subident, None), + kind: PatKind::Binding(BindingMode(ByRef::Yes(..), _), _, subident, None), .. }) => { // avoid `&ref` @@ -504,8 +504,8 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability); let requires_semi = matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(_)); let method_call_str = match by_ref { - ByRef::Yes(Mutability::Mut) => ".as_mut()", - ByRef::Yes(Mutability::Not) => ".as_ref()", + ByRef::Yes(_, Mutability::Mut) => ".as_mut()", + ByRef::Yes(_, Mutability::Not) => ".as_ref()", ByRef::No => "", }; let sugg = format!( diff --git a/src/tools/clippy/clippy_lints/src/toplevel_ref_arg.rs b/src/tools/clippy/clippy_lints/src/toplevel_ref_arg.rs index 074b79263d377..250c277ab5e1f 100644 --- a/src/tools/clippy/clippy_lints/src/toplevel_ref_arg.rs +++ b/src/tools/clippy/clippy_lints/src/toplevel_ref_arg.rs @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for ToplevelRefArg { ) { if !matches!(k, FnKind::Closure) { for arg in iter_input_pats(decl, body) { - if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind + if let PatKind::Binding(BindingMode(ByRef::Yes(..), _), ..) = arg.pat.kind && is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id) && !arg.span.in_external_macro(cx.tcx.sess.source_map()) { @@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for ToplevelRefArg { fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) { if let StmtKind::Let(local) = stmt.kind - && let PatKind::Binding(BindingMode(ByRef::Yes(mutabl), _), .., name, None) = local.pat.kind + && let PatKind::Binding(BindingMode(ByRef::Yes(_, mutabl), _), .., name, None) = local.pat.kind && let Some(init) = local.init // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue. && is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id) diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 68e51dace2db2..92cc11dae8b12 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -745,10 +745,14 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { let ann = match ann { BindingMode::NONE => "NONE", BindingMode::REF => "REF", + BindingMode::REF_PIN => "REF_PIN", BindingMode::MUT => "MUT", BindingMode::REF_MUT => "REF_MUT", + BindingMode::REF_PIN_MUT => "REF_PIN_MUT", BindingMode::MUT_REF => "MUT_REF", + BindingMode::MUT_REF_PIN => "MUT_REF_PIN", BindingMode::MUT_REF_MUT => "MUT_REF_MUT", + BindingMode::MUT_REF_PIN_MUT => "MUT_REF_PIN_MUT", }; kind!("Binding(BindingMode::{ann}, _, {name}, {sub})"); self.ident(name); diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index eb3f442ac754b..6b922a20ca207 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -212,7 +212,12 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS // Custom `Deref` impl might have side effects ExprKind::Unary(UnOp::Deref, e) - if self.cx.typeck_results().expr_ty(e).builtin_deref(true).is_none() => + if self + .cx + .typeck_results() + .expr_ty(e) + .builtin_deref(true) + .is_none() => { self.eagerness |= NoChange; }, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 6ee991eae137f..7b3de69d90868 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -783,7 +783,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { ByRef::No if !is_copy(cx, cx.typeck_results().node_type(id)) => { capture = CaptureKind::Value; }, - ByRef::Yes(Mutability::Mut) if capture != CaptureKind::Value => { + ByRef::Yes(_, Mutability::Mut) if capture != CaptureKind::Value => { capture = CaptureKind::Ref(Mutability::Mut); }, _ => (), @@ -1831,7 +1831,7 @@ pub fn is_expr_identity_of_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr< .typeck_results() .pat_binding_modes() .get(pat.hir_id) - .is_some_and(|mode| matches!(mode.0, ByRef::Yes(_))) + .is_some_and(|mode| matches!(mode.0, ByRef::Yes(..))) { // If the parameter is `(x, y)` of type `&(T, T)`, or `[x, y]` of type `&[T; 2]`, then // due to match ergonomics, the inner patterns become references. Don't consider this diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs index fa9a3e33914b6..03752c371ae11 100644 --- a/src/tools/rustfmt/src/patterns.rs +++ b/src/tools/rustfmt/src/patterns.rs @@ -134,7 +134,8 @@ impl Rewrite for Pat { let mut_prefix = format_mutability(mutability).trim(); let (ref_kw, mut_infix) = match by_ref { - ByRef::Yes(rmutbl) => ("ref", format_mutability(rmutbl).trim()), + // FIXME(pin_ergonomics): format the pinnedness + ByRef::Yes(_, rmutbl) => ("ref", format_mutability(rmutbl).trim()), ByRef::No => ("", ""), }; let id_str = rewrite_ident(context, ident); diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir new file mode 100644 index 0000000000000..15f7446cc5912 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir @@ -0,0 +1,33 @@ +// MIR for `bar_const` after built + +fn bar_const(_1: Pin<&Bar>) -> () { + debug bar => _1; + let mut _0: (); + let _2: std::pin::Pin<&T>; + let _3: std::pin::Pin<&U>; + let mut _4: &T; + let mut _5: &U; + scope 1 { + debug x => _2; + debug y => _3; + } + + bb0: { + PlaceMention(_1); + StorageLive(_2); + _4 = &((*(_1.0: &Bar)).0: T); + _2 = Pin::<&T> { pointer: move _4 }; + StorageLive(_3); + _5 = &((*(_1.0: &Bar)).1: U); + _3 = Pin::<&U> { pointer: move _5 }; + _0 = const (); + StorageDead(_3); + StorageDead(_2); + return; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir new file mode 100644 index 0000000000000..46fd15502ffb1 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir @@ -0,0 +1,33 @@ +// MIR for `bar_mut` after built + +fn bar_mut(_1: Pin<&mut Bar>) -> () { + debug bar => _1; + let mut _0: (); + let _2: std::pin::Pin<&mut T>; + let _3: std::pin::Pin<&mut U>; + let mut _4: &mut T; + let mut _5: &mut U; + scope 1 { + debug x => _2; + debug y => _3; + } + + bb0: { + PlaceMention(_1); + StorageLive(_2); + _4 = &mut ((*(_1.0: &mut Bar)).0: T); + _2 = Pin::<&mut T> { pointer: move _4 }; + StorageLive(_3); + _5 = &mut ((*(_1.0: &mut Bar)).1: U); + _3 = Pin::<&mut U> { pointer: move _5 }; + _0 = const (); + StorageDead(_3); + StorageDead(_2); + return; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir new file mode 100644 index 0000000000000..8cfaf50a5f876 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir @@ -0,0 +1,422 @@ +// MIR for `baz_baz_const` after built + +fn baz_baz_const(_1: Pin<&Baz, Baz>>) -> () { + debug baz => _1; + let mut _0: (); + let mut _2: isize; + let mut _3: isize; + let mut _4: isize; + let mut _5: isize; + let mut _6: isize; + let mut _7: isize; + let mut _8: isize; + let _9: std::pin::Pin<&T>; + let _10: std::pin::Pin<&U>; + let _11: std::pin::Pin<&T>; + let _12: std::pin::Pin<&U>; + let mut _13: &T; + let mut _14: &U; + let mut _15: &T; + let mut _16: &U; + let _17: std::pin::Pin<&T>; + let _18: std::pin::Pin<&U>; + let _19: std::pin::Pin<&T>; + let _20: std::pin::Pin<&U>; + let mut _21: &T; + let mut _22: &U; + let mut _23: &T; + let mut _24: &U; + let _25: std::pin::Pin<&T>; + let _26: std::pin::Pin<&U>; + let _27: std::pin::Pin<&T>; + let _28: std::pin::Pin<&U>; + let mut _29: &T; + let mut _30: &U; + let mut _31: &T; + let mut _32: &U; + let _33: std::pin::Pin<&T>; + let _34: std::pin::Pin<&U>; + let _35: std::pin::Pin<&T>; + let _36: std::pin::Pin<&U>; + let mut _37: &T; + let mut _38: &U; + let mut _39: &T; + let mut _40: &U; + let _41: std::pin::Pin<&T>; + let _42: std::pin::Pin<&U>; + let _43: std::pin::Pin<&T>; + let _44: std::pin::Pin<&U>; + let mut _45: &T; + let mut _46: &U; + let mut _47: &T; + let mut _48: &U; + let _49: std::pin::Pin<&T>; + let _50: std::pin::Pin<&U>; + let _51: std::pin::Pin<&T>; + let _52: std::pin::Pin<&U>; + let mut _53: &T; + let mut _54: &U; + let mut _55: &T; + let mut _56: &U; + let _57: std::pin::Pin<&T>; + let _58: std::pin::Pin<&U>; + let _59: std::pin::Pin<&T>; + let _60: std::pin::Pin<&U>; + let mut _61: &T; + let mut _62: &U; + let mut _63: &T; + let mut _64: &U; + let _65: std::pin::Pin<&T>; + let _66: std::pin::Pin<&U>; + let _67: std::pin::Pin<&T>; + let _68: std::pin::Pin<&U>; + let mut _69: &T; + let mut _70: &U; + let mut _71: &T; + let mut _72: &U; + scope 1 { + debug x => _9; + debug y => _10; + debug z => _11; + debug w => _12; + } + scope 2 { + debug x => _17; + debug y => _18; + debug z => _19; + debug w => _20; + } + scope 3 { + debug x => _25; + debug y => _26; + debug z => _27; + debug w => _28; + } + scope 4 { + debug x => _33; + debug y => _34; + debug z => _35; + debug w => _36; + } + scope 5 { + debug x => _41; + debug y => _42; + debug z => _43; + debug w => _44; + } + scope 6 { + debug x => _49; + debug y => _50; + debug z => _51; + debug w => _52; + } + scope 7 { + debug x => _57; + debug y => _58; + debug z => _59; + debug w => _60; + } + scope 8 { + debug x => _65; + debug y => _66; + debug z => _67; + debug w => _68; + } + + bb0: { + PlaceMention(_1); + _8 = discriminant((*(_1.0: &Baz, Baz>))); + switchInt(move _8) -> [0: bb2, 1: bb16, otherwise: bb1]; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb2: { + _4 = discriminant((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz)); + switchInt(move _4) -> [0: bb4, 1: bb10, otherwise: bb3]; + } + + bb3: { + goto -> bb1; + } + + bb4: { + _2 = discriminant((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz)); + switchInt(move _2) -> [0: bb6, 1: bb8, otherwise: bb5]; + } + + bb5: { + goto -> bb3; + } + + bb6: { + falseEdge -> [real: bb36, imaginary: bb8]; + } + + bb7: { + goto -> bb5; + } + + bb8: { + falseEdge -> [real: bb35, imaginary: bb10]; + } + + bb9: { + goto -> bb5; + } + + bb10: { + _3 = discriminant((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz)); + switchInt(move _3) -> [0: bb12, 1: bb14, otherwise: bb11]; + } + + bb11: { + goto -> bb3; + } + + bb12: { + falseEdge -> [real: bb34, imaginary: bb14]; + } + + bb13: { + goto -> bb11; + } + + bb14: { + falseEdge -> [real: bb33, imaginary: bb16]; + } + + bb15: { + goto -> bb11; + } + + bb16: { + _7 = discriminant((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz)); + switchInt(move _7) -> [0: bb18, 1: bb24, otherwise: bb17]; + } + + bb17: { + goto -> bb1; + } + + bb18: { + _5 = discriminant((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz)); + switchInt(move _5) -> [0: bb20, 1: bb22, otherwise: bb19]; + } + + bb19: { + goto -> bb17; + } + + bb20: { + falseEdge -> [real: bb32, imaginary: bb22]; + } + + bb21: { + goto -> bb19; + } + + bb22: { + falseEdge -> [real: bb31, imaginary: bb24]; + } + + bb23: { + goto -> bb19; + } + + bb24: { + _6 = discriminant((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz)); + switchInt(move _6) -> [0: bb26, 1: bb28, otherwise: bb25]; + } + + bb25: { + goto -> bb17; + } + + bb26: { + falseEdge -> [real: bb30, imaginary: bb28]; + } + + bb27: { + goto -> bb25; + } + + bb28: { + StorageLive(_65); + _69 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); + _65 = Pin::<&T> { pointer: move _69 }; + StorageLive(_66); + _70 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); + _66 = Pin::<&U> { pointer: move _70 }; + StorageLive(_67); + _71 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); + _67 = Pin::<&T> { pointer: move _71 }; + StorageLive(_68); + _72 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); + _68 = Pin::<&U> { pointer: move _72 }; + _0 = const (); + StorageDead(_68); + StorageDead(_67); + StorageDead(_66); + StorageDead(_65); + goto -> bb37; + } + + bb29: { + goto -> bb25; + } + + bb30: { + StorageLive(_57); + _61 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); + _57 = Pin::<&T> { pointer: move _61 }; + StorageLive(_58); + _62 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); + _58 = Pin::<&U> { pointer: move _62 }; + StorageLive(_59); + _63 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); + _59 = Pin::<&T> { pointer: move _63 }; + StorageLive(_60); + _64 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); + _60 = Pin::<&U> { pointer: move _64 }; + _0 = const (); + StorageDead(_60); + StorageDead(_59); + StorageDead(_58); + StorageDead(_57); + goto -> bb37; + } + + bb31: { + StorageLive(_49); + _53 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); + _49 = Pin::<&T> { pointer: move _53 }; + StorageLive(_50); + _54 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); + _50 = Pin::<&U> { pointer: move _54 }; + StorageLive(_51); + _55 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); + _51 = Pin::<&T> { pointer: move _55 }; + StorageLive(_52); + _56 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); + _52 = Pin::<&U> { pointer: move _56 }; + _0 = const (); + StorageDead(_52); + StorageDead(_51); + StorageDead(_50); + StorageDead(_49); + goto -> bb37; + } + + bb32: { + StorageLive(_41); + _45 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); + _41 = Pin::<&T> { pointer: move _45 }; + StorageLive(_42); + _46 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); + _42 = Pin::<&U> { pointer: move _46 }; + StorageLive(_43); + _47 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); + _43 = Pin::<&T> { pointer: move _47 }; + StorageLive(_44); + _48 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); + _44 = Pin::<&U> { pointer: move _48 }; + _0 = const (); + StorageDead(_44); + StorageDead(_43); + StorageDead(_42); + StorageDead(_41); + goto -> bb37; + } + + bb33: { + StorageLive(_33); + _37 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); + _33 = Pin::<&T> { pointer: move _37 }; + StorageLive(_34); + _38 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); + _34 = Pin::<&U> { pointer: move _38 }; + StorageLive(_35); + _39 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); + _35 = Pin::<&T> { pointer: move _39 }; + StorageLive(_36); + _40 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); + _36 = Pin::<&U> { pointer: move _40 }; + _0 = const (); + StorageDead(_36); + StorageDead(_35); + StorageDead(_34); + StorageDead(_33); + goto -> bb37; + } + + bb34: { + StorageLive(_25); + _29 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); + _25 = Pin::<&T> { pointer: move _29 }; + StorageLive(_26); + _30 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); + _26 = Pin::<&U> { pointer: move _30 }; + StorageLive(_27); + _31 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); + _27 = Pin::<&T> { pointer: move _31 }; + StorageLive(_28); + _32 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); + _28 = Pin::<&U> { pointer: move _32 }; + _0 = const (); + StorageDead(_28); + StorageDead(_27); + StorageDead(_26); + StorageDead(_25); + goto -> bb37; + } + + bb35: { + StorageLive(_17); + _21 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); + _17 = Pin::<&T> { pointer: move _21 }; + StorageLive(_18); + _22 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); + _18 = Pin::<&U> { pointer: move _22 }; + StorageLive(_19); + _23 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); + _19 = Pin::<&T> { pointer: move _23 }; + StorageLive(_20); + _24 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); + _20 = Pin::<&U> { pointer: move _24 }; + _0 = const (); + StorageDead(_20); + StorageDead(_19); + StorageDead(_18); + StorageDead(_17); + goto -> bb37; + } + + bb36: { + StorageLive(_9); + _13 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); + _9 = Pin::<&T> { pointer: move _13 }; + StorageLive(_10); + _14 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); + _10 = Pin::<&U> { pointer: move _14 }; + StorageLive(_11); + _15 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); + _11 = Pin::<&T> { pointer: move _15 }; + StorageLive(_12); + _16 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); + _12 = Pin::<&U> { pointer: move _16 }; + _0 = const (); + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_9); + goto -> bb37; + } + + bb37: { + return; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir new file mode 100644 index 0000000000000..43c523cbf5717 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir @@ -0,0 +1,422 @@ +// MIR for `baz_baz_mut` after built + +fn baz_baz_mut(_1: Pin<&mut Baz, Baz>>) -> () { + debug baz => _1; + let mut _0: (); + let mut _2: isize; + let mut _3: isize; + let mut _4: isize; + let mut _5: isize; + let mut _6: isize; + let mut _7: isize; + let mut _8: isize; + let _9: std::pin::Pin<&mut T>; + let _10: std::pin::Pin<&mut U>; + let _11: std::pin::Pin<&mut T>; + let _12: std::pin::Pin<&mut U>; + let mut _13: &mut T; + let mut _14: &mut U; + let mut _15: &mut T; + let mut _16: &mut U; + let _17: std::pin::Pin<&mut T>; + let _18: std::pin::Pin<&mut U>; + let _19: std::pin::Pin<&mut T>; + let _20: std::pin::Pin<&mut U>; + let mut _21: &mut T; + let mut _22: &mut U; + let mut _23: &mut T; + let mut _24: &mut U; + let _25: std::pin::Pin<&mut T>; + let _26: std::pin::Pin<&mut U>; + let _27: std::pin::Pin<&mut T>; + let _28: std::pin::Pin<&mut U>; + let mut _29: &mut T; + let mut _30: &mut U; + let mut _31: &mut T; + let mut _32: &mut U; + let _33: std::pin::Pin<&mut T>; + let _34: std::pin::Pin<&mut U>; + let _35: std::pin::Pin<&mut T>; + let _36: std::pin::Pin<&mut U>; + let mut _37: &mut T; + let mut _38: &mut U; + let mut _39: &mut T; + let mut _40: &mut U; + let _41: std::pin::Pin<&mut T>; + let _42: std::pin::Pin<&mut U>; + let _43: std::pin::Pin<&mut T>; + let _44: std::pin::Pin<&mut U>; + let mut _45: &mut T; + let mut _46: &mut U; + let mut _47: &mut T; + let mut _48: &mut U; + let _49: std::pin::Pin<&mut T>; + let _50: std::pin::Pin<&mut U>; + let _51: std::pin::Pin<&mut T>; + let _52: std::pin::Pin<&mut U>; + let mut _53: &mut T; + let mut _54: &mut U; + let mut _55: &mut T; + let mut _56: &mut U; + let _57: std::pin::Pin<&mut T>; + let _58: std::pin::Pin<&mut U>; + let _59: std::pin::Pin<&mut T>; + let _60: std::pin::Pin<&mut U>; + let mut _61: &mut T; + let mut _62: &mut U; + let mut _63: &mut T; + let mut _64: &mut U; + let _65: std::pin::Pin<&mut T>; + let _66: std::pin::Pin<&mut U>; + let _67: std::pin::Pin<&mut T>; + let _68: std::pin::Pin<&mut U>; + let mut _69: &mut T; + let mut _70: &mut U; + let mut _71: &mut T; + let mut _72: &mut U; + scope 1 { + debug x => _9; + debug y => _10; + debug z => _11; + debug w => _12; + } + scope 2 { + debug x => _17; + debug y => _18; + debug z => _19; + debug w => _20; + } + scope 3 { + debug x => _25; + debug y => _26; + debug z => _27; + debug w => _28; + } + scope 4 { + debug x => _33; + debug y => _34; + debug z => _35; + debug w => _36; + } + scope 5 { + debug x => _41; + debug y => _42; + debug z => _43; + debug w => _44; + } + scope 6 { + debug x => _49; + debug y => _50; + debug z => _51; + debug w => _52; + } + scope 7 { + debug x => _57; + debug y => _58; + debug z => _59; + debug w => _60; + } + scope 8 { + debug x => _65; + debug y => _66; + debug z => _67; + debug w => _68; + } + + bb0: { + PlaceMention(_1); + _8 = discriminant((*(_1.0: &mut Baz, Baz>))); + switchInt(move _8) -> [0: bb2, 1: bb16, otherwise: bb1]; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb2: { + _4 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz)); + switchInt(move _4) -> [0: bb4, 1: bb10, otherwise: bb3]; + } + + bb3: { + goto -> bb1; + } + + bb4: { + _2 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz)); + switchInt(move _2) -> [0: bb6, 1: bb8, otherwise: bb5]; + } + + bb5: { + goto -> bb3; + } + + bb6: { + falseEdge -> [real: bb36, imaginary: bb8]; + } + + bb7: { + goto -> bb5; + } + + bb8: { + falseEdge -> [real: bb35, imaginary: bb10]; + } + + bb9: { + goto -> bb5; + } + + bb10: { + _3 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz)); + switchInt(move _3) -> [0: bb12, 1: bb14, otherwise: bb11]; + } + + bb11: { + goto -> bb3; + } + + bb12: { + falseEdge -> [real: bb34, imaginary: bb14]; + } + + bb13: { + goto -> bb11; + } + + bb14: { + falseEdge -> [real: bb33, imaginary: bb16]; + } + + bb15: { + goto -> bb11; + } + + bb16: { + _7 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz)); + switchInt(move _7) -> [0: bb18, 1: bb24, otherwise: bb17]; + } + + bb17: { + goto -> bb1; + } + + bb18: { + _5 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz)); + switchInt(move _5) -> [0: bb20, 1: bb22, otherwise: bb19]; + } + + bb19: { + goto -> bb17; + } + + bb20: { + falseEdge -> [real: bb32, imaginary: bb22]; + } + + bb21: { + goto -> bb19; + } + + bb22: { + falseEdge -> [real: bb31, imaginary: bb24]; + } + + bb23: { + goto -> bb19; + } + + bb24: { + _6 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz)); + switchInt(move _6) -> [0: bb26, 1: bb28, otherwise: bb25]; + } + + bb25: { + goto -> bb17; + } + + bb26: { + falseEdge -> [real: bb30, imaginary: bb28]; + } + + bb27: { + goto -> bb25; + } + + bb28: { + StorageLive(_65); + _69 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); + _65 = Pin::<&mut T> { pointer: move _69 }; + StorageLive(_66); + _70 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); + _66 = Pin::<&mut U> { pointer: move _70 }; + StorageLive(_67); + _71 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); + _67 = Pin::<&mut T> { pointer: move _71 }; + StorageLive(_68); + _72 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); + _68 = Pin::<&mut U> { pointer: move _72 }; + _0 = const (); + StorageDead(_68); + StorageDead(_67); + StorageDead(_66); + StorageDead(_65); + goto -> bb37; + } + + bb29: { + goto -> bb25; + } + + bb30: { + StorageLive(_57); + _61 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); + _57 = Pin::<&mut T> { pointer: move _61 }; + StorageLive(_58); + _62 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); + _58 = Pin::<&mut U> { pointer: move _62 }; + StorageLive(_59); + _63 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); + _59 = Pin::<&mut T> { pointer: move _63 }; + StorageLive(_60); + _64 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); + _60 = Pin::<&mut U> { pointer: move _64 }; + _0 = const (); + StorageDead(_60); + StorageDead(_59); + StorageDead(_58); + StorageDead(_57); + goto -> bb37; + } + + bb31: { + StorageLive(_49); + _53 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); + _49 = Pin::<&mut T> { pointer: move _53 }; + StorageLive(_50); + _54 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); + _50 = Pin::<&mut U> { pointer: move _54 }; + StorageLive(_51); + _55 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); + _51 = Pin::<&mut T> { pointer: move _55 }; + StorageLive(_52); + _56 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); + _52 = Pin::<&mut U> { pointer: move _56 }; + _0 = const (); + StorageDead(_52); + StorageDead(_51); + StorageDead(_50); + StorageDead(_49); + goto -> bb37; + } + + bb32: { + StorageLive(_41); + _45 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); + _41 = Pin::<&mut T> { pointer: move _45 }; + StorageLive(_42); + _46 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); + _42 = Pin::<&mut U> { pointer: move _46 }; + StorageLive(_43); + _47 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); + _43 = Pin::<&mut T> { pointer: move _47 }; + StorageLive(_44); + _48 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); + _44 = Pin::<&mut U> { pointer: move _48 }; + _0 = const (); + StorageDead(_44); + StorageDead(_43); + StorageDead(_42); + StorageDead(_41); + goto -> bb37; + } + + bb33: { + StorageLive(_33); + _37 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); + _33 = Pin::<&mut T> { pointer: move _37 }; + StorageLive(_34); + _38 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); + _34 = Pin::<&mut U> { pointer: move _38 }; + StorageLive(_35); + _39 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); + _35 = Pin::<&mut T> { pointer: move _39 }; + StorageLive(_36); + _40 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); + _36 = Pin::<&mut U> { pointer: move _40 }; + _0 = const (); + StorageDead(_36); + StorageDead(_35); + StorageDead(_34); + StorageDead(_33); + goto -> bb37; + } + + bb34: { + StorageLive(_25); + _29 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); + _25 = Pin::<&mut T> { pointer: move _29 }; + StorageLive(_26); + _30 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); + _26 = Pin::<&mut U> { pointer: move _30 }; + StorageLive(_27); + _31 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); + _27 = Pin::<&mut T> { pointer: move _31 }; + StorageLive(_28); + _32 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); + _28 = Pin::<&mut U> { pointer: move _32 }; + _0 = const (); + StorageDead(_28); + StorageDead(_27); + StorageDead(_26); + StorageDead(_25); + goto -> bb37; + } + + bb35: { + StorageLive(_17); + _21 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); + _17 = Pin::<&mut T> { pointer: move _21 }; + StorageLive(_18); + _22 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); + _18 = Pin::<&mut U> { pointer: move _22 }; + StorageLive(_19); + _23 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); + _19 = Pin::<&mut T> { pointer: move _23 }; + StorageLive(_20); + _24 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); + _20 = Pin::<&mut U> { pointer: move _24 }; + _0 = const (); + StorageDead(_20); + StorageDead(_19); + StorageDead(_18); + StorageDead(_17); + goto -> bb37; + } + + bb36: { + StorageLive(_9); + _13 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); + _9 = Pin::<&mut T> { pointer: move _13 }; + StorageLive(_10); + _14 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); + _10 = Pin::<&mut U> { pointer: move _14 }; + StorageLive(_11); + _15 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); + _11 = Pin::<&mut T> { pointer: move _15 }; + StorageLive(_12); + _16 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); + _12 = Pin::<&mut U> { pointer: move _16 }; + _0 = const (); + StorageDead(_12); + StorageDead(_11); + StorageDead(_10); + StorageDead(_9); + goto -> bb37; + } + + bb37: { + return; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir new file mode 100644 index 0000000000000..5538449cc43cc --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir @@ -0,0 +1,76 @@ +// MIR for `baz_const` after built + +fn baz_const(_1: Pin<&Baz>) -> () { + debug baz => _1; + let mut _0: (); + let mut _2: isize; + let _3: std::pin::Pin<&T>; + let _4: std::pin::Pin<&U>; + let mut _5: &T; + let mut _6: &U; + let _7: std::pin::Pin<&T>; + let _8: std::pin::Pin<&U>; + let mut _9: &T; + let mut _10: &U; + scope 1 { + debug x => _3; + debug y => _4; + } + scope 2 { + debug x => _7; + debug y => _8; + } + + bb0: { + PlaceMention(_1); + _2 = discriminant((*(_1.0: &Baz))); + switchInt(move _2) -> [0: bb2, 1: bb4, otherwise: bb1]; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb2: { + falseEdge -> [real: bb6, imaginary: bb4]; + } + + bb3: { + goto -> bb1; + } + + bb4: { + StorageLive(_7); + _9 = &(((*(_1.0: &Baz)) as Bar).0: T); + _7 = Pin::<&T> { pointer: move _9 }; + StorageLive(_8); + _10 = &(((*(_1.0: &Baz)) as Bar).1: U); + _8 = Pin::<&U> { pointer: move _10 }; + _0 = const (); + StorageDead(_8); + StorageDead(_7); + goto -> bb7; + } + + bb5: { + goto -> bb1; + } + + bb6: { + StorageLive(_3); + _5 = &(((*(_1.0: &Baz)) as Foo).0: T); + _3 = Pin::<&T> { pointer: move _5 }; + StorageLive(_4); + _6 = &(((*(_1.0: &Baz)) as Foo).1: U); + _4 = Pin::<&U> { pointer: move _6 }; + _0 = const (); + StorageDead(_4); + StorageDead(_3); + goto -> bb7; + } + + bb7: { + return; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir new file mode 100644 index 0000000000000..4ae472cba3a58 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir @@ -0,0 +1,76 @@ +// MIR for `baz_mut` after built + +fn baz_mut(_1: Pin<&mut Baz>) -> () { + debug baz => _1; + let mut _0: (); + let mut _2: isize; + let _3: std::pin::Pin<&mut T>; + let _4: std::pin::Pin<&mut U>; + let mut _5: &mut T; + let mut _6: &mut U; + let _7: std::pin::Pin<&mut T>; + let _8: std::pin::Pin<&mut U>; + let mut _9: &mut T; + let mut _10: &mut U; + scope 1 { + debug x => _3; + debug y => _4; + } + scope 2 { + debug x => _7; + debug y => _8; + } + + bb0: { + PlaceMention(_1); + _2 = discriminant((*(_1.0: &mut Baz))); + switchInt(move _2) -> [0: bb2, 1: bb4, otherwise: bb1]; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb2: { + falseEdge -> [real: bb6, imaginary: bb4]; + } + + bb3: { + goto -> bb1; + } + + bb4: { + StorageLive(_7); + _9 = &mut (((*(_1.0: &mut Baz)) as Bar).0: T); + _7 = Pin::<&mut T> { pointer: move _9 }; + StorageLive(_8); + _10 = &mut (((*(_1.0: &mut Baz)) as Bar).1: U); + _8 = Pin::<&mut U> { pointer: move _10 }; + _0 = const (); + StorageDead(_8); + StorageDead(_7); + goto -> bb7; + } + + bb5: { + goto -> bb1; + } + + bb6: { + StorageLive(_3); + _5 = &mut (((*(_1.0: &mut Baz)) as Foo).0: T); + _3 = Pin::<&mut T> { pointer: move _5 }; + StorageLive(_4); + _6 = &mut (((*(_1.0: &mut Baz)) as Foo).1: U); + _4 = Pin::<&mut U> { pointer: move _6 }; + _0 = const (); + StorageDead(_4); + StorageDead(_3); + goto -> bb7; + } + + bb7: { + return; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir new file mode 100644 index 0000000000000..8b397ffd18142 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir @@ -0,0 +1,47 @@ +// MIR for `foo_bar_const` after built + +fn foo_bar_const(_1: Pin<&Foo, Bar>>) -> () { + debug foo => _1; + let mut _0: (); + let _2: std::pin::Pin<&T>; + let _3: std::pin::Pin<&U>; + let _4: std::pin::Pin<&T>; + let _5: std::pin::Pin<&U>; + let mut _6: &T; + let mut _7: &U; + let mut _8: &T; + let mut _9: &U; + scope 1 { + debug x => _2; + debug y => _3; + debug z => _4; + debug w => _5; + } + + bb0: { + PlaceMention(_1); + StorageLive(_2); + _6 = &(((*(_1.0: &Foo, Bar>)).0: Bar).0: T); + _2 = Pin::<&T> { pointer: move _6 }; + StorageLive(_3); + _7 = &(((*(_1.0: &Foo, Bar>)).0: Bar).1: U); + _3 = Pin::<&U> { pointer: move _7 }; + StorageLive(_4); + _8 = &(((*(_1.0: &Foo, Bar>)).1: Bar).0: T); + _4 = Pin::<&T> { pointer: move _8 }; + StorageLive(_5); + _9 = &(((*(_1.0: &Foo, Bar>)).1: Bar).1: U); + _5 = Pin::<&U> { pointer: move _9 }; + _0 = const (); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + return; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir new file mode 100644 index 0000000000000..2e8128bb9d1e4 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir @@ -0,0 +1,47 @@ +// MIR for `foo_bar_mut` after built + +fn foo_bar_mut(_1: Pin<&mut Foo, Bar>>) -> () { + debug foo => _1; + let mut _0: (); + let _2: std::pin::Pin<&mut T>; + let _3: std::pin::Pin<&mut U>; + let _4: std::pin::Pin<&mut T>; + let _5: std::pin::Pin<&mut U>; + let mut _6: &mut T; + let mut _7: &mut U; + let mut _8: &mut T; + let mut _9: &mut U; + scope 1 { + debug x => _2; + debug y => _3; + debug z => _4; + debug w => _5; + } + + bb0: { + PlaceMention(_1); + StorageLive(_2); + _6 = &mut (((*(_1.0: &mut Foo, Bar>)).0: Bar).0: T); + _2 = Pin::<&mut T> { pointer: move _6 }; + StorageLive(_3); + _7 = &mut (((*(_1.0: &mut Foo, Bar>)).0: Bar).1: U); + _3 = Pin::<&mut U> { pointer: move _7 }; + StorageLive(_4); + _8 = &mut (((*(_1.0: &mut Foo, Bar>)).1: Bar).0: T); + _4 = Pin::<&mut T> { pointer: move _8 }; + StorageLive(_5); + _9 = &mut (((*(_1.0: &mut Foo, Bar>)).1: Bar).1: U); + _5 = Pin::<&mut U> { pointer: move _9 }; + _0 = const (); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + return; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir new file mode 100644 index 0000000000000..b77b341d4ef76 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir @@ -0,0 +1,33 @@ +// MIR for `foo_const` after built + +fn foo_const(_1: Pin<&Foo>) -> () { + debug foo => _1; + let mut _0: (); + let _2: std::pin::Pin<&T>; + let _3: std::pin::Pin<&U>; + let mut _4: &T; + let mut _5: &U; + scope 1 { + debug x => _2; + debug y => _3; + } + + bb0: { + PlaceMention(_1); + StorageLive(_2); + _4 = &((*(_1.0: &Foo)).0: T); + _2 = Pin::<&T> { pointer: move _4 }; + StorageLive(_3); + _5 = &((*(_1.0: &Foo)).1: U); + _3 = Pin::<&U> { pointer: move _5 }; + _0 = const (); + StorageDead(_3); + StorageDead(_2); + return; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir new file mode 100644 index 0000000000000..c7b88d239f87a --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir @@ -0,0 +1,33 @@ +// MIR for `foo_mut` after built + +fn foo_mut(_1: Pin<&mut Foo>) -> () { + debug foo => _1; + let mut _0: (); + let _2: std::pin::Pin<&mut T>; + let _3: std::pin::Pin<&mut U>; + let mut _4: &mut T; + let mut _5: &mut U; + scope 1 { + debug x => _2; + debug y => _3; + } + + bb0: { + PlaceMention(_1); + StorageLive(_2); + _4 = &mut ((*(_1.0: &mut Foo)).0: T); + _2 = Pin::<&mut T> { pointer: move _4 }; + StorageLive(_3); + _5 = &mut ((*(_1.0: &mut Foo)).1: U); + _3 = Pin::<&mut U> { pointer: move _5 }; + _0 = const (); + StorageDead(_3); + StorageDead(_2); + return; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } +} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.rs b/tests/mir-opt/pin-ergonomics/project_pattern_match.rs new file mode 100644 index 0000000000000..8808111f303b3 --- /dev/null +++ b/tests/mir-opt/pin-ergonomics/project_pattern_match.rs @@ -0,0 +1,95 @@ +// skip-filecheck +#![feature(pin_ergonomics)] +#![allow(incomplete_features)] + +// This test verifies that a `&pin mut Foo` can be projected to a pinned +// reference `&pin mut T` of a `?Unpin` field , and can be projected to +// an unpinned reference `&mut U` of an `Unpin` field . + +struct Foo { + x: T, + y: U, +} + +struct Bar(T, U); + +enum Baz { + Foo(T, U), + Bar { x: T, y: U }, +} + +// EMIT_MIR project_pattern_match.foo_mut.built.after.mir +fn foo_mut(foo: &pin mut Foo) { + let Foo { x, y } = foo; +} + +// EMIT_MIR project_pattern_match.foo_const.built.after.mir +fn foo_const(foo: &pin const Foo) { + let Foo { x, y } = foo; +} + +// EMIT_MIR project_pattern_match.bar_mut.built.after.mir +fn bar_mut(bar: &pin mut Bar) { + let Bar(x, y) = bar; +} + +// EMIT_MIR project_pattern_match.bar_const.built.after.mir +fn bar_const(bar: &pin const Bar) { + let Bar(x, y) = bar; +} + +// EMIT_MIR project_pattern_match.foo_bar_mut.built.after.mir +fn foo_bar_mut(foo: &pin mut Foo, Bar>) { + let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; +} + +// EMIT_MIR project_pattern_match.foo_bar_const.built.after.mir +fn foo_bar_const(foo: &pin const Foo, Bar>) { + let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; +} + +// EMIT_MIR project_pattern_match.baz_mut.built.after.mir +fn baz_mut(baz: &pin mut Baz) { + match baz { + Baz::Foo(x, y) => {} + Baz::Bar { x, y } => {} + } +} + +// EMIT_MIR project_pattern_match.baz_const.built.after.mir +fn baz_const(baz: &pin const Baz) { + match baz { + Baz::Foo(x, y) => {} + Baz::Bar { x, y } => {} + } +} + +// EMIT_MIR project_pattern_match.baz_baz_mut.built.after.mir +fn baz_baz_mut(baz: &pin mut Baz, Baz>) { + match baz { + Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w)) => {} + Baz::Foo(Baz::Foo(x, y), Baz::Bar { x: z, y: w }) => {} + Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w)) => {} + Baz::Foo(Baz::Bar { x, y }, Baz::Bar { x: z, y: w }) => {} + Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) } => {} + Baz::Bar { x: Baz::Foo(x, y), y: Baz::Bar { x: z, y: w } } => {} + Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) } => {} + Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Bar { x: z, y: w } } => {} + } +} + +// EMIT_MIR project_pattern_match.baz_baz_const.built.after.mir +fn baz_baz_const(baz: &pin const Baz, Baz>) { + match baz { + Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w)) => {} + Baz::Foo(Baz::Foo(x, y), Baz::Bar { x: z, y: w }) => {} + Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w)) => {} + Baz::Foo(Baz::Bar { x, y }, Baz::Bar { x: z, y: w }) => {} + Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) } => {} + Baz::Bar { x: Baz::Foo(x, y), y: Baz::Bar { x: z, y: w } } => {} + Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) } => {} + Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Bar { x: z, y: w } } => {} + } +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs new file mode 100644 index 0000000000000..23d29e6f9dae4 --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs @@ -0,0 +1,91 @@ +//@ revisions: pin_ergonomics normal +//@ edition:2024 +//@ check-pass +// //@[normal] check-pass +// //@[pin_ergonomics] rustc-env:RUSTC_LOG=rustc_hir_typeck::expr_use_visitor=DEBUG +#![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] +#![feature(deref_patterns)] +#![allow(incomplete_features)] + +// This test verifies that the `pin_ergonomics` feature works well +// together with the `deref_patterns` feature. + +use std::pin::Pin; + +struct Foo { + x: T, + y: U, +} + +struct Bar(T, U); + +enum Baz { + Foo(T, U), + Bar { x: T, y: U }, +} + +fn foo_mut(foo: Pin<&mut Foo>) { + let Foo { .. } = foo; + let Pin { .. } = foo; + let _ = || { + let Foo { .. } = foo; + let Pin { .. } = foo; + }; + + #[cfg(pin_ergonomics)] + let Foo { x, y } = foo; + #[cfg(pin_ergonomics)] + let _ = || { + let Foo { x, y } = foo; + }; +} + +fn foo_const(foo: Pin<&Foo>) { + let Foo { .. } = foo; + let Pin { .. } = foo; + let _ = || { + let Foo { .. } = foo; + let Pin { .. } = foo; + }; + + #[cfg(pin_ergonomics)] + let Foo { x, y } = foo; + #[cfg(pin_ergonomics)] + let _ = || { + let Foo { x, y } = foo; + }; +} + +fn bar_mut(bar: Pin<&mut Bar>) { + let Bar(..) = bar; + let Pin { .. } = bar; + let _ = || { + let Bar(..) = bar; + let Pin { .. } = bar; + }; + + #[cfg(pin_ergonomics)] + let Bar(x, y) = bar; + #[cfg(pin_ergonomics)] + let _ = || { + let Bar(x, y) = bar; + }; +} + +fn bar_const(bar: Pin<&Bar>) { + let Bar(..) = bar; + let Pin { .. } = bar; + let _ = || { + let Bar(..) = bar; + let Pin { .. } = bar; + }; + + #[cfg(pin_ergonomics)] + let Bar(x, y) = bar; + #[cfg(pin_ergonomics)] + let _ = || { + let Bar(x, y) = bar; + }; +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr new file mode 100644 index 0000000000000..2389fe9ed98cd --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr @@ -0,0 +1,66 @@ +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:31:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:49:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:53:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:71:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:75:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:93:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:97:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr new file mode 100644 index 0000000000000..f23e5cf72a45e --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr @@ -0,0 +1,130 @@ +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:37:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:31:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:42:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:49:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:59:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:53:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:64:9 + | +LL | Foo { .. } => {} + | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:71:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:81:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:75:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:86:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:93:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:103:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:97:9 + | +LL | Bar(..) => {} + | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:108:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: aborting due to 16 previous errors + diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs new file mode 100644 index 0000000000000..c5ba9dbeb2e6e --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs @@ -0,0 +1,113 @@ +//@ revisions: pin_ergonomics normal +//@ edition:2024 +#![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] +#![feature(deref_patterns)] +#![allow(incomplete_features)] + +// This test verifies that the `pin_ergonomics` feature works well +// together with the `deref_patterns` feature under the error: +// "mix of deref patterns and normal constructors". + +use std::pin::Pin; + +struct Foo { + x: T, + y: U, +} + +struct Bar(T, U); + +enum Baz { + Foo(T, U), + Bar { x: T, y: U }, +} + +fn foo_mut(foo: Pin<&mut Foo>) { + match foo { + Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + let _ = || match foo { + Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; + + #[cfg(pin_ergonomics)] + match foo { + Foo { x, y } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + #[cfg(pin_ergonomics)] + let _ = || match foo { + Foo { .. } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; +} + +fn foo_const(foo: Pin<&Foo>) { + match foo { + Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + let _ = || match foo { + Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; + + #[cfg(pin_ergonomics)] + match foo { + Foo { x, y } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + #[cfg(pin_ergonomics)] + let _ = || match foo { + Foo { .. } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; +} + +fn bar_mut(bar: Pin<&mut Bar>) { + match bar { + Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + let _ = || match bar { + Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; + + #[cfg(pin_ergonomics)] + match bar { + Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + #[cfg(pin_ergonomics)] + let _ = || match bar { + Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; +} + +fn bar_const(bar: Pin<&Bar>) { + match bar { + Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + let _ = || match bar { + Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; + + #[cfg(pin_ergonomics)] + match bar { + Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + } + #[cfg(pin_ergonomics)] + let _ = || match bar { + Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Pin { .. } => {} + }; +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr new file mode 100644 index 0000000000000..7aaa51e81ed90 --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr @@ -0,0 +1,313 @@ +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:35:9 + | +LL | let Foo { x, y } = foo; + | ^^^^^^^^^^^^ --- this expression has type `Pin<&mut Foo>` + | | + | expected `Pin<&mut Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&mut Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Foo { x, y } = *foo; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:42:9 + | +LL | let Foo { x, y } = foo; + | ^^^^^^^^^^^^ --- this expression has type `Pin<&Foo>` + | | + | expected `Pin<&Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Foo { x, y } = *foo; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:49:9 + | +LL | let Bar(x, y) = bar; + | ^^^^^^^^^ --- this expression has type `Pin<&mut Bar>` + | | + | expected `Pin<&mut Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&mut Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Bar(x, y) = *bar; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:56:9 + | +LL | let Bar(x, y) = bar; + | ^^^^^^^^^ --- this expression has type `Pin<&Bar>` + | | + | expected `Pin<&Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Bar(x, y) = *bar; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:63:9 + | +LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- this expression has type `Pin<&mut Foo, Bar>>` + | | + | expected `Pin<&mut Foo, Bar>>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&mut Foo, Bar>>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = *foo; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:72:9 + | +LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- this expression has type `Pin<&Foo, Bar>>` + | | + | expected `Pin<&Foo, Bar>>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&Foo, Bar>>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = *foo; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:82:9 + | +LL | match baz { + | --- this expression has type `Pin<&mut Baz>` +LL | Baz::Foo(x, y) => { + | ^^^^^^^^^^^^^^ expected `Pin<&mut Baz>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&mut Baz>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:87:9 + | +LL | match baz { + | --- this expression has type `Pin<&mut Baz>` +... +LL | Baz::Bar { x, y } => { + | ^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&mut Baz>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:97:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz>` +LL | Baz::Foo(x, y) => { + | ^^^^^^^^^^^^^^ expected `Pin<&Baz>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:102:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz>` +... +LL | Baz::Bar { x, y } => { + | ^^^^^^^^^^^^^^^^^ expected `Pin<&Baz>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:112:9 + | +LL | match baz { + | --- this expression has type `Pin<&mut Baz, Baz>>` +LL | Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&mut Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:119:9 + | +LL | match baz { + | --- this expression has type `Pin<&mut Baz, Baz>>` +... +LL | Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&mut Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:126:9 + | +LL | match baz { + | --- this expression has type `Pin<&mut Baz, Baz>>` +... +LL | Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&mut Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:133:9 + | +LL | match baz { + | --- this expression has type `Pin<&mut Baz, Baz>>` +... +LL | Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&mut Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:145:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz, Baz>>` +LL | Baz::Foo(foo, _) if let Baz::Foo(x, y) = foo => { + | ^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:150:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz, Baz>>` +... +LL | Baz::Bar { x: _, y: bar } if let Baz::Bar { x, y } = bar => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:155:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz, Baz>>` +... +LL | Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:162:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz, Baz>>` +... +LL | Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:169:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz, Baz>>` +... +LL | Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:176:9 + | +LL | match baz { + | --- this expression has type `Pin<&Baz, Baz>>` +... +LL | Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` + | + = note: expected struct `Pin<&Baz, Baz>>` + found enum `Baz<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *baz { + | + + +error: aborting due to 20 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching.rs b/tests/ui/pin-ergonomics/pattern-matching.rs new file mode 100644 index 0000000000000..e480ebfc00626 --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching.rs @@ -0,0 +1,186 @@ +//@ revisions: pin_ergonomics normal +//@ edition:2024 +//@[pin_ergonomics] check-pass +#![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] +#![feature(if_let_guard)] +#![allow(incomplete_features)] + +use std::pin::Pin; + +// This test verifies that a `&pin mut Foo` can be projected to a pinned +// reference `&pin mut T` of a `?Unpin` field , and can be projected to +// an unpinned reference `&mut U` of an `Unpin` field. + +struct Foo { + x: T, + y: U, +} + +struct Bar(T, U); + +enum Baz { + Foo(T, U), + Bar { x: T, y: U }, +} + +trait IsPinMut {} +trait IsPinConst {} +impl IsPinMut for Pin<&mut T> {} +impl IsPinConst for Pin<&T> {} + +fn assert_pin_mut(_: T) {} +fn assert_pin_const(_: T) {} + +fn foo_mut(foo: Pin<&mut Foo>) { + let Foo { x, y } = foo; + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); +} + +fn foo_const(foo: Pin<&Foo>) { + let Foo { x, y } = foo; + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); +} + +fn bar_mut(bar: Pin<&mut Bar>) { + let Bar(x, y) = bar; + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); +} + +fn bar_const(bar: Pin<&Bar>) { + let Bar(x, y) = bar; + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); +} + +fn foo_bar_mut(foo: Pin<&mut Foo, Bar>>) { + let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + assert_pin_mut(z); + assert_pin_mut(w); +} + +fn foo_bar_const(foo: Pin<&Foo, Bar>>) { + let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + assert_pin_const(z); + assert_pin_const(w); +} + +fn baz_mut(baz: Pin<&mut Baz>) { + match baz { + Baz::Foo(x, y) => { + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + } + Baz::Bar { x, y } => { + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + } + } +} + +fn baz_const(baz: Pin<&Baz>) { + match baz { + Baz::Foo(x, y) => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + } + Baz::Bar { x, y } => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + } + } +} + +fn baz_baz_mut(baz: Pin<&mut Baz, Baz>>) { + match baz { + Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + assert_pin_mut(z); + assert_pin_mut(w); + } + Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + assert_pin_mut(z); + assert_pin_mut(w); + } + Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + assert_pin_mut(z); + assert_pin_mut(w); + } + Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + assert_pin_mut(z); + assert_pin_mut(w); + } + } +} + +fn baz_baz_const(baz: Pin<&Baz, Baz>>) { + match baz { + Baz::Foo(foo, _) if let Baz::Foo(x, y) = foo => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + } + Baz::Bar { x: _, y: bar } if let Baz::Bar { x, y } = bar => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + } + Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + assert_pin_const(z); + assert_pin_const(w); + } + Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + assert_pin_const(z); + assert_pin_const(w); + } + Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + assert_pin_const(z); + assert_pin_const(w); + } + Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); + assert_pin_const(z); + assert_pin_const(w); + } + } +} + +fn main() {} From 9fc1d8aa3b45adaf310601b7ea28f59fdc3573e2 Mon Sep 17 00:00:00 2001 From: Frank King Date: Sat, 19 Jul 2025 21:54:05 +0800 Subject: [PATCH 13/45] require `T: !Unpin` for `&pin mut T` to be projected to `&pin mut T.U` where `U: ?Unpin` --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 25 +- compiler/rustc_hir_typeck/src/pat.rs | 210 ++++++--- compiler/rustc_middle/src/ty/sty.rs | 10 + .../rustc_middle/src/ty/typeck_results.rs | 26 ++ .../rustc_pattern_analysis/src/constructor.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 76 +++- .../src/traits/select/confirmation.rs | 5 + .../src/traits/select/mod.rs | 52 ++- ...ct_pattern_match.bar_const.built.after.mir | 33 -- ...ject_pattern_match.bar_mut.built.after.mir | 33 -- ...attern_match.baz_baz_const.built.after.mir | 422 ------------------ ..._pattern_match.baz_baz_mut.built.after.mir | 422 ------------------ ...ct_pattern_match.baz_const.built.after.mir | 76 ---- ...ject_pattern_match.baz_mut.built.after.mir | 76 ---- ...attern_match.foo_bar_const.built.after.mir | 47 -- ..._pattern_match.foo_bar_mut.built.after.mir | 47 -- ...ct_pattern_match.foo_const.built.after.mir | 33 -- ...ject_pattern_match.foo_mut.built.after.mir | 33 -- .../pin-ergonomics/project_pattern_match.rs | 95 ---- .../pattern-matching.normal.stderr | 327 +++++--------- tests/ui/pin-ergonomics/pattern-matching.rs | 186 ++++---- .../pin-ergonomics/projection-unpin-checks.rs | 132 ++++++ .../projection-unpin-checks.stderr | 333 ++++++++++++++ 23 files changed, 999 insertions(+), 1702 deletions(-) delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir delete mode 100644 tests/mir-opt/pin-ergonomics/project_pattern_match.rs create mode 100644 tests/ui/pin-ergonomics/projection-unpin-checks.rs create mode 100644 tests/ui/pin-ergonomics/projection-unpin-checks.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index dde6b8ce9b8b2..ec67efe6399e3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -23,7 +23,7 @@ use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity, - SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, + SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, Upcast, UserArgs, UserSelfTy, }; use rustc_middle::{bug, span_bug}; @@ -464,6 +464,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub(crate) fn register_negative_bound( + &self, + ty: Ty<'tcx>, + def_id: DefId, + cause: traits::ObligationCause<'tcx>, + ) { + if !ty.references_error() { + let trait_ref = ty::TraitRef::new(self.tcx, def_id, [ty]); + let predicate = + ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative } + .upcast(self.tcx); + self.fulfillment_cx.borrow_mut().register_predicate_obligation( + self, + traits::Obligation { + cause, + recursion_depth: 0, + param_env: self.param_env, + predicate, + }, + ); + } + } + pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> { let ty = self.lowerer().lower_ty(hir_ty); self.register_wf_obligation(ty.into(), hir_ty.span, ObligationCauseCode::WellFormed(None)); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index d2b3041ad7e1a..3a6b11653c031 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -27,7 +27,7 @@ use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym}; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode}; +use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt}; use tracing::{debug, instrument, trace}; use ty::VariantDef; use ty::adjustment::{PatAdjust, PatAdjustment}; @@ -403,19 +403,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.check_pat_inner(pat, opt_path_res, adjust_mode, expected, pat_info); self.write_ty(pat.hir_id, ty); - // If we implicitly inserted overloaded dereferences before matching, check the pattern to - // see if the dereferenced types need `DerefMut` bounds. - if let Some(derefed_tys) = self.typeck_results.borrow().pat_adjustments().get(pat.hir_id) - && derefed_tys.iter().any(|adjust| adjust.kind == PatAdjust::OverloadedDeref) - { - self.register_deref_mut_bounds_if_needed( - pat.span, - pat, - derefed_tys.iter().filter_map(|adjust| match adjust.kind { - PatAdjust::OverloadedDeref => Some(adjust.source), - PatAdjust::BuiltinDeref | PatAdjust::PinDeref => None, - }), - ); + // If we implicitly inserted overloaded dereferences and pinned dereferences before matching, + // check the pattern to see if the dereferenced types need `DerefMut` or `!Unpin` bounds. + if let Some(derefed_tys) = self.typeck_results.borrow().pat_adjustments().get(pat.hir_id) { + let mut has_overloaded_deref = false; + let mut has_pin_deref = false; + derefed_tys.iter().for_each(|adjust| match adjust.kind { + PatAdjust::BuiltinDeref => {} + PatAdjust::OverloadedDeref => has_overloaded_deref = true, + PatAdjust::PinDeref => has_pin_deref = true, + }); + if has_overloaded_deref { + self.register_deref_mut_bounds_if_needed( + pat.span, + pat, + derefed_tys.iter().filter_map(|adjust| match adjust.kind { + PatAdjust::OverloadedDeref => Some(adjust.source), + PatAdjust::BuiltinDeref | PatAdjust::PinDeref => None, + }), + ); + } + if has_pin_deref { + self.register_not_unpin_bounds_if_needed( + pat.span, + pat, + derefed_tys.iter().filter_map(|adjust| match adjust.kind { + PatAdjust::BuiltinDeref | PatAdjust::OverloadedDeref => None, + PatAdjust::PinDeref => { + Some(adjust.source.pinned_ref().expect("expected pinned reference").0) + } + }), + ); + } } // (note_1): In most of the cases where (note_1) is referenced @@ -553,13 +572,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let &ty::Ref(_, inner_ty, inner_mutability) = pinned_ty.kind() => { debug!("scrutinee ty {expected:?} is a pinned reference, inserting pin deref"); - // Preserve the pinned type. We'll need it later during THIR lowering. - self.typeck_results - .borrow_mut() - .pat_adjustments_mut() - .entry(pat.hir_id) - .or_default() - .push(PatAdjustment { kind: PatAdjust::PinDeref, source: expected }); let binding_mode = adjust_binding_mode(Pinnedness::Pinned, inner_mutability); // If the pinnedness is `Not`, it means the pattern is unpinned @@ -569,14 +581,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inner_ty, self.tcx.require_lang_item(hir::LangItem::Unpin, pat.span), self.misc(pat.span), - ); + ) } + // Once we've checked `pat`, we'll add a `!Unpin` bound if it contains any + // `ref pin` bindings. See `Self::register_not_unpin_bounds_if_needed`. + + debug!("default binding mode is now {:?}", binding_mode); + // Use the old pat info to keep `current_depth` to its old value. let new_pat_info = PatInfo { binding_mode, ..old_pat_info }; - // Recurse with the new expected type. - // using `break` instead of `return` in case where any shared codes are added - // after the `match pat.kind {}`. - self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, new_pat_info) + + self.check_deref_pattern( + pat, + opt_path_res, + adjust_mode, + expected, + inner_ty, + PatAdjust::PinDeref, + new_pat_info, + ) } // If `deref_patterns` is enabled, peel a smart pointer from the scrutinee type. See the // examples in `tests/ui/pattern/deref_patterns/`. @@ -585,35 +608,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && pat.default_binding_modes && self.should_peel_smart_pointer(peel_kind, expected) => { - debug!("scrutinee ty {expected:?} is a smart pointer, inserting overloaded deref"); + debug!("scrutinee ty {expected:?} is a smart pointer, inserting pin deref"); + // The scrutinee is a smart pointer; implicitly dereference it. This adds a // requirement that `expected: DerefPure`. - let mut inner_ty = self.deref_pat_target(pat.span, expected); + let inner_ty = self.deref_pat_target(pat.span, expected); // Once we've checked `pat`, we'll add a `DerefMut` bound if it contains any // `ref mut` bindings. See `Self::register_deref_mut_bounds_if_needed`. - let mut typeck_results = self.typeck_results.borrow_mut(); - let mut pat_adjustments_table = typeck_results.pat_adjustments_mut(); - let pat_adjustments = pat_adjustments_table.entry(pat.hir_id).or_default(); - // We may reach the recursion limit if a user matches on a type `T` satisfying - // `T: Deref`; error gracefully in this case. - // FIXME(deref_patterns): If `deref_patterns` stabilizes, it may make sense to move - // this check out of this branch. Alternatively, this loop could be implemented with - // autoderef and this check removed. For now though, don't break code compiling on - // stable with lots of `&`s and a low recursion limit, if anyone's done that. - if self.tcx.recursion_limit().value_within_limit(pat_adjustments.len()) { - // Preserve the smart pointer type for THIR lowering and closure upvar analysis. - pat_adjustments - .push(PatAdjustment { kind: PatAdjust::OverloadedDeref, source: expected }); - } else { - let guar = report_autoderef_recursion_limit_error(self.tcx, pat.span, expected); - inner_ty = Ty::new_error(self.tcx, guar); - } - drop(typeck_results); - - // Recurse, using the old pat info to keep `current_depth` to its old value. - // Peeling smart pointers does not update the default binding mode. - self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, old_pat_info) + self.check_deref_pattern( + pat, + opt_path_res, + adjust_mode, + expected, + inner_ty, + PatAdjust::OverloadedDeref, + old_pat_info, + ) } PatKind::Missing | PatKind::Wild | PatKind::Err(_) => expected, // We allow any type here; we ensure that the type is uninhabited during match checking. @@ -692,6 +703,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn check_deref_pattern( + &self, + pat: &'tcx Pat<'tcx>, + opt_path_res: Option, ErrorGuaranteed>>, + adjust_mode: AdjustMode, + expected: Ty<'tcx>, + mut inner_ty: Ty<'tcx>, + pat_adjust_kind: PatAdjust, + pat_info: PatInfo<'tcx>, + ) -> Ty<'tcx> { + debug_assert!( + !matches!(pat_adjust_kind, PatAdjust::BuiltinDeref), + "unexpected deref pattern for builtin reference type {expected:?}", + ); + + let mut typeck_results = self.typeck_results.borrow_mut(); + let mut pat_adjustments_table = typeck_results.pat_adjustments_mut(); + let pat_adjustments = pat_adjustments_table.entry(pat.hir_id).or_default(); + // We may reach the recursion limit if a user matches on a type `T` satisfying + // `T: Deref`; error gracefully in this case. + // FIXME(deref_patterns): If `deref_patterns` stabilizes, it may make sense to move + // this check out of this branch. Alternatively, this loop could be implemented with + // autoderef and this check removed. For now though, don't break code compiling on + // stable with lots of `&`s and a low recursion limit, if anyone's done that. + if self.tcx.recursion_limit().value_within_limit(pat_adjustments.len()) { + // Preserve the smart pointer type for THIR lowering and closure upvar analysis. + pat_adjustments.push(PatAdjustment { kind: pat_adjust_kind, source: expected }); + } else { + let guar = report_autoderef_recursion_limit_error(self.tcx, pat.span, expected); + inner_ty = Ty::new_error(self.tcx, guar); + } + drop(typeck_results); + + // Recurse, using the old pat info to keep `current_depth` to its old value. + // Peeling smart pointers does not update the default binding mode. + self.check_pat_inner(pat, opt_path_res, adjust_mode, inner_ty, pat_info) + } + /// How should the binding mode and expected type be adjusted? /// /// When the pattern contains a path, `opt_path_res` must be `Some(path_res)`. @@ -2630,6 +2679,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Check if the interior of a pin pattern (either explicit or implicit) has any `ref pin` + /// bindings of non-`Unpin` types, which would require `!Unpin` to be emitted. + fn register_not_unpin_bounds_if_needed( + &self, + span: Span, + inner: &'tcx Pat<'tcx>, + derefed_tys: impl IntoIterator>, + ) { + // Check if there are subpatterns with `ref pin` binding modes of non-`Unpin` types. + let unpin = self.tcx.require_lang_item(hir::LangItem::Unpin, span); + let cause = self.misc(span); + let unpin_obligations = self.probe(|_| { + let ocx = ObligationCtxt::new(&self); + self.typeck_results.borrow().pat_walk_ref_pin_binding_of_non_unpin_type(inner, |ty| { + let ty = ocx + .normalize(&cause, self.param_env, ty) + .pinned_ref() + .expect("expect pinned reference") + .0; + debug!("check if `Unpin` is implemented for `{ty:?}`"); + ocx.register_bound(cause.clone(), self.param_env, ty, unpin); + }); + ocx.select_all_or_error() + }); + + // If any, the current pattern type should implement `!Unpin`. + if !unpin_obligations.is_empty() { + for pinned_derefed_ty in derefed_tys { + debug!("register `!Unpin` for `{pinned_derefed_ty:?}`"); + self.register_negative_bound( + pinned_derefed_ty, + self.tcx.require_lang_item(hir::LangItem::Unpin, span), + self.misc(span), + ); + } + } + } + // Precondition: Pat is Ref(inner) fn check_pat_ref( &self, @@ -2656,7 +2743,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected = self.try_structurally_resolve_type(pat.span, expected); // Determine whether we're consuming an inherited reference and resetting the default // binding mode, based on edition and enabled experimental features. - if let ByRef::Yes(_, inh_mut) = pat_info.binding_mode { + // FIXME(pin_ergonomics): since `&pin` pattern is supported, the condition here + // should be adjusted to `pat_pin == inh_pin` + if let ByRef::Yes(Pinnedness::Not, inh_mut) = pat_info.binding_mode { match self.ref_pat_matches_inherited_ref(pat.span.edition()) { InheritedRefMatchRule::EatOuter => { // ref pattern attempts to consume inherited reference @@ -2675,9 +2764,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } InheritedRefMatchRule::EatInner => { - if let ty::Ref(_, _, r_mutbl) = *expected.kind() - && pat_mutbl <= r_mutbl - { + let expected_ref_or_pinned_ref = || { + if self.tcx.features().pin_ergonomics() + && let Some(ty::Ref(_, _, r_mutbl)) = + expected.pinned_ty().map(|ty| *ty.kind()) + && pat_mutbl <= r_mutbl + { + return Some((Pinnedness::Pinned, r_mutbl)); + } + if let ty::Ref(_, _, r_mutbl) = *expected.kind() + && pat_mutbl <= r_mutbl + { + return Some((Pinnedness::Not, r_mutbl)); + } + None + }; + if let Some((_, r_mutbl)) = expected_ref_or_pinned_ref() { // Match against the reference type; don't consume the inherited ref. // NB: The check for compatible pattern and ref type mutability assumes that // `&` patterns can match against mutable references (RFC 3627, Rule 5). If diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d883f63486040..953c806658aef 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1356,6 +1356,16 @@ impl<'tcx> Ty<'tcx> { } } + pub fn pinned_ref(self) -> Option<(Ty<'tcx>, ty::Mutability)> { + if let Adt(def, args) = self.kind() + && def.is_pin() + && let &ty::Ref(_, ty, mutbl) = args.type_at(0).kind() + { + return Some((ty, mutbl)); + } + None + } + /// Panics if called on any type other than `Box`. pub fn expect_boxed_ty(self) -> Ty<'tcx> { self.boxed_ty() diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 6a6ed702373d1..06e9e28d0fdc8 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -493,6 +493,32 @@ impl<'tcx> TypeckResults<'tcx> { has_ref_mut } + /// Visits the pattern recursively whether it contains a `ref pin` binding + /// of non-`Unpin` type in it. + /// + /// This is used to determined whether a `&pin` pattern should emit a `!Unpin` + /// call for its pattern scrutinee. + /// + /// This is computed from the typeck results since we want to make + /// sure to apply any match-ergonomics adjustments, which we cannot + /// determine from the HIR alone. + pub fn pat_walk_ref_pin_binding_of_non_unpin_type<'a>( + &self, + pat: &hir::Pat<'_>, + mut ty_visitor: impl FnMut(Ty<'tcx>) + 'a, + ) { + pat.walk(|pat| { + if let hir::PatKind::Binding(_, id, _, _) = pat.kind + && let Some(BindingMode(ByRef::Yes(Pinnedness::Pinned, _), _)) = + self.pat_binding_modes().get(id) + { + let ty = self.pat_ty(pat); + ty_visitor(ty); + } + true + }); + } + /// How should a deref pattern find the place for its inner pattern to match on? /// /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index fb5292f48d2b0..12f653a13371d 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -981,7 +981,7 @@ pub enum ConstructorSet { /// This type has the following list of constructors. If `variants` is empty and /// `non_exhaustive` is false, don't use this; use `NoConstructors` instead. Variants { variants: IndexVec, non_exhaustive: bool }, - /// The type is `&T` + /// The type is `&T`. Ref, /// The type is a union. Union, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index cecb43e537a8e..12c8aa424d6d2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -52,20 +52,35 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; + let def_id = obligation.predicate.def_id(); + let tcx = self.tcx(); + + let lang_item = tcx.as_lang_item(def_id); + // Negative trait predicates have different rules than positive trait predicates. if obligation.polarity() == ty::PredicatePolarity::Negative { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); self.assemble_candidates_from_impls(obligation, &mut candidates); self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?; + + match lang_item { + Some(LangItem::Unpin) if tcx.features().pin_ergonomics() => { + debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty()); + + // impl `!Unpin` automatically for tuples, slices, and arrays + // to support projections for pinned patterns. + self.assemble_builtin_neg_unpin_candidate( + obligation.predicate.self_ty().skip_binder(), + &mut candidates, + ); + } + _ => {} + } } else { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); // Other bounds. Consider both in-scope bounds from fn decl // and applicable impls. There is a certain set of precedence rules here. - let def_id = obligation.predicate.def_id(); - let tcx = self.tcx(); - - let lang_item = tcx.as_lang_item(def_id); match lang_item { Some(LangItem::Copy | LangItem::Clone) => { debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty()); @@ -1223,6 +1238,59 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + /// Assembles `!Unpin` candidates for built-in types with no libcore-defined + /// `!Unpin` impls. + #[instrument(level = "debug", skip(self, candidates))] + fn assemble_builtin_neg_unpin_candidate( + &mut self, + self_ty: Ty<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + match *self_ty.kind() { + // `Unpin` types + ty::FnDef(..) + | ty::FnPtr(..) + | ty::Error(_) + | ty::Uint(_) + | ty::Int(_) + | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::Bool + | ty::Float(_) + | ty::Char + | ty::RawPtr(..) + | ty::Never + | ty::Ref(..) + | ty::Dynamic(..) + | ty::Str + | ty::Foreign(..) + | ty::UnsafeBinder(_) + | ty::Pat(..) => {} + + ty::Array(..) | ty::Slice(_) | ty::Tuple(_) => { + candidates.vec.push(BuiltinCandidate); + } + + // FIXME(pin_ergonomics): should we impl `!Unpin` for coroutines or closures? + ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) => {} + + ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {} + + ty::Infer(ty::TyVar(_)) => { + candidates.ambiguous = true; + } + + // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. + ty::Bound(..) => {} + + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); + } + } + } + /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself. #[instrument(level = "debug", skip(self, candidates))] fn assemble_builtin_sized_candidate( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 88f512708ff04..d6b7fbdec78e1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -250,6 +250,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { bug!("`PointeeSized` is removing during lowering"); } Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(self_ty), + Some(LangItem::Unpin) if obligation.polarity() == ty::PredicatePolarity::Negative => { + self.neg_unpin_conditions(self_ty) + } Some(LangItem::FusedIterator) => { if self.coroutine_is_gen(self_ty) { ty::Binder::dummy(vec![]) @@ -275,6 +278,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause, obligation.recursion_depth + 1, trait_def, + obligation.polarity(), types, ) } @@ -401,6 +405,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), obligation.recursion_depth + 1, obligation.predicate.def_id(), + obligation.polarity(), constituents.types, ); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ea903bac9d617..e4207b3271d7a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2272,6 +2272,52 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } + fn neg_unpin_conditions(&mut self, self_ty: Ty<'tcx>) -> ty::Binder<'tcx, Vec>> { + match *self_ty.kind() { + ty::Array(ty, _) | ty::Slice(ty) => { + // (*) binder moved here + ty::Binder::dummy(vec![ty]) + } + ty::Tuple(tys) => { + // (*) binder moved here + ty::Binder::dummy(tys.iter().collect()) + } + + // `Unpin` types + ty::FnDef(..) + | ty::FnPtr(..) + | ty::Error(_) + | ty::Uint(_) + | ty::Int(_) + | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::Bool + | ty::Float(_) + | ty::Char + | ty::RawPtr(..) + | ty::Never + | ty::Ref(..) + | ty::Dynamic(..) + | ty::Str + | ty::Foreign(..) + | ty::UnsafeBinder(_) + | ty::Pat(..) => bug!("`Unpin` type cannot have `!Unpin` bound"), + + ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Infer(ty::TyVar(_)) + | ty::Bound(..) + | ty::Adt(..) + | ty::Alias(..) + | ty::Param(..) + | ty::Placeholder(..) + | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty) + } + } + } + fn coroutine_is_gen(&mut self, self_ty: Ty<'tcx>) -> bool { matches!(*self_ty.kind(), ty::Coroutine(did, ..) if self.tcx().coroutine_is_gen(did)) @@ -2422,6 +2468,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { cause: ObligationCause<'tcx>, recursion_depth: usize, trait_def_id: DefId, + polarity: ty::PredicatePolarity, types: Vec>, ) -> PredicateObligations<'tcx> { // Because the types were potentially derived from @@ -2466,7 +2513,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::TraitRef::new_from_args(tcx, trait_def_id, err_args) }; - let obligation = Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref); + let trait_predicate = ty::TraitPredicate { trait_ref, polarity }; + + let obligation = + Obligation::new(self.tcx(), cause.clone(), param_env, trait_predicate); obligations.push(obligation); obligations }) diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir deleted file mode 100644 index 15f7446cc5912..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_const.built.after.mir +++ /dev/null @@ -1,33 +0,0 @@ -// MIR for `bar_const` after built - -fn bar_const(_1: Pin<&Bar>) -> () { - debug bar => _1; - let mut _0: (); - let _2: std::pin::Pin<&T>; - let _3: std::pin::Pin<&U>; - let mut _4: &T; - let mut _5: &U; - scope 1 { - debug x => _2; - debug y => _3; - } - - bb0: { - PlaceMention(_1); - StorageLive(_2); - _4 = &((*(_1.0: &Bar)).0: T); - _2 = Pin::<&T> { pointer: move _4 }; - StorageLive(_3); - _5 = &((*(_1.0: &Bar)).1: U); - _3 = Pin::<&U> { pointer: move _5 }; - _0 = const (); - StorageDead(_3); - StorageDead(_2); - return; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir deleted file mode 100644 index 46fd15502ffb1..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.bar_mut.built.after.mir +++ /dev/null @@ -1,33 +0,0 @@ -// MIR for `bar_mut` after built - -fn bar_mut(_1: Pin<&mut Bar>) -> () { - debug bar => _1; - let mut _0: (); - let _2: std::pin::Pin<&mut T>; - let _3: std::pin::Pin<&mut U>; - let mut _4: &mut T; - let mut _5: &mut U; - scope 1 { - debug x => _2; - debug y => _3; - } - - bb0: { - PlaceMention(_1); - StorageLive(_2); - _4 = &mut ((*(_1.0: &mut Bar)).0: T); - _2 = Pin::<&mut T> { pointer: move _4 }; - StorageLive(_3); - _5 = &mut ((*(_1.0: &mut Bar)).1: U); - _3 = Pin::<&mut U> { pointer: move _5 }; - _0 = const (); - StorageDead(_3); - StorageDead(_2); - return; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir deleted file mode 100644 index 8cfaf50a5f876..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_const.built.after.mir +++ /dev/null @@ -1,422 +0,0 @@ -// MIR for `baz_baz_const` after built - -fn baz_baz_const(_1: Pin<&Baz, Baz>>) -> () { - debug baz => _1; - let mut _0: (); - let mut _2: isize; - let mut _3: isize; - let mut _4: isize; - let mut _5: isize; - let mut _6: isize; - let mut _7: isize; - let mut _8: isize; - let _9: std::pin::Pin<&T>; - let _10: std::pin::Pin<&U>; - let _11: std::pin::Pin<&T>; - let _12: std::pin::Pin<&U>; - let mut _13: &T; - let mut _14: &U; - let mut _15: &T; - let mut _16: &U; - let _17: std::pin::Pin<&T>; - let _18: std::pin::Pin<&U>; - let _19: std::pin::Pin<&T>; - let _20: std::pin::Pin<&U>; - let mut _21: &T; - let mut _22: &U; - let mut _23: &T; - let mut _24: &U; - let _25: std::pin::Pin<&T>; - let _26: std::pin::Pin<&U>; - let _27: std::pin::Pin<&T>; - let _28: std::pin::Pin<&U>; - let mut _29: &T; - let mut _30: &U; - let mut _31: &T; - let mut _32: &U; - let _33: std::pin::Pin<&T>; - let _34: std::pin::Pin<&U>; - let _35: std::pin::Pin<&T>; - let _36: std::pin::Pin<&U>; - let mut _37: &T; - let mut _38: &U; - let mut _39: &T; - let mut _40: &U; - let _41: std::pin::Pin<&T>; - let _42: std::pin::Pin<&U>; - let _43: std::pin::Pin<&T>; - let _44: std::pin::Pin<&U>; - let mut _45: &T; - let mut _46: &U; - let mut _47: &T; - let mut _48: &U; - let _49: std::pin::Pin<&T>; - let _50: std::pin::Pin<&U>; - let _51: std::pin::Pin<&T>; - let _52: std::pin::Pin<&U>; - let mut _53: &T; - let mut _54: &U; - let mut _55: &T; - let mut _56: &U; - let _57: std::pin::Pin<&T>; - let _58: std::pin::Pin<&U>; - let _59: std::pin::Pin<&T>; - let _60: std::pin::Pin<&U>; - let mut _61: &T; - let mut _62: &U; - let mut _63: &T; - let mut _64: &U; - let _65: std::pin::Pin<&T>; - let _66: std::pin::Pin<&U>; - let _67: std::pin::Pin<&T>; - let _68: std::pin::Pin<&U>; - let mut _69: &T; - let mut _70: &U; - let mut _71: &T; - let mut _72: &U; - scope 1 { - debug x => _9; - debug y => _10; - debug z => _11; - debug w => _12; - } - scope 2 { - debug x => _17; - debug y => _18; - debug z => _19; - debug w => _20; - } - scope 3 { - debug x => _25; - debug y => _26; - debug z => _27; - debug w => _28; - } - scope 4 { - debug x => _33; - debug y => _34; - debug z => _35; - debug w => _36; - } - scope 5 { - debug x => _41; - debug y => _42; - debug z => _43; - debug w => _44; - } - scope 6 { - debug x => _49; - debug y => _50; - debug z => _51; - debug w => _52; - } - scope 7 { - debug x => _57; - debug y => _58; - debug z => _59; - debug w => _60; - } - scope 8 { - debug x => _65; - debug y => _66; - debug z => _67; - debug w => _68; - } - - bb0: { - PlaceMention(_1); - _8 = discriminant((*(_1.0: &Baz, Baz>))); - switchInt(move _8) -> [0: bb2, 1: bb16, otherwise: bb1]; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } - - bb2: { - _4 = discriminant((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz)); - switchInt(move _4) -> [0: bb4, 1: bb10, otherwise: bb3]; - } - - bb3: { - goto -> bb1; - } - - bb4: { - _2 = discriminant((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz)); - switchInt(move _2) -> [0: bb6, 1: bb8, otherwise: bb5]; - } - - bb5: { - goto -> bb3; - } - - bb6: { - falseEdge -> [real: bb36, imaginary: bb8]; - } - - bb7: { - goto -> bb5; - } - - bb8: { - falseEdge -> [real: bb35, imaginary: bb10]; - } - - bb9: { - goto -> bb5; - } - - bb10: { - _3 = discriminant((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz)); - switchInt(move _3) -> [0: bb12, 1: bb14, otherwise: bb11]; - } - - bb11: { - goto -> bb3; - } - - bb12: { - falseEdge -> [real: bb34, imaginary: bb14]; - } - - bb13: { - goto -> bb11; - } - - bb14: { - falseEdge -> [real: bb33, imaginary: bb16]; - } - - bb15: { - goto -> bb11; - } - - bb16: { - _7 = discriminant((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz)); - switchInt(move _7) -> [0: bb18, 1: bb24, otherwise: bb17]; - } - - bb17: { - goto -> bb1; - } - - bb18: { - _5 = discriminant((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz)); - switchInt(move _5) -> [0: bb20, 1: bb22, otherwise: bb19]; - } - - bb19: { - goto -> bb17; - } - - bb20: { - falseEdge -> [real: bb32, imaginary: bb22]; - } - - bb21: { - goto -> bb19; - } - - bb22: { - falseEdge -> [real: bb31, imaginary: bb24]; - } - - bb23: { - goto -> bb19; - } - - bb24: { - _6 = discriminant((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz)); - switchInt(move _6) -> [0: bb26, 1: bb28, otherwise: bb25]; - } - - bb25: { - goto -> bb17; - } - - bb26: { - falseEdge -> [real: bb30, imaginary: bb28]; - } - - bb27: { - goto -> bb25; - } - - bb28: { - StorageLive(_65); - _69 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); - _65 = Pin::<&T> { pointer: move _69 }; - StorageLive(_66); - _70 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); - _66 = Pin::<&U> { pointer: move _70 }; - StorageLive(_67); - _71 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); - _67 = Pin::<&T> { pointer: move _71 }; - StorageLive(_68); - _72 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); - _68 = Pin::<&U> { pointer: move _72 }; - _0 = const (); - StorageDead(_68); - StorageDead(_67); - StorageDead(_66); - StorageDead(_65); - goto -> bb37; - } - - bb29: { - goto -> bb25; - } - - bb30: { - StorageLive(_57); - _61 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); - _57 = Pin::<&T> { pointer: move _61 }; - StorageLive(_58); - _62 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); - _58 = Pin::<&U> { pointer: move _62 }; - StorageLive(_59); - _63 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); - _59 = Pin::<&T> { pointer: move _63 }; - StorageLive(_60); - _64 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); - _60 = Pin::<&U> { pointer: move _64 }; - _0 = const (); - StorageDead(_60); - StorageDead(_59); - StorageDead(_58); - StorageDead(_57); - goto -> bb37; - } - - bb31: { - StorageLive(_49); - _53 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); - _49 = Pin::<&T> { pointer: move _53 }; - StorageLive(_50); - _54 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); - _50 = Pin::<&U> { pointer: move _54 }; - StorageLive(_51); - _55 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); - _51 = Pin::<&T> { pointer: move _55 }; - StorageLive(_52); - _56 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); - _52 = Pin::<&U> { pointer: move _56 }; - _0 = const (); - StorageDead(_52); - StorageDead(_51); - StorageDead(_50); - StorageDead(_49); - goto -> bb37; - } - - bb32: { - StorageLive(_41); - _45 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); - _41 = Pin::<&T> { pointer: move _45 }; - StorageLive(_42); - _46 = &(((((*(_1.0: &Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); - _42 = Pin::<&U> { pointer: move _46 }; - StorageLive(_43); - _47 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); - _43 = Pin::<&T> { pointer: move _47 }; - StorageLive(_44); - _48 = &(((((*(_1.0: &Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); - _44 = Pin::<&U> { pointer: move _48 }; - _0 = const (); - StorageDead(_44); - StorageDead(_43); - StorageDead(_42); - StorageDead(_41); - goto -> bb37; - } - - bb33: { - StorageLive(_33); - _37 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); - _33 = Pin::<&T> { pointer: move _37 }; - StorageLive(_34); - _38 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); - _34 = Pin::<&U> { pointer: move _38 }; - StorageLive(_35); - _39 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); - _35 = Pin::<&T> { pointer: move _39 }; - StorageLive(_36); - _40 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); - _36 = Pin::<&U> { pointer: move _40 }; - _0 = const (); - StorageDead(_36); - StorageDead(_35); - StorageDead(_34); - StorageDead(_33); - goto -> bb37; - } - - bb34: { - StorageLive(_25); - _29 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); - _25 = Pin::<&T> { pointer: move _29 }; - StorageLive(_26); - _30 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); - _26 = Pin::<&U> { pointer: move _30 }; - StorageLive(_27); - _31 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); - _27 = Pin::<&T> { pointer: move _31 }; - StorageLive(_28); - _32 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); - _28 = Pin::<&U> { pointer: move _32 }; - _0 = const (); - StorageDead(_28); - StorageDead(_27); - StorageDead(_26); - StorageDead(_25); - goto -> bb37; - } - - bb35: { - StorageLive(_17); - _21 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); - _17 = Pin::<&T> { pointer: move _21 }; - StorageLive(_18); - _22 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); - _18 = Pin::<&U> { pointer: move _22 }; - StorageLive(_19); - _23 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); - _19 = Pin::<&T> { pointer: move _23 }; - StorageLive(_20); - _24 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); - _20 = Pin::<&U> { pointer: move _24 }; - _0 = const (); - StorageDead(_20); - StorageDead(_19); - StorageDead(_18); - StorageDead(_17); - goto -> bb37; - } - - bb36: { - StorageLive(_9); - _13 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); - _9 = Pin::<&T> { pointer: move _13 }; - StorageLive(_10); - _14 = &(((((*(_1.0: &Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); - _10 = Pin::<&U> { pointer: move _14 }; - StorageLive(_11); - _15 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); - _11 = Pin::<&T> { pointer: move _15 }; - StorageLive(_12); - _16 = &(((((*(_1.0: &Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); - _12 = Pin::<&U> { pointer: move _16 }; - _0 = const (); - StorageDead(_12); - StorageDead(_11); - StorageDead(_10); - StorageDead(_9); - goto -> bb37; - } - - bb37: { - return; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir deleted file mode 100644 index 43c523cbf5717..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_baz_mut.built.after.mir +++ /dev/null @@ -1,422 +0,0 @@ -// MIR for `baz_baz_mut` after built - -fn baz_baz_mut(_1: Pin<&mut Baz, Baz>>) -> () { - debug baz => _1; - let mut _0: (); - let mut _2: isize; - let mut _3: isize; - let mut _4: isize; - let mut _5: isize; - let mut _6: isize; - let mut _7: isize; - let mut _8: isize; - let _9: std::pin::Pin<&mut T>; - let _10: std::pin::Pin<&mut U>; - let _11: std::pin::Pin<&mut T>; - let _12: std::pin::Pin<&mut U>; - let mut _13: &mut T; - let mut _14: &mut U; - let mut _15: &mut T; - let mut _16: &mut U; - let _17: std::pin::Pin<&mut T>; - let _18: std::pin::Pin<&mut U>; - let _19: std::pin::Pin<&mut T>; - let _20: std::pin::Pin<&mut U>; - let mut _21: &mut T; - let mut _22: &mut U; - let mut _23: &mut T; - let mut _24: &mut U; - let _25: std::pin::Pin<&mut T>; - let _26: std::pin::Pin<&mut U>; - let _27: std::pin::Pin<&mut T>; - let _28: std::pin::Pin<&mut U>; - let mut _29: &mut T; - let mut _30: &mut U; - let mut _31: &mut T; - let mut _32: &mut U; - let _33: std::pin::Pin<&mut T>; - let _34: std::pin::Pin<&mut U>; - let _35: std::pin::Pin<&mut T>; - let _36: std::pin::Pin<&mut U>; - let mut _37: &mut T; - let mut _38: &mut U; - let mut _39: &mut T; - let mut _40: &mut U; - let _41: std::pin::Pin<&mut T>; - let _42: std::pin::Pin<&mut U>; - let _43: std::pin::Pin<&mut T>; - let _44: std::pin::Pin<&mut U>; - let mut _45: &mut T; - let mut _46: &mut U; - let mut _47: &mut T; - let mut _48: &mut U; - let _49: std::pin::Pin<&mut T>; - let _50: std::pin::Pin<&mut U>; - let _51: std::pin::Pin<&mut T>; - let _52: std::pin::Pin<&mut U>; - let mut _53: &mut T; - let mut _54: &mut U; - let mut _55: &mut T; - let mut _56: &mut U; - let _57: std::pin::Pin<&mut T>; - let _58: std::pin::Pin<&mut U>; - let _59: std::pin::Pin<&mut T>; - let _60: std::pin::Pin<&mut U>; - let mut _61: &mut T; - let mut _62: &mut U; - let mut _63: &mut T; - let mut _64: &mut U; - let _65: std::pin::Pin<&mut T>; - let _66: std::pin::Pin<&mut U>; - let _67: std::pin::Pin<&mut T>; - let _68: std::pin::Pin<&mut U>; - let mut _69: &mut T; - let mut _70: &mut U; - let mut _71: &mut T; - let mut _72: &mut U; - scope 1 { - debug x => _9; - debug y => _10; - debug z => _11; - debug w => _12; - } - scope 2 { - debug x => _17; - debug y => _18; - debug z => _19; - debug w => _20; - } - scope 3 { - debug x => _25; - debug y => _26; - debug z => _27; - debug w => _28; - } - scope 4 { - debug x => _33; - debug y => _34; - debug z => _35; - debug w => _36; - } - scope 5 { - debug x => _41; - debug y => _42; - debug z => _43; - debug w => _44; - } - scope 6 { - debug x => _49; - debug y => _50; - debug z => _51; - debug w => _52; - } - scope 7 { - debug x => _57; - debug y => _58; - debug z => _59; - debug w => _60; - } - scope 8 { - debug x => _65; - debug y => _66; - debug z => _67; - debug w => _68; - } - - bb0: { - PlaceMention(_1); - _8 = discriminant((*(_1.0: &mut Baz, Baz>))); - switchInt(move _8) -> [0: bb2, 1: bb16, otherwise: bb1]; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } - - bb2: { - _4 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz)); - switchInt(move _4) -> [0: bb4, 1: bb10, otherwise: bb3]; - } - - bb3: { - goto -> bb1; - } - - bb4: { - _2 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz)); - switchInt(move _2) -> [0: bb6, 1: bb8, otherwise: bb5]; - } - - bb5: { - goto -> bb3; - } - - bb6: { - falseEdge -> [real: bb36, imaginary: bb8]; - } - - bb7: { - goto -> bb5; - } - - bb8: { - falseEdge -> [real: bb35, imaginary: bb10]; - } - - bb9: { - goto -> bb5; - } - - bb10: { - _3 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz)); - switchInt(move _3) -> [0: bb12, 1: bb14, otherwise: bb11]; - } - - bb11: { - goto -> bb3; - } - - bb12: { - falseEdge -> [real: bb34, imaginary: bb14]; - } - - bb13: { - goto -> bb11; - } - - bb14: { - falseEdge -> [real: bb33, imaginary: bb16]; - } - - bb15: { - goto -> bb11; - } - - bb16: { - _7 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz)); - switchInt(move _7) -> [0: bb18, 1: bb24, otherwise: bb17]; - } - - bb17: { - goto -> bb1; - } - - bb18: { - _5 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz)); - switchInt(move _5) -> [0: bb20, 1: bb22, otherwise: bb19]; - } - - bb19: { - goto -> bb17; - } - - bb20: { - falseEdge -> [real: bb32, imaginary: bb22]; - } - - bb21: { - goto -> bb19; - } - - bb22: { - falseEdge -> [real: bb31, imaginary: bb24]; - } - - bb23: { - goto -> bb19; - } - - bb24: { - _6 = discriminant((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz)); - switchInt(move _6) -> [0: bb26, 1: bb28, otherwise: bb25]; - } - - bb25: { - goto -> bb17; - } - - bb26: { - falseEdge -> [real: bb30, imaginary: bb28]; - } - - bb27: { - goto -> bb25; - } - - bb28: { - StorageLive(_65); - _69 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); - _65 = Pin::<&mut T> { pointer: move _69 }; - StorageLive(_66); - _70 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); - _66 = Pin::<&mut U> { pointer: move _70 }; - StorageLive(_67); - _71 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); - _67 = Pin::<&mut T> { pointer: move _71 }; - StorageLive(_68); - _72 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); - _68 = Pin::<&mut U> { pointer: move _72 }; - _0 = const (); - StorageDead(_68); - StorageDead(_67); - StorageDead(_66); - StorageDead(_65); - goto -> bb37; - } - - bb29: { - goto -> bb25; - } - - bb30: { - StorageLive(_57); - _61 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).0: T); - _57 = Pin::<&mut T> { pointer: move _61 }; - StorageLive(_58); - _62 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Bar).1: U); - _58 = Pin::<&mut U> { pointer: move _62 }; - StorageLive(_59); - _63 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); - _59 = Pin::<&mut T> { pointer: move _63 }; - StorageLive(_60); - _64 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); - _60 = Pin::<&mut U> { pointer: move _64 }; - _0 = const (); - StorageDead(_60); - StorageDead(_59); - StorageDead(_58); - StorageDead(_57); - goto -> bb37; - } - - bb31: { - StorageLive(_49); - _53 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); - _49 = Pin::<&mut T> { pointer: move _53 }; - StorageLive(_50); - _54 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); - _50 = Pin::<&mut U> { pointer: move _54 }; - StorageLive(_51); - _55 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).0: T); - _51 = Pin::<&mut T> { pointer: move _55 }; - StorageLive(_52); - _56 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Bar).1: U); - _52 = Pin::<&mut U> { pointer: move _56 }; - _0 = const (); - StorageDead(_52); - StorageDead(_51); - StorageDead(_50); - StorageDead(_49); - goto -> bb37; - } - - bb32: { - StorageLive(_41); - _45 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).0: T); - _41 = Pin::<&mut T> { pointer: move _45 }; - StorageLive(_42); - _46 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).0: Baz) as Foo).1: U); - _42 = Pin::<&mut U> { pointer: move _46 }; - StorageLive(_43); - _47 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).0: T); - _43 = Pin::<&mut T> { pointer: move _47 }; - StorageLive(_44); - _48 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Bar).1: Baz) as Foo).1: U); - _44 = Pin::<&mut U> { pointer: move _48 }; - _0 = const (); - StorageDead(_44); - StorageDead(_43); - StorageDead(_42); - StorageDead(_41); - goto -> bb37; - } - - bb33: { - StorageLive(_33); - _37 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); - _33 = Pin::<&mut T> { pointer: move _37 }; - StorageLive(_34); - _38 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); - _34 = Pin::<&mut U> { pointer: move _38 }; - StorageLive(_35); - _39 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); - _35 = Pin::<&mut T> { pointer: move _39 }; - StorageLive(_36); - _40 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); - _36 = Pin::<&mut U> { pointer: move _40 }; - _0 = const (); - StorageDead(_36); - StorageDead(_35); - StorageDead(_34); - StorageDead(_33); - goto -> bb37; - } - - bb34: { - StorageLive(_25); - _29 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).0: T); - _25 = Pin::<&mut T> { pointer: move _29 }; - StorageLive(_26); - _30 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Bar).1: U); - _26 = Pin::<&mut U> { pointer: move _30 }; - StorageLive(_27); - _31 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); - _27 = Pin::<&mut T> { pointer: move _31 }; - StorageLive(_28); - _32 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); - _28 = Pin::<&mut U> { pointer: move _32 }; - _0 = const (); - StorageDead(_28); - StorageDead(_27); - StorageDead(_26); - StorageDead(_25); - goto -> bb37; - } - - bb35: { - StorageLive(_17); - _21 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); - _17 = Pin::<&mut T> { pointer: move _21 }; - StorageLive(_18); - _22 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); - _18 = Pin::<&mut U> { pointer: move _22 }; - StorageLive(_19); - _23 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).0: T); - _19 = Pin::<&mut T> { pointer: move _23 }; - StorageLive(_20); - _24 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Bar).1: U); - _20 = Pin::<&mut U> { pointer: move _24 }; - _0 = const (); - StorageDead(_20); - StorageDead(_19); - StorageDead(_18); - StorageDead(_17); - goto -> bb37; - } - - bb36: { - StorageLive(_9); - _13 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).0: T); - _9 = Pin::<&mut T> { pointer: move _13 }; - StorageLive(_10); - _14 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).0: Baz) as Foo).1: U); - _10 = Pin::<&mut U> { pointer: move _14 }; - StorageLive(_11); - _15 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).0: T); - _11 = Pin::<&mut T> { pointer: move _15 }; - StorageLive(_12); - _16 = &mut (((((*(_1.0: &mut Baz, Baz>)) as Foo).1: Baz) as Foo).1: U); - _12 = Pin::<&mut U> { pointer: move _16 }; - _0 = const (); - StorageDead(_12); - StorageDead(_11); - StorageDead(_10); - StorageDead(_9); - goto -> bb37; - } - - bb37: { - return; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir deleted file mode 100644 index 5538449cc43cc..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_const.built.after.mir +++ /dev/null @@ -1,76 +0,0 @@ -// MIR for `baz_const` after built - -fn baz_const(_1: Pin<&Baz>) -> () { - debug baz => _1; - let mut _0: (); - let mut _2: isize; - let _3: std::pin::Pin<&T>; - let _4: std::pin::Pin<&U>; - let mut _5: &T; - let mut _6: &U; - let _7: std::pin::Pin<&T>; - let _8: std::pin::Pin<&U>; - let mut _9: &T; - let mut _10: &U; - scope 1 { - debug x => _3; - debug y => _4; - } - scope 2 { - debug x => _7; - debug y => _8; - } - - bb0: { - PlaceMention(_1); - _2 = discriminant((*(_1.0: &Baz))); - switchInt(move _2) -> [0: bb2, 1: bb4, otherwise: bb1]; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } - - bb2: { - falseEdge -> [real: bb6, imaginary: bb4]; - } - - bb3: { - goto -> bb1; - } - - bb4: { - StorageLive(_7); - _9 = &(((*(_1.0: &Baz)) as Bar).0: T); - _7 = Pin::<&T> { pointer: move _9 }; - StorageLive(_8); - _10 = &(((*(_1.0: &Baz)) as Bar).1: U); - _8 = Pin::<&U> { pointer: move _10 }; - _0 = const (); - StorageDead(_8); - StorageDead(_7); - goto -> bb7; - } - - bb5: { - goto -> bb1; - } - - bb6: { - StorageLive(_3); - _5 = &(((*(_1.0: &Baz)) as Foo).0: T); - _3 = Pin::<&T> { pointer: move _5 }; - StorageLive(_4); - _6 = &(((*(_1.0: &Baz)) as Foo).1: U); - _4 = Pin::<&U> { pointer: move _6 }; - _0 = const (); - StorageDead(_4); - StorageDead(_3); - goto -> bb7; - } - - bb7: { - return; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir deleted file mode 100644 index 4ae472cba3a58..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.baz_mut.built.after.mir +++ /dev/null @@ -1,76 +0,0 @@ -// MIR for `baz_mut` after built - -fn baz_mut(_1: Pin<&mut Baz>) -> () { - debug baz => _1; - let mut _0: (); - let mut _2: isize; - let _3: std::pin::Pin<&mut T>; - let _4: std::pin::Pin<&mut U>; - let mut _5: &mut T; - let mut _6: &mut U; - let _7: std::pin::Pin<&mut T>; - let _8: std::pin::Pin<&mut U>; - let mut _9: &mut T; - let mut _10: &mut U; - scope 1 { - debug x => _3; - debug y => _4; - } - scope 2 { - debug x => _7; - debug y => _8; - } - - bb0: { - PlaceMention(_1); - _2 = discriminant((*(_1.0: &mut Baz))); - switchInt(move _2) -> [0: bb2, 1: bb4, otherwise: bb1]; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } - - bb2: { - falseEdge -> [real: bb6, imaginary: bb4]; - } - - bb3: { - goto -> bb1; - } - - bb4: { - StorageLive(_7); - _9 = &mut (((*(_1.0: &mut Baz)) as Bar).0: T); - _7 = Pin::<&mut T> { pointer: move _9 }; - StorageLive(_8); - _10 = &mut (((*(_1.0: &mut Baz)) as Bar).1: U); - _8 = Pin::<&mut U> { pointer: move _10 }; - _0 = const (); - StorageDead(_8); - StorageDead(_7); - goto -> bb7; - } - - bb5: { - goto -> bb1; - } - - bb6: { - StorageLive(_3); - _5 = &mut (((*(_1.0: &mut Baz)) as Foo).0: T); - _3 = Pin::<&mut T> { pointer: move _5 }; - StorageLive(_4); - _6 = &mut (((*(_1.0: &mut Baz)) as Foo).1: U); - _4 = Pin::<&mut U> { pointer: move _6 }; - _0 = const (); - StorageDead(_4); - StorageDead(_3); - goto -> bb7; - } - - bb7: { - return; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir deleted file mode 100644 index 8b397ffd18142..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_const.built.after.mir +++ /dev/null @@ -1,47 +0,0 @@ -// MIR for `foo_bar_const` after built - -fn foo_bar_const(_1: Pin<&Foo, Bar>>) -> () { - debug foo => _1; - let mut _0: (); - let _2: std::pin::Pin<&T>; - let _3: std::pin::Pin<&U>; - let _4: std::pin::Pin<&T>; - let _5: std::pin::Pin<&U>; - let mut _6: &T; - let mut _7: &U; - let mut _8: &T; - let mut _9: &U; - scope 1 { - debug x => _2; - debug y => _3; - debug z => _4; - debug w => _5; - } - - bb0: { - PlaceMention(_1); - StorageLive(_2); - _6 = &(((*(_1.0: &Foo, Bar>)).0: Bar).0: T); - _2 = Pin::<&T> { pointer: move _6 }; - StorageLive(_3); - _7 = &(((*(_1.0: &Foo, Bar>)).0: Bar).1: U); - _3 = Pin::<&U> { pointer: move _7 }; - StorageLive(_4); - _8 = &(((*(_1.0: &Foo, Bar>)).1: Bar).0: T); - _4 = Pin::<&T> { pointer: move _8 }; - StorageLive(_5); - _9 = &(((*(_1.0: &Foo, Bar>)).1: Bar).1: U); - _5 = Pin::<&U> { pointer: move _9 }; - _0 = const (); - StorageDead(_5); - StorageDead(_4); - StorageDead(_3); - StorageDead(_2); - return; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir deleted file mode 100644 index 2e8128bb9d1e4..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_bar_mut.built.after.mir +++ /dev/null @@ -1,47 +0,0 @@ -// MIR for `foo_bar_mut` after built - -fn foo_bar_mut(_1: Pin<&mut Foo, Bar>>) -> () { - debug foo => _1; - let mut _0: (); - let _2: std::pin::Pin<&mut T>; - let _3: std::pin::Pin<&mut U>; - let _4: std::pin::Pin<&mut T>; - let _5: std::pin::Pin<&mut U>; - let mut _6: &mut T; - let mut _7: &mut U; - let mut _8: &mut T; - let mut _9: &mut U; - scope 1 { - debug x => _2; - debug y => _3; - debug z => _4; - debug w => _5; - } - - bb0: { - PlaceMention(_1); - StorageLive(_2); - _6 = &mut (((*(_1.0: &mut Foo, Bar>)).0: Bar).0: T); - _2 = Pin::<&mut T> { pointer: move _6 }; - StorageLive(_3); - _7 = &mut (((*(_1.0: &mut Foo, Bar>)).0: Bar).1: U); - _3 = Pin::<&mut U> { pointer: move _7 }; - StorageLive(_4); - _8 = &mut (((*(_1.0: &mut Foo, Bar>)).1: Bar).0: T); - _4 = Pin::<&mut T> { pointer: move _8 }; - StorageLive(_5); - _9 = &mut (((*(_1.0: &mut Foo, Bar>)).1: Bar).1: U); - _5 = Pin::<&mut U> { pointer: move _9 }; - _0 = const (); - StorageDead(_5); - StorageDead(_4); - StorageDead(_3); - StorageDead(_2); - return; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir deleted file mode 100644 index b77b341d4ef76..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_const.built.after.mir +++ /dev/null @@ -1,33 +0,0 @@ -// MIR for `foo_const` after built - -fn foo_const(_1: Pin<&Foo>) -> () { - debug foo => _1; - let mut _0: (); - let _2: std::pin::Pin<&T>; - let _3: std::pin::Pin<&U>; - let mut _4: &T; - let mut _5: &U; - scope 1 { - debug x => _2; - debug y => _3; - } - - bb0: { - PlaceMention(_1); - StorageLive(_2); - _4 = &((*(_1.0: &Foo)).0: T); - _2 = Pin::<&T> { pointer: move _4 }; - StorageLive(_3); - _5 = &((*(_1.0: &Foo)).1: U); - _3 = Pin::<&U> { pointer: move _5 }; - _0 = const (); - StorageDead(_3); - StorageDead(_2); - return; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir b/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir deleted file mode 100644 index c7b88d239f87a..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.foo_mut.built.after.mir +++ /dev/null @@ -1,33 +0,0 @@ -// MIR for `foo_mut` after built - -fn foo_mut(_1: Pin<&mut Foo>) -> () { - debug foo => _1; - let mut _0: (); - let _2: std::pin::Pin<&mut T>; - let _3: std::pin::Pin<&mut U>; - let mut _4: &mut T; - let mut _5: &mut U; - scope 1 { - debug x => _2; - debug y => _3; - } - - bb0: { - PlaceMention(_1); - StorageLive(_2); - _4 = &mut ((*(_1.0: &mut Foo)).0: T); - _2 = Pin::<&mut T> { pointer: move _4 }; - StorageLive(_3); - _5 = &mut ((*(_1.0: &mut Foo)).1: U); - _3 = Pin::<&mut U> { pointer: move _5 }; - _0 = const (); - StorageDead(_3); - StorageDead(_2); - return; - } - - bb1: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; - } -} diff --git a/tests/mir-opt/pin-ergonomics/project_pattern_match.rs b/tests/mir-opt/pin-ergonomics/project_pattern_match.rs deleted file mode 100644 index 8808111f303b3..0000000000000 --- a/tests/mir-opt/pin-ergonomics/project_pattern_match.rs +++ /dev/null @@ -1,95 +0,0 @@ -// skip-filecheck -#![feature(pin_ergonomics)] -#![allow(incomplete_features)] - -// This test verifies that a `&pin mut Foo` can be projected to a pinned -// reference `&pin mut T` of a `?Unpin` field , and can be projected to -// an unpinned reference `&mut U` of an `Unpin` field . - -struct Foo { - x: T, - y: U, -} - -struct Bar(T, U); - -enum Baz { - Foo(T, U), - Bar { x: T, y: U }, -} - -// EMIT_MIR project_pattern_match.foo_mut.built.after.mir -fn foo_mut(foo: &pin mut Foo) { - let Foo { x, y } = foo; -} - -// EMIT_MIR project_pattern_match.foo_const.built.after.mir -fn foo_const(foo: &pin const Foo) { - let Foo { x, y } = foo; -} - -// EMIT_MIR project_pattern_match.bar_mut.built.after.mir -fn bar_mut(bar: &pin mut Bar) { - let Bar(x, y) = bar; -} - -// EMIT_MIR project_pattern_match.bar_const.built.after.mir -fn bar_const(bar: &pin const Bar) { - let Bar(x, y) = bar; -} - -// EMIT_MIR project_pattern_match.foo_bar_mut.built.after.mir -fn foo_bar_mut(foo: &pin mut Foo, Bar>) { - let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; -} - -// EMIT_MIR project_pattern_match.foo_bar_const.built.after.mir -fn foo_bar_const(foo: &pin const Foo, Bar>) { - let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; -} - -// EMIT_MIR project_pattern_match.baz_mut.built.after.mir -fn baz_mut(baz: &pin mut Baz) { - match baz { - Baz::Foo(x, y) => {} - Baz::Bar { x, y } => {} - } -} - -// EMIT_MIR project_pattern_match.baz_const.built.after.mir -fn baz_const(baz: &pin const Baz) { - match baz { - Baz::Foo(x, y) => {} - Baz::Bar { x, y } => {} - } -} - -// EMIT_MIR project_pattern_match.baz_baz_mut.built.after.mir -fn baz_baz_mut(baz: &pin mut Baz, Baz>) { - match baz { - Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w)) => {} - Baz::Foo(Baz::Foo(x, y), Baz::Bar { x: z, y: w }) => {} - Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w)) => {} - Baz::Foo(Baz::Bar { x, y }, Baz::Bar { x: z, y: w }) => {} - Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) } => {} - Baz::Bar { x: Baz::Foo(x, y), y: Baz::Bar { x: z, y: w } } => {} - Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) } => {} - Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Bar { x: z, y: w } } => {} - } -} - -// EMIT_MIR project_pattern_match.baz_baz_const.built.after.mir -fn baz_baz_const(baz: &pin const Baz, Baz>) { - match baz { - Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w)) => {} - Baz::Foo(Baz::Foo(x, y), Baz::Bar { x: z, y: w }) => {} - Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w)) => {} - Baz::Foo(Baz::Bar { x, y }, Baz::Bar { x: z, y: w }) => {} - Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) } => {} - Baz::Bar { x: Baz::Foo(x, y), y: Baz::Bar { x: z, y: w } } => {} - Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) } => {} - Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Bar { x: z, y: w } } => {} - } -} - -fn main() {} diff --git a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr index 7aaa51e81ed90..5e91fae18cca5 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:35:9 + --> $DIR/pattern-matching.rs:41:9 | -LL | let Foo { x, y } = foo; - | ^^^^^^^^^^^^ --- this expression has type `Pin<&mut Foo>` +LL | let Foo { x, y } = foo_mut; + | ^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` | | | expected `Pin<&mut Foo>`, found `Foo<_, _>` | @@ -10,14 +10,14 @@ LL | let Foo { x, y } = foo; found struct `Foo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | let Foo { x, y } = *foo; +LL | let Foo { x, y } = *foo_mut; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:42:9 + --> $DIR/pattern-matching.rs:46:9 | -LL | let Foo { x, y } = foo; - | ^^^^^^^^^^^^ --- this expression has type `Pin<&Foo>` +LL | let Foo { x, y } = foo_const; + | ^^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` | | | expected `Pin<&Foo>`, found `Foo<_, _>` | @@ -25,289 +25,184 @@ LL | let Foo { x, y } = foo; found struct `Foo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | let Foo { x, y } = *foo; +LL | let Foo { x, y } = *foo_const; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:49:9 + --> $DIR/pattern-matching.rs:54:9 | -LL | let Bar(x, y) = bar; - | ^^^^^^^^^ --- this expression has type `Pin<&mut Bar>` +LL | let Foo { x, .. } = foo_mut; + | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` | | - | expected `Pin<&mut Bar>`, found `Bar<_, _>` - | - = note: expected struct `Pin<&mut Bar>` - found struct `Bar<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | let Bar(x, y) = *bar; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:56:9 - | -LL | let Bar(x, y) = bar; - | ^^^^^^^^^ --- this expression has type `Pin<&Bar>` - | | - | expected `Pin<&Bar>`, found `Bar<_, _>` - | - = note: expected struct `Pin<&Bar>` - found struct `Bar<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | let Bar(x, y) = *bar; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:63:9 - | -LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- this expression has type `Pin<&mut Foo, Bar>>` - | | - | expected `Pin<&mut Foo, Bar>>`, found `Foo<_, _>` + | expected `Pin<&mut Foo>`, found `Foo<_, _>` | - = note: expected struct `Pin<&mut Foo, Bar>>` + = note: expected struct `Pin<&mut Foo>` found struct `Foo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = *foo; - | + +LL | let Foo { x, .. } = *foo_mut; + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:72:9 + --> $DIR/pattern-matching.rs:58:9 | -LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- this expression has type `Pin<&Foo, Bar>>` +LL | let Foo { x, .. } = foo_const; + | ^^^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` | | - | expected `Pin<&Foo, Bar>>`, found `Foo<_, _>` + | expected `Pin<&Foo>`, found `Foo<_, _>` | - = note: expected struct `Pin<&Foo, Bar>>` + = note: expected struct `Pin<&Foo>` found struct `Foo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | let Foo { x: Bar(x, y), y: Bar(z, w) } = *foo; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:82:9 - | -LL | match baz { - | --- this expression has type `Pin<&mut Baz>` -LL | Baz::Foo(x, y) => { - | ^^^^^^^^^^^^^^ expected `Pin<&mut Baz>`, found `Baz<_, _>` - | - = note: expected struct `Pin<&mut Baz>` - found enum `Baz<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | match *baz { - | + +LL | let Foo { x, .. } = *foo_const; + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:87:9 - | -LL | match baz { - | --- this expression has type `Pin<&mut Baz>` -... -LL | Baz::Bar { x, y } => { - | ^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz>`, found `Baz<_, _>` - | - = note: expected struct `Pin<&mut Baz>` - found enum `Baz<_, _>` -help: consider dereferencing to access the inner value using the Deref trait + --> $DIR/pattern-matching.rs:68:9 | -LL | match *baz { - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:97:9 - | -LL | match baz { - | --- this expression has type `Pin<&Baz>` -LL | Baz::Foo(x, y) => { - | ^^^^^^^^^^^^^^ expected `Pin<&Baz>`, found `Baz<_, _>` +LL | let NegUnpinFoo { x, y } = foo_mut; + | ^^^^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinFoo>` + | | + | expected `Pin<&mut NegUnpinFoo>`, found `NegUnpinFoo<_, _>` | - = note: expected struct `Pin<&Baz>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&mut NegUnpinFoo>` + found struct `NegUnpinFoo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { - | + +LL | let NegUnpinFoo { x, y } = *foo_mut; + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:102:9 + --> $DIR/pattern-matching.rs:73:9 | -LL | match baz { - | --- this expression has type `Pin<&Baz>` -... -LL | Baz::Bar { x, y } => { - | ^^^^^^^^^^^^^^^^^ expected `Pin<&Baz>`, found `Baz<_, _>` +LL | let NegUnpinFoo { x, y } = foo_const; + | ^^^^^^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinFoo>` + | | + | expected `Pin<&NegUnpinFoo>`, found `NegUnpinFoo<_, _>` | - = note: expected struct `Pin<&Baz>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&NegUnpinFoo>` + found struct `NegUnpinFoo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { - | + +LL | let NegUnpinFoo { x, y } = *foo_const; + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:112:9 + --> $DIR/pattern-matching.rs:85:9 | -LL | match baz { - | --- this expression has type `Pin<&mut Baz, Baz>>` -LL | Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` +LL | match bar_mut { + | ------- this expression has type `Pin<&mut NegUnpinBar>` +LL | NegUnpinBar::Foo(x, y) => { + | ^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut NegUnpinBar>`, found `NegUnpinBar<_, _>` | - = note: expected struct `Pin<&mut Baz, Baz>>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&mut NegUnpinBar>` + found enum `NegUnpinBar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { +LL | match *bar_mut { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:119:9 + --> $DIR/pattern-matching.rs:90:18 | -LL | match baz { - | --- this expression has type `Pin<&mut Baz, Baz>>` -... -LL | Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` +LL | _ if let NegUnpinBar::Bar { x, y } = bar_mut => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinBar>` + | | + | expected `Pin<&mut NegUnpinBar>`, found `NegUnpinBar<_, _>` | - = note: expected struct `Pin<&mut Baz, Baz>>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&mut NegUnpinBar>` + found enum `NegUnpinBar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { - | + +LL | _ if let NegUnpinBar::Bar { x, y } = *bar_mut => { + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:126:9 + --> $DIR/pattern-matching.rs:98:9 | -LL | match baz { - | --- this expression has type `Pin<&mut Baz, Baz>>` -... -LL | Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` +LL | match bar_const { + | --------- this expression has type `Pin<&NegUnpinBar>` +LL | NegUnpinBar::Bar { x, y } => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&NegUnpinBar>`, found `NegUnpinBar<_, _>` | - = note: expected struct `Pin<&mut Baz, Baz>>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&NegUnpinBar>` + found enum `NegUnpinBar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { +LL | match *bar_const { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:133:9 + --> $DIR/pattern-matching.rs:103:18 | -LL | match baz { - | --- this expression has type `Pin<&mut Baz, Baz>>` -... -LL | Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut Baz, Baz>>`, found `Baz<_, _>` +LL | _ if let NegUnpinBar::Foo(x, y) = bar_const => { + | ^^^^^^^^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinBar>` + | | + | expected `Pin<&NegUnpinBar>`, found `NegUnpinBar<_, _>` | - = note: expected struct `Pin<&mut Baz, Baz>>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&NegUnpinBar>` + found enum `NegUnpinBar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { - | + +LL | _ if let NegUnpinBar::Foo(x, y) = *bar_const => { + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:145:9 + --> $DIR/pattern-matching.rs:116:9 | -LL | match baz { - | --- this expression has type `Pin<&Baz, Baz>>` -LL | Baz::Foo(foo, _) if let Baz::Foo(x, y) = foo => { - | ^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` +LL | let (NegUnpinFoo { x, y },) = foo_mut; + | ^^^^^^^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut (NegUnpinFoo,)>` + | | + | expected `Pin<&mut (NegUnpinFoo,)>`, found `(_,)` | - = note: expected struct `Pin<&Baz, Baz>>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&mut (NegUnpinFoo,)>` + found tuple `(_,)` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { - | + +LL | let (NegUnpinFoo { x, y },) = *foo_mut; + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:150:9 + --> $DIR/pattern-matching.rs:120:9 | -LL | match baz { - | --- this expression has type `Pin<&Baz, Baz>>` -... -LL | Baz::Bar { x: _, y: bar } if let Baz::Bar { x, y } = bar => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` +LL | let (NegUnpinFoo { x, y },) = foo_const; + | ^^^^^^^^^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&(NegUnpinFoo,)>` + | | + | expected `Pin<&(NegUnpinFoo,)>`, found `(_,)` | - = note: expected struct `Pin<&Baz, Baz>>` - found enum `Baz<_, _>` + = note: expected struct `Pin<&(NegUnpinFoo,)>` + found tuple `(_,)` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *baz { - | + +LL | let (NegUnpinFoo { x, y },) = *foo_const; + | + -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:155:9 - | -LL | match baz { - | --- this expression has type `Pin<&Baz, Baz>>` -... -LL | Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` - | - = note: expected struct `Pin<&Baz, Baz>>` - found enum `Baz<_, _>` -help: consider dereferencing to access the inner value using the Deref trait +error[E0529]: expected an array or slice, found `Pin<&mut [NegUnpinFoo; 1]>` + --> $DIR/pattern-matching.rs:130:9 | -LL | match *baz { - | + +LL | let [NegUnpinFoo { x, y }] = foo_mut; + | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [NegUnpinFoo; 1]>` -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:162:9 - | -LL | match baz { - | --- this expression has type `Pin<&Baz, Baz>>` -... -LL | Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` - | - = note: expected struct `Pin<&Baz, Baz>>` - found enum `Baz<_, _>` -help: consider dereferencing to access the inner value using the Deref trait +error[E0529]: expected an array or slice, found `Pin<&[NegUnpinFoo; 1]>` + --> $DIR/pattern-matching.rs:134:9 | -LL | match *baz { - | + +LL | let [NegUnpinFoo { x, y }] = foo_const; + | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[NegUnpinFoo; 1]>` -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:169:9 - | -LL | match baz { - | --- this expression has type `Pin<&Baz, Baz>>` -... -LL | Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` +error[E0529]: expected an array or slice, found `Pin<&mut [NegUnpinFoo]>` + --> $DIR/pattern-matching.rs:144:12 | - = note: expected struct `Pin<&Baz, Baz>>` - found enum `Baz<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | match *baz { - | + +LL | if let [NegUnpinFoo { x, y }] = foo_mut { + | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [NegUnpinFoo]>` -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:176:9 +error[E0529]: expected an array or slice, found `Pin<&[NegUnpinFoo]>` + --> $DIR/pattern-matching.rs:149:12 | -LL | match baz { - | --- this expression has type `Pin<&Baz, Baz>>` -... -LL | Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&Baz, Baz>>`, found `Baz<_, _>` - | - = note: expected struct `Pin<&Baz, Baz>>` - found enum `Baz<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | match *baz { - | + +LL | if let [NegUnpinFoo { x, y }] = foo_const { + | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[NegUnpinFoo]>` -error: aborting due to 20 previous errors +error: aborting due to 16 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0308, E0529. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching.rs b/tests/ui/pin-ergonomics/pattern-matching.rs index e480ebfc00626..42cb86d7fdc6f 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.rs +++ b/tests/ui/pin-ergonomics/pattern-matching.rs @@ -2,27 +2,32 @@ //@ edition:2024 //@[pin_ergonomics] check-pass #![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] -#![feature(if_let_guard)] +#![feature(if_let_guard, negative_impls)] #![allow(incomplete_features)] use std::pin::Pin; -// This test verifies that a `&pin mut Foo` can be projected to a pinned -// reference `&pin mut T` of a `?Unpin` field , and can be projected to -// an unpinned reference `&mut U` of an `Unpin` field. +// This test verifies that a `&pin mut T` can be projected to a pinned +// reference field `&pin mut T.U` when `T: !Unpin` or when `U: Unpin`. struct Foo { x: T, y: U, } -struct Bar(T, U); +struct NegUnpinFoo { + x: T, + y: U, +} -enum Baz { +enum NegUnpinBar { Foo(T, U), Bar { x: T, y: U }, } +impl !Unpin for NegUnpinFoo {} +impl !Unpin for NegUnpinBar {} + trait IsPinMut {} trait IsPinConst {} impl IsPinMut for Pin<&mut T> {} @@ -31,155 +36,120 @@ impl IsPinConst for Pin<&T> {} fn assert_pin_mut(_: T) {} fn assert_pin_const(_: T) {} -fn foo_mut(foo: Pin<&mut Foo>) { - let Foo { x, y } = foo; +// Pinned references can be projected to pinned references of `Unpin` fields +fn unpin2unpin(foo_mut: Pin<&mut Foo>, foo_const: Pin<&Foo>) { + let Foo { x, y } = foo_mut; //[normal]~^ ERROR mismatched types assert_pin_mut(x); assert_pin_mut(y); -} -fn foo_const(foo: Pin<&Foo>) { - let Foo { x, y } = foo; + let Foo { x, y } = foo_const; //[normal]~^ ERROR mismatched types assert_pin_const(x); assert_pin_const(y); } -fn bar_mut(bar: Pin<&mut Bar>) { - let Bar(x, y) = bar; +// Pinned references can be only projected to pinned references of `Unpin` fields +fn unpin2partial_unpin(foo_mut: Pin<&mut Foo>, foo_const: Pin<&Foo>) { + let Foo { x, .. } = foo_mut; //[normal]~^ ERROR mismatched types assert_pin_mut(x); - assert_pin_mut(y); -} -fn bar_const(bar: Pin<&Bar>) { - let Bar(x, y) = bar; + let Foo { x, .. } = foo_const; //[normal]~^ ERROR mismatched types assert_pin_const(x); - assert_pin_const(y); } -fn foo_bar_mut(foo: Pin<&mut Foo, Bar>>) { - let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; +// Pinned references of `!Unpin` types can be projected to pinned references +fn neg_unpin2not_unpin( + foo_mut: Pin<&mut NegUnpinFoo>, + foo_const: Pin<&NegUnpinFoo>, +) { + let NegUnpinFoo { x, y } = foo_mut; //[normal]~^ ERROR mismatched types assert_pin_mut(x); assert_pin_mut(y); - assert_pin_mut(z); - assert_pin_mut(w); -} -fn foo_bar_const(foo: Pin<&Foo, Bar>>) { - let Foo { x: Bar(x, y), y: Bar(z, w) } = foo; + let NegUnpinFoo { x, y } = foo_const; //[normal]~^ ERROR mismatched types assert_pin_const(x); assert_pin_const(y); - assert_pin_const(z); - assert_pin_const(w); } -fn baz_mut(baz: Pin<&mut Baz>) { - match baz { - Baz::Foo(x, y) => { +// Pinned references of `!Unpin` types can be projected to pinned references of `Unpin` fields +fn neg_unpin2unpin( + bar_mut: Pin<&mut NegUnpinBar>, + bar_const: Pin<&NegUnpinBar>, +) { + match bar_mut { + NegUnpinBar::Foo(x, y) => { //[normal]~^ ERROR mismatched types assert_pin_mut(x); assert_pin_mut(y); } - Baz::Bar { x, y } => { + _ if let NegUnpinBar::Bar { x, y } = bar_mut => { //[normal]~^ ERROR mismatched types assert_pin_mut(x); assert_pin_mut(y); } + _ => {} } -} - -fn baz_const(baz: Pin<&Baz>) { - match baz { - Baz::Foo(x, y) => { + match bar_const { + NegUnpinBar::Bar { x, y } => { //[normal]~^ ERROR mismatched types assert_pin_const(x); assert_pin_const(y); } - Baz::Bar { x, y } => { + _ if let NegUnpinBar::Foo(x, y) = bar_const => { //[normal]~^ ERROR mismatched types assert_pin_const(x); assert_pin_const(y); } + _ => {} } } -fn baz_baz_mut(baz: Pin<&mut Baz, Baz>>) { - match baz { - Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - //[normal]~^ ERROR mismatched types - assert_pin_mut(x); - assert_pin_mut(y); - assert_pin_mut(z); - assert_pin_mut(w); - } - Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - //[normal]~^ ERROR mismatched types - assert_pin_mut(x); - assert_pin_mut(y); - assert_pin_mut(z); - assert_pin_mut(w); - } - Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - //[normal]~^ ERROR mismatched types - assert_pin_mut(x); - assert_pin_mut(y); - assert_pin_mut(z); - assert_pin_mut(w); - } - Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - //[normal]~^ ERROR mismatched types - assert_pin_mut(x); - assert_pin_mut(y); - assert_pin_mut(z); - assert_pin_mut(w); - } - } +fn neg_unpin_tuple( + foo_mut: Pin<&mut (NegUnpinFoo,)>, + foo_const: Pin<&(NegUnpinFoo,)>, +) { + let (NegUnpinFoo { x, y },) = foo_mut; + //[normal]~^ ERROR mismatched types + assert_pin_mut(x); + assert_pin_mut(y); + let (NegUnpinFoo { x, y },) = foo_const; + //[normal]~^ ERROR mismatched types + assert_pin_const(x); + assert_pin_const(y); } -fn baz_baz_const(baz: Pin<&Baz, Baz>>) { - match baz { - Baz::Foo(foo, _) if let Baz::Foo(x, y) = foo => { - //[normal]~^ ERROR mismatched types - assert_pin_const(x); - assert_pin_const(y); - } - Baz::Bar { x: _, y: bar } if let Baz::Bar { x, y } = bar => { - //[normal]~^ ERROR mismatched types - assert_pin_const(x); - assert_pin_const(y); - } - Baz::Foo(Baz::Foo(x, y), Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - //[normal]~^ ERROR mismatched types - assert_pin_const(x); - assert_pin_const(y); - assert_pin_const(z); - assert_pin_const(w); - } - Baz::Foo(Baz::Bar { x, y }, Baz::Foo(z, w) | Baz::Bar { x: z, y: w }) => { - //[normal]~^ ERROR mismatched types - assert_pin_const(x); - assert_pin_const(y); - assert_pin_const(z); - assert_pin_const(w); - } - Baz::Bar { x: Baz::Foo(x, y), y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - //[normal]~^ ERROR mismatched types - assert_pin_const(x); - assert_pin_const(y); - assert_pin_const(z); - assert_pin_const(w); - } - Baz::Bar { x: Baz::Bar { x, y }, y: Baz::Foo(z, w) | Baz::Bar { x: z, y: w } } => { - //[normal]~^ ERROR mismatched types - assert_pin_const(x); - assert_pin_const(y); - assert_pin_const(z); - assert_pin_const(w); - } +fn neg_unpin_array( + foo_mut: Pin<&mut [NegUnpinFoo; 1]>, + foo_const: Pin<&[NegUnpinFoo; 1]>, +) { + let [NegUnpinFoo { x, y }] = foo_mut; + //[normal]~^ ERROR expected an array or slice, found `Pin<&mut [NegUnpinFoo; 1]>` + assert_pin_mut(x); + assert_pin_mut(y); + let [NegUnpinFoo { x, y }] = foo_const; + //[normal]~^ ERROR expected an array or slice, found `Pin<&[NegUnpinFoo; 1]>` + assert_pin_const(x); + assert_pin_const(y); +} + +fn neg_unpin_slice( + foo_mut: Pin<&mut [NegUnpinFoo]>, + foo_const: Pin<&[NegUnpinFoo]>, +) { + if let [NegUnpinFoo { x, y }] = foo_mut { + //[normal]~^ ERROR expected an array or slice, found `Pin<&mut [NegUnpinFoo]>` + assert_pin_mut(x); + assert_pin_mut(y); + } + if let [NegUnpinFoo { x, y }] = foo_const { + //[normal]~^ ERROR expected an array or slice, found `Pin<&[NegUnpinFoo]>` + assert_pin_const(x); + assert_pin_const(y); } } diff --git a/tests/ui/pin-ergonomics/projection-unpin-checks.rs b/tests/ui/pin-ergonomics/projection-unpin-checks.rs new file mode 100644 index 0000000000000..3a7c4f04c6903 --- /dev/null +++ b/tests/ui/pin-ergonomics/projection-unpin-checks.rs @@ -0,0 +1,132 @@ +//@ edition:2024 +#![feature(pin_ergonomics, negative_impls)] +#![allow(incomplete_features)] + +// This test verifies that a `&pin mut T` cannot be projected to a pinned +// reference field `&pin mut T.U` if neither `T: !Unpin` nor `U: Unpin`. + +struct Foo(T); +struct NotUnpinFoo(T, std::marker::PhantomPinned); +struct NegUnpinFoo(T); + +impl !Unpin for NegUnpinFoo {} + +fn unpin2not_unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + let Foo(_x) = foo_mut; //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] + let Foo(_x) = foo_const; //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] + let Foo(_x) = (|| foo_mut)(); //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] + let Foo(_x) = (|| foo_const)(); //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] + let &mut _foo_mut = foo_mut; //~ ERROR mismatched types + let &_foo_const = foo_const; //~ ERROR mismatched types + // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready + // let &pin mut _foo_mut = foo_mut; // error + // let &pin mut _foo_const = foo_const; // error +} + +fn unpin2unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { + let Foo(_x) = foo_mut; // ok + let Foo(_x) = foo_const; // ok + let Foo(_x) = (|| foo_mut)(); // ok + let Foo(_x) = (|| foo_const)(); // ok + let &mut _foo_mut = foo_mut; //~ ERROR mismatched types + let &_foo_const = foo_const; //~ ERROR mismatched types + // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready + // let &pin mut _foo_mut = foo_mut; // ok + // let &pin mut _foo_const = foo_const; // ok +} + +fn not_unpin2not_unpin(foo_mut: &pin mut NotUnpinFoo, foo_const: &pin const NotUnpinFoo) { + let NotUnpinFoo(_x, _) = foo_mut; //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] + let NotUnpinFoo(_x, _) = foo_const; //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] + let NotUnpinFoo(_x, _) = (|| foo_mut)(); //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] + let NotUnpinFoo(_x, _) = (|| foo_const)(); //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] + let &mut _foo_mut = foo_mut; //~ ERROR mismatched types + let &_foo_const = foo_const; //~ ERROR mismatched types + // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready + // let &pin mut _foo_mut = foo_mut; // error + // let &pin mut _foo_const = foo_const; // error +} + +fn not_unpin2unpin( + foo_mut: &pin mut NotUnpinFoo, + foo_const: &pin const NotUnpinFoo, +) { + let NotUnpinFoo(_x, _) = foo_mut; // ok + let NotUnpinFoo(_x, _) = foo_const; // ok + let NotUnpinFoo(_x, _) = (|| foo_mut)(); // ok + let NotUnpinFoo(_x, _) = (|| foo_const)(); // ok + let &mut _foo_mut = foo_mut; //~ ERROR mismatched types + let &_foo_const = foo_const; //~ ERROR mismatched types + // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready + // let &pin mut _foo_mut = foo_mut; // ok + // let &pin mut _foo_const = foo_const; // ok +} + +fn neg_unpin2not_unpin(foo_mut: &pin mut NegUnpinFoo, foo_const: &pin const NegUnpinFoo) { + let NegUnpinFoo(_x) = foo_mut; // ok + let NegUnpinFoo(_x) = foo_const; // ok + let NegUnpinFoo(_x) = (|| foo_mut)(); // ok + let NegUnpinFoo(_x) = (|| foo_const)(); // ok + let &mut _foo_mut = foo_mut; //~ ERROR mismatched types + let &_foo_const = foo_const; //~ ERROR mismatched types + // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready + // let &pin mut _foo_mut = foo_mut; // ok + // let &pin mut _foo_const = foo_const; // ok +} + +fn neg_unpin2unpin( + foo_mut: &pin mut NegUnpinFoo, + foo_const: &pin const NegUnpinFoo, +) { + let NegUnpinFoo(_x) = foo_mut; // ok + let NegUnpinFoo(_x) = foo_const; // ok + let NegUnpinFoo(_x) = (|| foo_mut)(); // ok + let NegUnpinFoo(_x) = (|| foo_const)(); // ok + let &mut _foo_mut = foo_mut; //~ ERROR mismatched types + let &_foo_const = foo_const; //~ ERROR mismatched types + // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready + // let &pin mut _foo_mut = foo_mut; // ok + // let &pin mut _foo_const = foo_const; // ok +} + +fn tuple_ref_mut_pat_and_pin_mut_of_tuple_mut_ty<'a, T>( + (&mut x,): &'a pin mut (&'a mut NegUnpinFoo,), + //~^ ERROR the trait bound `&'a mut NegUnpinFoo: !Unpin` is not satisfied in `(&'a mut NegUnpinFoo,)` [E0277] +) -> &'a pin mut NegUnpinFoo { + x +} + +fn tuple_ref_mut_pat_and_pin_mut_of_mut_tuple_ty<'a, T>( + (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), + //~^ ERROR mismatched type + //~| ERROR the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied [E0277] +) -> &'a pin mut NegUnpinFoo { + x +} + +fn ref_mut_tuple_pat_and_pin_mut_of_tuple_mut_ty<'a, T>( + &mut (x,): &'a pin mut (&'a mut NegUnpinFoo,), //~ ERROR mismatched type +) -> &'a pin mut NegUnpinFoo { + x +} + +fn ref_mut_tuple_pat_and_pin_mut_of_mut_tuple_ty<'a, T>( + &mut (x,): &'a pin mut &'a mut (NegUnpinFoo,), //~ ERROR mismatched type +) -> &'a pin mut NegUnpinFoo { + x +} + +fn tuple_pat_and_pin_mut_of_tuple_mut_ty<'a, T>( + (x,): &'a pin mut (&'a mut NegUnpinFoo,), +) -> &'a pin mut &'a mut NegUnpinFoo { + x // ok +} + +fn tuple_pat_and_pin_mut_of_mut_tuple_ty<'a, T>( + (x,): &'a pin mut &'a mut (NegUnpinFoo,), + //~^ ERROR the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied [E0277] +) -> &'a pin mut NegUnpinFoo { + x +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/projection-unpin-checks.stderr b/tests/ui/pin-ergonomics/projection-unpin-checks.stderr new file mode 100644 index 0000000000000..c79e1e11b0771 --- /dev/null +++ b/tests/ui/pin-ergonomics/projection-unpin-checks.stderr @@ -0,0 +1,333 @@ +error[E0277]: the trait bound `Foo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:15:9 + | +LL | let Foo(_x) = foo_mut; + | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied + +error[E0277]: the trait bound `Foo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:16:9 + | +LL | let Foo(_x) = foo_const; + | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied + +error[E0277]: the trait bound `Foo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:17:9 + | +LL | let Foo(_x) = (|| foo_mut)(); + | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied + +error[E0277]: the trait bound `Foo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:18:9 + | +LL | let Foo(_x) = (|| foo_const)(); + | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:19:9 + | +LL | let &mut _foo_mut = foo_mut; + | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` + | | + | expected `Pin<&mut Foo>`, found `&mut _` + | + = note: expected struct `Pin<&mut Foo>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&mut Foo` + | +LL | let &mut _foo_mut = foo_mut.pointer; + | ++++++++ +help: to declare a mutable variable use + | +LL - let &mut _foo_mut = foo_mut; +LL + let mut _foo_mut = foo_mut; + | + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:20:9 + | +LL | let &_foo_const = foo_const; + | ^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` + | | + | expected `Pin<&Foo>`, found `&_` + | + = note: expected struct `Pin<&Foo>` + found reference `&_` +help: you might have meant to use field `pointer` whose type is `&Foo` + | +LL | let &_foo_const = foo_const.pointer; + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:31:9 + | +LL | let &mut _foo_mut = foo_mut; + | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` + | | + | expected `Pin<&mut Foo>`, found `&mut _` + | + = note: expected struct `Pin<&mut Foo>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&mut Foo` + | +LL | let &mut _foo_mut = foo_mut.pointer; + | ++++++++ +help: to declare a mutable variable use + | +LL - let &mut _foo_mut = foo_mut; +LL + let mut _foo_mut = foo_mut; + | + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:32:9 + | +LL | let &_foo_const = foo_const; + | ^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` + | | + | expected `Pin<&Foo>`, found `&_` + | + = note: expected struct `Pin<&Foo>` + found reference `&_` +help: you might have meant to use field `pointer` whose type is `&Foo` + | +LL | let &_foo_const = foo_const.pointer; + | ++++++++ + +error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:39:9 + | +LL | let NotUnpinFoo(_x, _) = foo_mut; + | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied + +error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:40:9 + | +LL | let NotUnpinFoo(_x, _) = foo_const; + | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied + +error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:41:9 + | +LL | let NotUnpinFoo(_x, _) = (|| foo_mut)(); + | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied + +error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:42:9 + | +LL | let NotUnpinFoo(_x, _) = (|| foo_const)(); + | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:43:9 + | +LL | let &mut _foo_mut = foo_mut; + | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NotUnpinFoo>` + | | + | expected `Pin<&mut NotUnpinFoo>`, found `&mut _` + | + = note: expected struct `Pin<&mut NotUnpinFoo>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&mut NotUnpinFoo` + | +LL | let &mut _foo_mut = foo_mut.pointer; + | ++++++++ +help: to declare a mutable variable use + | +LL - let &mut _foo_mut = foo_mut; +LL + let mut _foo_mut = foo_mut; + | + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:44:9 + | +LL | let &_foo_const = foo_const; + | ^^^^^^^^^^^ --------- this expression has type `Pin<&NotUnpinFoo>` + | | + | expected `Pin<&NotUnpinFoo>`, found `&_` + | + = note: expected struct `Pin<&NotUnpinFoo>` + found reference `&_` +help: you might have meant to use field `pointer` whose type is `&NotUnpinFoo` + | +LL | let &_foo_const = foo_const.pointer; + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:58:9 + | +LL | let &mut _foo_mut = foo_mut; + | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NotUnpinFoo>` + | | + | expected `Pin<&mut NotUnpinFoo>`, found `&mut _` + | + = note: expected struct `Pin<&mut NotUnpinFoo>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&mut NotUnpinFoo` + | +LL | let &mut _foo_mut = foo_mut.pointer; + | ++++++++ +help: to declare a mutable variable use + | +LL - let &mut _foo_mut = foo_mut; +LL + let mut _foo_mut = foo_mut; + | + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:59:9 + | +LL | let &_foo_const = foo_const; + | ^^^^^^^^^^^ --------- this expression has type `Pin<&NotUnpinFoo>` + | | + | expected `Pin<&NotUnpinFoo>`, found `&_` + | + = note: expected struct `Pin<&NotUnpinFoo>` + found reference `&_` +help: you might have meant to use field `pointer` whose type is `&NotUnpinFoo` + | +LL | let &_foo_const = foo_const.pointer; + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:70:9 + | +LL | let &mut _foo_mut = foo_mut; + | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinFoo>` + | | + | expected `Pin<&mut NegUnpinFoo>`, found `&mut _` + | + = note: expected struct `Pin<&mut NegUnpinFoo>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&mut NegUnpinFoo` + | +LL | let &mut _foo_mut = foo_mut.pointer; + | ++++++++ +help: to declare a mutable variable use + | +LL - let &mut _foo_mut = foo_mut; +LL + let mut _foo_mut = foo_mut; + | + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:71:9 + | +LL | let &_foo_const = foo_const; + | ^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinFoo>` + | | + | expected `Pin<&NegUnpinFoo>`, found `&_` + | + = note: expected struct `Pin<&NegUnpinFoo>` + found reference `&_` +help: you might have meant to use field `pointer` whose type is `&NegUnpinFoo` + | +LL | let &_foo_const = foo_const.pointer; + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:85:9 + | +LL | let &mut _foo_mut = foo_mut; + | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinFoo>` + | | + | expected `Pin<&mut NegUnpinFoo>`, found `&mut _` + | + = note: expected struct `Pin<&mut NegUnpinFoo>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&mut NegUnpinFoo` + | +LL | let &mut _foo_mut = foo_mut.pointer; + | ++++++++ +help: to declare a mutable variable use + | +LL - let &mut _foo_mut = foo_mut; +LL + let mut _foo_mut = foo_mut; + | + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:86:9 + | +LL | let &_foo_const = foo_const; + | ^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinFoo>` + | | + | expected `Pin<&NegUnpinFoo>`, found `&_` + | + = note: expected struct `Pin<&NegUnpinFoo>` + found reference `&_` +help: you might have meant to use field `pointer` whose type is `&NegUnpinFoo` + | +LL | let &_foo_const = foo_const.pointer; + | ++++++++ + +error[E0277]: the trait bound `&'a mut NegUnpinFoo: !Unpin` is not satisfied in `(&'a mut NegUnpinFoo,)` + --> $DIR/projection-unpin-checks.rs:93:5 + | +LL | (&mut x,): &'a pin mut (&'a mut NegUnpinFoo,), + | ^^^^^^^^^ within `(&'a mut NegUnpinFoo,)`, the trait bound `&'a mut NegUnpinFoo: !Unpin` is not satisfied + | + = note: required because it appears within the type `(&'a mut NegUnpinFoo,)` + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:100:6 + | +LL | (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), + | ^^^^^^ ------------------------------------- expected due to this + | | + | expected `NegUnpinFoo`, found `&mut _` + | + = note: expected struct `NegUnpinFoo` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/projection-unpin-checks.rs:100:6 + | +LL | (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), +LL + (x,): &'a pin mut &'a mut (NegUnpinFoo,), + | + +error[E0277]: the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:100:5 + | +LL | (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), + | ^^^^^^^^^ the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:108:5 + | +LL | &mut (x,): &'a pin mut (&'a mut NegUnpinFoo,), + | ^^^^^^^^^ ------------------------------------- expected due to this + | | + | expected `Pin<&mut (&mut NegUnpinFoo,)>`, found `&mut _` + | + = note: expected struct `Pin<&'a mut (&'a mut NegUnpinFoo,)>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&'a mut (&'a mut NegUnpinFoo,)` + | +LL | &mut (x,): &'a pin mut (&'a mut NegUnpinFoo,).pointer, + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/projection-unpin-checks.rs:114:5 + | +LL | &mut (x,): &'a pin mut &'a mut (NegUnpinFoo,), + | ^^^^^^^^^ ------------------------------------- expected due to this + | | + | expected `Pin<&mut &mut (NegUnpinFoo,)>`, found `&mut _` + | + = note: expected struct `Pin<&'a mut &'a mut (NegUnpinFoo,)>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&'a mut &'a mut (NegUnpinFoo,)` + | +LL | &mut (x,): &'a pin mut &'a mut (NegUnpinFoo,).pointer, + | ++++++++ + +error[E0277]: the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied + --> $DIR/projection-unpin-checks.rs:126:5 + | +LL | (x,): &'a pin mut &'a mut (NegUnpinFoo,), + | ^^^^ the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied + +error: aborting due to 26 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From 7070709cca9af5f2216ca229464a806c74fc29db Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 3 Aug 2025 11:10:59 +0800 Subject: [PATCH 14/45] Remove `!Unpin` related bounds --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 25 +- compiler/rustc_hir_typeck/src/pat.rs | 88 +---- .../src/traits/select/candidate_assembly.rs | 76 +--- .../src/traits/select/confirmation.rs | 5 - .../src/traits/select/mod.rs | 51 +-- .../pattern-matching.normal.stderr | 182 ++++------ tests/ui/pin-ergonomics/pattern-matching.rs | 94 ++--- .../pin-ergonomics/projection-unpin-checks.rs | 132 ------- .../projection-unpin-checks.stderr | 333 ------------------ 9 files changed, 105 insertions(+), 881 deletions(-) delete mode 100644 tests/ui/pin-ergonomics/projection-unpin-checks.rs delete mode 100644 tests/ui/pin-ergonomics/projection-unpin-checks.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ec67efe6399e3..dde6b8ce9b8b2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -23,7 +23,7 @@ use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity, - SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, Upcast, UserArgs, + SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, UserSelfTy, }; use rustc_middle::{bug, span_bug}; @@ -464,29 +464,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(crate) fn register_negative_bound( - &self, - ty: Ty<'tcx>, - def_id: DefId, - cause: traits::ObligationCause<'tcx>, - ) { - if !ty.references_error() { - let trait_ref = ty::TraitRef::new(self.tcx, def_id, [ty]); - let predicate = - ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative } - .upcast(self.tcx); - self.fulfillment_cx.borrow_mut().register_predicate_obligation( - self, - traits::Obligation { - cause, - recursion_depth: 0, - param_env: self.param_env, - predicate, - }, - ); - } - } - pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> { let ty = self.lowerer().lower_ty(hir_ty); self.register_wf_obligation(ty.into(), hir_ty.span, ObligationCauseCode::WellFormed(None)); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 3a6b11653c031..615e80f1ba0e5 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -27,7 +27,7 @@ use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym}; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt}; +use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode}; use tracing::{debug, instrument, trace}; use ty::VariantDef; use ty::adjustment::{PatAdjust, PatAdjustment}; @@ -403,38 +403,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.check_pat_inner(pat, opt_path_res, adjust_mode, expected, pat_info); self.write_ty(pat.hir_id, ty); - // If we implicitly inserted overloaded dereferences and pinned dereferences before matching, - // check the pattern to see if the dereferenced types need `DerefMut` or `!Unpin` bounds. - if let Some(derefed_tys) = self.typeck_results.borrow().pat_adjustments().get(pat.hir_id) { - let mut has_overloaded_deref = false; - let mut has_pin_deref = false; - derefed_tys.iter().for_each(|adjust| match adjust.kind { - PatAdjust::BuiltinDeref => {} - PatAdjust::OverloadedDeref => has_overloaded_deref = true, - PatAdjust::PinDeref => has_pin_deref = true, - }); - if has_overloaded_deref { - self.register_deref_mut_bounds_if_needed( - pat.span, - pat, - derefed_tys.iter().filter_map(|adjust| match adjust.kind { - PatAdjust::OverloadedDeref => Some(adjust.source), - PatAdjust::BuiltinDeref | PatAdjust::PinDeref => None, - }), - ); - } - if has_pin_deref { - self.register_not_unpin_bounds_if_needed( - pat.span, - pat, - derefed_tys.iter().filter_map(|adjust| match adjust.kind { - PatAdjust::BuiltinDeref | PatAdjust::OverloadedDeref => None, - PatAdjust::PinDeref => { - Some(adjust.source.pinned_ref().expect("expected pinned reference").0) - } - }), - ); - } + // If we implicitly inserted overloaded dereferences before matching check the pattern to + // see if the dereferenced types need `DerefMut` bounds. + if let Some(derefed_tys) = self.typeck_results.borrow().pat_adjustments().get(pat.hir_id) + && derefed_tys.iter().any(|adjust| adjust.kind == PatAdjust::OverloadedDeref) + { + self.register_deref_mut_bounds_if_needed( + pat.span, + pat, + derefed_tys.iter().filter_map(|adjust| match adjust.kind { + PatAdjust::OverloadedDeref => Some(adjust.source), + PatAdjust::BuiltinDeref | PatAdjust::PinDeref => None, + }), + ); } // (note_1): In most of the cases where (note_1) is referenced @@ -583,9 +564,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.misc(pat.span), ) } - // Once we've checked `pat`, we'll add a `!Unpin` bound if it contains any - // `ref pin` bindings. See `Self::register_not_unpin_bounds_if_needed`. - debug!("default binding mode is now {:?}", binding_mode); // Use the old pat info to keep `current_depth` to its old value. @@ -2679,44 +2657,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - /// Check if the interior of a pin pattern (either explicit or implicit) has any `ref pin` - /// bindings of non-`Unpin` types, which would require `!Unpin` to be emitted. - fn register_not_unpin_bounds_if_needed( - &self, - span: Span, - inner: &'tcx Pat<'tcx>, - derefed_tys: impl IntoIterator>, - ) { - // Check if there are subpatterns with `ref pin` binding modes of non-`Unpin` types. - let unpin = self.tcx.require_lang_item(hir::LangItem::Unpin, span); - let cause = self.misc(span); - let unpin_obligations = self.probe(|_| { - let ocx = ObligationCtxt::new(&self); - self.typeck_results.borrow().pat_walk_ref_pin_binding_of_non_unpin_type(inner, |ty| { - let ty = ocx - .normalize(&cause, self.param_env, ty) - .pinned_ref() - .expect("expect pinned reference") - .0; - debug!("check if `Unpin` is implemented for `{ty:?}`"); - ocx.register_bound(cause.clone(), self.param_env, ty, unpin); - }); - ocx.select_all_or_error() - }); - - // If any, the current pattern type should implement `!Unpin`. - if !unpin_obligations.is_empty() { - for pinned_derefed_ty in derefed_tys { - debug!("register `!Unpin` for `{pinned_derefed_ty:?}`"); - self.register_negative_bound( - pinned_derefed_ty, - self.tcx.require_lang_item(hir::LangItem::Unpin, span), - self.misc(span), - ); - } - } - } - // Precondition: Pat is Ref(inner) fn check_pat_ref( &self, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 12c8aa424d6d2..cecb43e537a8e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -52,35 +52,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; - let def_id = obligation.predicate.def_id(); - let tcx = self.tcx(); - - let lang_item = tcx.as_lang_item(def_id); - // Negative trait predicates have different rules than positive trait predicates. if obligation.polarity() == ty::PredicatePolarity::Negative { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); self.assemble_candidates_from_impls(obligation, &mut candidates); self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?; - - match lang_item { - Some(LangItem::Unpin) if tcx.features().pin_ergonomics() => { - debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty()); - - // impl `!Unpin` automatically for tuples, slices, and arrays - // to support projections for pinned patterns. - self.assemble_builtin_neg_unpin_candidate( - obligation.predicate.self_ty().skip_binder(), - &mut candidates, - ); - } - _ => {} - } } else { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); // Other bounds. Consider both in-scope bounds from fn decl // and applicable impls. There is a certain set of precedence rules here. + let def_id = obligation.predicate.def_id(); + let tcx = self.tcx(); + + let lang_item = tcx.as_lang_item(def_id); match lang_item { Some(LangItem::Copy | LangItem::Clone) => { debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty()); @@ -1238,59 +1223,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - /// Assembles `!Unpin` candidates for built-in types with no libcore-defined - /// `!Unpin` impls. - #[instrument(level = "debug", skip(self, candidates))] - fn assemble_builtin_neg_unpin_candidate( - &mut self, - self_ty: Ty<'tcx>, - candidates: &mut SelectionCandidateSet<'tcx>, - ) { - match *self_ty.kind() { - // `Unpin` types - ty::FnDef(..) - | ty::FnPtr(..) - | ty::Error(_) - | ty::Uint(_) - | ty::Int(_) - | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) - | ty::Bool - | ty::Float(_) - | ty::Char - | ty::RawPtr(..) - | ty::Never - | ty::Ref(..) - | ty::Dynamic(..) - | ty::Str - | ty::Foreign(..) - | ty::UnsafeBinder(_) - | ty::Pat(..) => {} - - ty::Array(..) | ty::Slice(_) | ty::Tuple(_) => { - candidates.vec.push(BuiltinCandidate); - } - - // FIXME(pin_ergonomics): should we impl `!Unpin` for coroutines or closures? - ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) => {} - - ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {} - - ty::Infer(ty::TyVar(_)) => { - candidates.ambiguous = true; - } - - // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. - ty::Bound(..) => {} - - ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); - } - } - } - /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself. #[instrument(level = "debug", skip(self, candidates))] fn assemble_builtin_sized_candidate( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index d6b7fbdec78e1..88f512708ff04 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -250,9 +250,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { bug!("`PointeeSized` is removing during lowering"); } Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(self_ty), - Some(LangItem::Unpin) if obligation.polarity() == ty::PredicatePolarity::Negative => { - self.neg_unpin_conditions(self_ty) - } Some(LangItem::FusedIterator) => { if self.coroutine_is_gen(self_ty) { ty::Binder::dummy(vec![]) @@ -278,7 +275,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause, obligation.recursion_depth + 1, trait_def, - obligation.polarity(), types, ) } @@ -405,7 +401,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), obligation.recursion_depth + 1, obligation.predicate.def_id(), - obligation.polarity(), constituents.types, ); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e4207b3271d7a..ed63949ee022e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2272,52 +2272,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } - fn neg_unpin_conditions(&mut self, self_ty: Ty<'tcx>) -> ty::Binder<'tcx, Vec>> { - match *self_ty.kind() { - ty::Array(ty, _) | ty::Slice(ty) => { - // (*) binder moved here - ty::Binder::dummy(vec![ty]) - } - ty::Tuple(tys) => { - // (*) binder moved here - ty::Binder::dummy(tys.iter().collect()) - } - - // `Unpin` types - ty::FnDef(..) - | ty::FnPtr(..) - | ty::Error(_) - | ty::Uint(_) - | ty::Int(_) - | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) - | ty::Bool - | ty::Float(_) - | ty::Char - | ty::RawPtr(..) - | ty::Never - | ty::Ref(..) - | ty::Dynamic(..) - | ty::Str - | ty::Foreign(..) - | ty::UnsafeBinder(_) - | ty::Pat(..) => bug!("`Unpin` type cannot have `!Unpin` bound"), - - ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Infer(ty::TyVar(_)) - | ty::Bound(..) - | ty::Adt(..) - | ty::Alias(..) - | ty::Param(..) - | ty::Placeholder(..) - | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty) - } - } - } - fn coroutine_is_gen(&mut self, self_ty: Ty<'tcx>) -> bool { matches!(*self_ty.kind(), ty::Coroutine(did, ..) if self.tcx().coroutine_is_gen(did)) @@ -2468,7 +2422,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { cause: ObligationCause<'tcx>, recursion_depth: usize, trait_def_id: DefId, - polarity: ty::PredicatePolarity, types: Vec>, ) -> PredicateObligations<'tcx> { // Because the types were potentially derived from @@ -2513,10 +2466,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::TraitRef::new_from_args(tcx, trait_def_id, err_args) }; - let trait_predicate = ty::TraitPredicate { trait_ref, polarity }; - let obligation = - Obligation::new(self.tcx(), cause.clone(), param_env, trait_predicate); + Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref); obligations.push(obligation); obligations }) diff --git a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr index 5e91fae18cca5..1b4908abdc176 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:41:9 + --> $DIR/pattern-matching.rs:35:9 | LL | let Foo { x, y } = foo_mut; | ^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` @@ -14,7 +14,7 @@ LL | let Foo { x, y } = *foo_mut; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:46:9 + --> $DIR/pattern-matching.rs:40:9 | LL | let Foo { x, y } = foo_const; | ^^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` @@ -29,180 +29,120 @@ LL | let Foo { x, y } = *foo_const; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:54:9 - | -LL | let Foo { x, .. } = foo_mut; - | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` - | | - | expected `Pin<&mut Foo>`, found `Foo<_, _>` - | - = note: expected struct `Pin<&mut Foo>` - found struct `Foo<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | let Foo { x, .. } = *foo_mut; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:58:9 - | -LL | let Foo { x, .. } = foo_const; - | ^^^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` - | | - | expected `Pin<&Foo>`, found `Foo<_, _>` - | - = note: expected struct `Pin<&Foo>` - found struct `Foo<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | let Foo { x, .. } = *foo_const; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:68:9 - | -LL | let NegUnpinFoo { x, y } = foo_mut; - | ^^^^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinFoo>` - | | - | expected `Pin<&mut NegUnpinFoo>`, found `NegUnpinFoo<_, _>` - | - = note: expected struct `Pin<&mut NegUnpinFoo>` - found struct `NegUnpinFoo<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | let NegUnpinFoo { x, y } = *foo_mut; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:73:9 - | -LL | let NegUnpinFoo { x, y } = foo_const; - | ^^^^^^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinFoo>` - | | - | expected `Pin<&NegUnpinFoo>`, found `NegUnpinFoo<_, _>` - | - = note: expected struct `Pin<&NegUnpinFoo>` - found struct `NegUnpinFoo<_, _>` -help: consider dereferencing to access the inner value using the Deref trait - | -LL | let NegUnpinFoo { x, y } = *foo_const; - | + - -error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:85:9 + --> $DIR/pattern-matching.rs:48:9 | LL | match bar_mut { - | ------- this expression has type `Pin<&mut NegUnpinBar>` -LL | NegUnpinBar::Foo(x, y) => { - | ^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut NegUnpinBar>`, found `NegUnpinBar<_, _>` + | ------- this expression has type `Pin<&mut Bar>` +LL | Bar::Foo(x, y) => { + | ^^^^^^^^^^^^^^ expected `Pin<&mut Bar>`, found `Bar<_, _>` | - = note: expected struct `Pin<&mut NegUnpinBar>` - found enum `NegUnpinBar<_, _>` + = note: expected struct `Pin<&mut Bar>` + found enum `Bar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | LL | match *bar_mut { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:90:18 + --> $DIR/pattern-matching.rs:53:18 | -LL | _ if let NegUnpinBar::Bar { x, y } = bar_mut => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinBar>` +LL | _ if let Bar::Bar { x, y } = bar_mut => { + | ^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Bar>` | | - | expected `Pin<&mut NegUnpinBar>`, found `NegUnpinBar<_, _>` + | expected `Pin<&mut Bar>`, found `Bar<_, _>` | - = note: expected struct `Pin<&mut NegUnpinBar>` - found enum `NegUnpinBar<_, _>` + = note: expected struct `Pin<&mut Bar>` + found enum `Bar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | _ if let NegUnpinBar::Bar { x, y } = *bar_mut => { - | + +LL | _ if let Bar::Bar { x, y } = *bar_mut => { + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:98:9 + --> $DIR/pattern-matching.rs:61:9 | LL | match bar_const { - | --------- this expression has type `Pin<&NegUnpinBar>` -LL | NegUnpinBar::Bar { x, y } => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<&NegUnpinBar>`, found `NegUnpinBar<_, _>` + | --------- this expression has type `Pin<&Bar>` +LL | Bar::Bar { x, y } => { + | ^^^^^^^^^^^^^^^^^ expected `Pin<&Bar>`, found `Bar<_, _>` | - = note: expected struct `Pin<&NegUnpinBar>` - found enum `NegUnpinBar<_, _>` + = note: expected struct `Pin<&Bar>` + found enum `Bar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | LL | match *bar_const { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:103:18 + --> $DIR/pattern-matching.rs:66:18 | -LL | _ if let NegUnpinBar::Foo(x, y) = bar_const => { - | ^^^^^^^^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinBar>` +LL | _ if let Bar::Foo(x, y) = bar_const => { + | ^^^^^^^^^^^^^^ --------- this expression has type `Pin<&Bar>` | | - | expected `Pin<&NegUnpinBar>`, found `NegUnpinBar<_, _>` + | expected `Pin<&Bar>`, found `Bar<_, _>` | - = note: expected struct `Pin<&NegUnpinBar>` - found enum `NegUnpinBar<_, _>` + = note: expected struct `Pin<&Bar>` + found enum `Bar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | _ if let NegUnpinBar::Foo(x, y) = *bar_const => { - | + +LL | _ if let Bar::Foo(x, y) = *bar_const => { + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:116:9 + --> $DIR/pattern-matching.rs:76:9 | -LL | let (NegUnpinFoo { x, y },) = foo_mut; - | ^^^^^^^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut (NegUnpinFoo,)>` +LL | let (Foo { x, y },) = foo_mut; + | ^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut (Foo,)>` | | - | expected `Pin<&mut (NegUnpinFoo,)>`, found `(_,)` + | expected `Pin<&mut (Foo,)>`, found `(_,)` | - = note: expected struct `Pin<&mut (NegUnpinFoo,)>` + = note: expected struct `Pin<&mut (Foo,)>` found tuple `(_,)` help: consider dereferencing to access the inner value using the Deref trait | -LL | let (NegUnpinFoo { x, y },) = *foo_mut; - | + +LL | let (Foo { x, y },) = *foo_mut; + | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:120:9 + --> $DIR/pattern-matching.rs:80:9 | -LL | let (NegUnpinFoo { x, y },) = foo_const; - | ^^^^^^^^^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&(NegUnpinFoo,)>` +LL | let (Foo { x, y },) = foo_const; + | ^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&(Foo,)>` | | - | expected `Pin<&(NegUnpinFoo,)>`, found `(_,)` + | expected `Pin<&(Foo,)>`, found `(_,)` | - = note: expected struct `Pin<&(NegUnpinFoo,)>` + = note: expected struct `Pin<&(Foo,)>` found tuple `(_,)` help: consider dereferencing to access the inner value using the Deref trait | -LL | let (NegUnpinFoo { x, y },) = *foo_const; - | + +LL | let (Foo { x, y },) = *foo_const; + | + -error[E0529]: expected an array or slice, found `Pin<&mut [NegUnpinFoo; 1]>` - --> $DIR/pattern-matching.rs:130:9 +error[E0529]: expected an array or slice, found `Pin<&mut [Foo; 1]>` + --> $DIR/pattern-matching.rs:87:9 | -LL | let [NegUnpinFoo { x, y }] = foo_mut; - | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [NegUnpinFoo; 1]>` +LL | let [Foo { x, y }] = foo_mut; + | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [Foo; 1]>` -error[E0529]: expected an array or slice, found `Pin<&[NegUnpinFoo; 1]>` - --> $DIR/pattern-matching.rs:134:9 +error[E0529]: expected an array or slice, found `Pin<&[Foo; 1]>` + --> $DIR/pattern-matching.rs:91:9 | -LL | let [NegUnpinFoo { x, y }] = foo_const; - | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[NegUnpinFoo; 1]>` +LL | let [Foo { x, y }] = foo_const; + | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[Foo; 1]>` -error[E0529]: expected an array or slice, found `Pin<&mut [NegUnpinFoo]>` - --> $DIR/pattern-matching.rs:144:12 +error[E0529]: expected an array or slice, found `Pin<&mut [Foo]>` + --> $DIR/pattern-matching.rs:98:12 | -LL | if let [NegUnpinFoo { x, y }] = foo_mut { - | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [NegUnpinFoo]>` +LL | if let [Foo { x, y }] = foo_mut { + | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [Foo]>` -error[E0529]: expected an array or slice, found `Pin<&[NegUnpinFoo]>` - --> $DIR/pattern-matching.rs:149:12 +error[E0529]: expected an array or slice, found `Pin<&[Foo]>` + --> $DIR/pattern-matching.rs:103:12 | -LL | if let [NegUnpinFoo { x, y }] = foo_const { - | ^^^^^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[NegUnpinFoo]>` +LL | if let [Foo { x, y }] = foo_const { + | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[Foo]>` -error: aborting due to 16 previous errors +error: aborting due to 12 previous errors Some errors have detailed explanations: E0308, E0529. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching.rs b/tests/ui/pin-ergonomics/pattern-matching.rs index 42cb86d7fdc6f..8aff264aaa8e3 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.rs +++ b/tests/ui/pin-ergonomics/pattern-matching.rs @@ -8,26 +8,21 @@ use std::pin::Pin; // This test verifies that a `&pin mut T` can be projected to a pinned -// reference field `&pin mut T.U` when `T: !Unpin` or when `U: Unpin`. +// reference field `&pin mut T.U`. +// FIXME(pin_ergonomics): it is unsound to project `&pin mut T` to +// `&pin mut T.U` when `U: !Unpin` but `T: Unpin`, or when there exists +// `impl Drop for T` that takes a `&mut self` receiver. struct Foo { x: T, y: U, } -struct NegUnpinFoo { - x: T, - y: U, -} - -enum NegUnpinBar { +enum Bar { Foo(T, U), Bar { x: T, y: U }, } -impl !Unpin for NegUnpinFoo {} -impl !Unpin for NegUnpinBar {} - trait IsPinMut {} trait IsPinConst {} impl IsPinMut for Pin<&mut T> {} @@ -36,8 +31,7 @@ impl IsPinConst for Pin<&T> {} fn assert_pin_mut(_: T) {} fn assert_pin_const(_: T) {} -// Pinned references can be projected to pinned references of `Unpin` fields -fn unpin2unpin(foo_mut: Pin<&mut Foo>, foo_const: Pin<&Foo>) { +fn foo(foo_mut: Pin<&mut Foo>, foo_const: Pin<&Foo>) { let Foo { x, y } = foo_mut; //[normal]~^ ERROR mismatched types assert_pin_mut(x); @@ -49,45 +43,14 @@ fn unpin2unpin(foo_mut: Pin<&mut Foo>, foo_const: Pin< assert_pin_const(y); } -// Pinned references can be only projected to pinned references of `Unpin` fields -fn unpin2partial_unpin(foo_mut: Pin<&mut Foo>, foo_const: Pin<&Foo>) { - let Foo { x, .. } = foo_mut; - //[normal]~^ ERROR mismatched types - assert_pin_mut(x); - - let Foo { x, .. } = foo_const; - //[normal]~^ ERROR mismatched types - assert_pin_const(x); -} - -// Pinned references of `!Unpin` types can be projected to pinned references -fn neg_unpin2not_unpin( - foo_mut: Pin<&mut NegUnpinFoo>, - foo_const: Pin<&NegUnpinFoo>, -) { - let NegUnpinFoo { x, y } = foo_mut; - //[normal]~^ ERROR mismatched types - assert_pin_mut(x); - assert_pin_mut(y); - - let NegUnpinFoo { x, y } = foo_const; - //[normal]~^ ERROR mismatched types - assert_pin_const(x); - assert_pin_const(y); -} - -// Pinned references of `!Unpin` types can be projected to pinned references of `Unpin` fields -fn neg_unpin2unpin( - bar_mut: Pin<&mut NegUnpinBar>, - bar_const: Pin<&NegUnpinBar>, -) { +fn bar(bar_mut: Pin<&mut Bar>, bar_const: Pin<&Bar>) { match bar_mut { - NegUnpinBar::Foo(x, y) => { + Bar::Foo(x, y) => { //[normal]~^ ERROR mismatched types assert_pin_mut(x); assert_pin_mut(y); } - _ if let NegUnpinBar::Bar { x, y } = bar_mut => { + _ if let Bar::Bar { x, y } = bar_mut => { //[normal]~^ ERROR mismatched types assert_pin_mut(x); assert_pin_mut(y); @@ -95,12 +58,12 @@ fn neg_unpin2unpin( _ => {} } match bar_const { - NegUnpinBar::Bar { x, y } => { + Bar::Bar { x, y } => { //[normal]~^ ERROR mismatched types assert_pin_const(x); assert_pin_const(y); } - _ if let NegUnpinBar::Foo(x, y) = bar_const => { + _ if let Bar::Foo(x, y) = bar_const => { //[normal]~^ ERROR mismatched types assert_pin_const(x); assert_pin_const(y); @@ -109,45 +72,36 @@ fn neg_unpin2unpin( } } -fn neg_unpin_tuple( - foo_mut: Pin<&mut (NegUnpinFoo,)>, - foo_const: Pin<&(NegUnpinFoo,)>, -) { - let (NegUnpinFoo { x, y },) = foo_mut; +fn pin_mut_tuple(foo_mut: Pin<&mut (Foo,)>, foo_const: Pin<&(Foo,)>) { + let (Foo { x, y },) = foo_mut; //[normal]~^ ERROR mismatched types assert_pin_mut(x); assert_pin_mut(y); - let (NegUnpinFoo { x, y },) = foo_const; + let (Foo { x, y },) = foo_const; //[normal]~^ ERROR mismatched types assert_pin_const(x); assert_pin_const(y); } -fn neg_unpin_array( - foo_mut: Pin<&mut [NegUnpinFoo; 1]>, - foo_const: Pin<&[NegUnpinFoo; 1]>, -) { - let [NegUnpinFoo { x, y }] = foo_mut; - //[normal]~^ ERROR expected an array or slice, found `Pin<&mut [NegUnpinFoo; 1]>` +fn pin_mut_array(foo_mut: Pin<&mut [Foo; 1]>, foo_const: Pin<&[Foo; 1]>) { + let [Foo { x, y }] = foo_mut; + //[normal]~^ ERROR expected an array or slice, found `Pin<&mut [Foo; 1]>` assert_pin_mut(x); assert_pin_mut(y); - let [NegUnpinFoo { x, y }] = foo_const; - //[normal]~^ ERROR expected an array or slice, found `Pin<&[NegUnpinFoo; 1]>` + let [Foo { x, y }] = foo_const; + //[normal]~^ ERROR expected an array or slice, found `Pin<&[Foo; 1]>` assert_pin_const(x); assert_pin_const(y); } -fn neg_unpin_slice( - foo_mut: Pin<&mut [NegUnpinFoo]>, - foo_const: Pin<&[NegUnpinFoo]>, -) { - if let [NegUnpinFoo { x, y }] = foo_mut { - //[normal]~^ ERROR expected an array or slice, found `Pin<&mut [NegUnpinFoo]>` +fn pin_mut_slice(foo_mut: Pin<&mut [Foo]>, foo_const: Pin<&[Foo]>) { + if let [Foo { x, y }] = foo_mut { + //[normal]~^ ERROR expected an array or slice, found `Pin<&mut [Foo]>` assert_pin_mut(x); assert_pin_mut(y); } - if let [NegUnpinFoo { x, y }] = foo_const { - //[normal]~^ ERROR expected an array or slice, found `Pin<&[NegUnpinFoo]>` + if let [Foo { x, y }] = foo_const { + //[normal]~^ ERROR expected an array or slice, found `Pin<&[Foo]>` assert_pin_const(x); assert_pin_const(y); } diff --git a/tests/ui/pin-ergonomics/projection-unpin-checks.rs b/tests/ui/pin-ergonomics/projection-unpin-checks.rs deleted file mode 100644 index 3a7c4f04c6903..0000000000000 --- a/tests/ui/pin-ergonomics/projection-unpin-checks.rs +++ /dev/null @@ -1,132 +0,0 @@ -//@ edition:2024 -#![feature(pin_ergonomics, negative_impls)] -#![allow(incomplete_features)] - -// This test verifies that a `&pin mut T` cannot be projected to a pinned -// reference field `&pin mut T.U` if neither `T: !Unpin` nor `U: Unpin`. - -struct Foo(T); -struct NotUnpinFoo(T, std::marker::PhantomPinned); -struct NegUnpinFoo(T); - -impl !Unpin for NegUnpinFoo {} - -fn unpin2not_unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { - let Foo(_x) = foo_mut; //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] - let Foo(_x) = foo_const; //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] - let Foo(_x) = (|| foo_mut)(); //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] - let Foo(_x) = (|| foo_const)(); //~ ERROR the trait bound `Foo: !Unpin` is not satisfied [E0277] - let &mut _foo_mut = foo_mut; //~ ERROR mismatched types - let &_foo_const = foo_const; //~ ERROR mismatched types - // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready - // let &pin mut _foo_mut = foo_mut; // error - // let &pin mut _foo_const = foo_const; // error -} - -fn unpin2unpin(foo_mut: &pin mut Foo, foo_const: &pin const Foo) { - let Foo(_x) = foo_mut; // ok - let Foo(_x) = foo_const; // ok - let Foo(_x) = (|| foo_mut)(); // ok - let Foo(_x) = (|| foo_const)(); // ok - let &mut _foo_mut = foo_mut; //~ ERROR mismatched types - let &_foo_const = foo_const; //~ ERROR mismatched types - // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready - // let &pin mut _foo_mut = foo_mut; // ok - // let &pin mut _foo_const = foo_const; // ok -} - -fn not_unpin2not_unpin(foo_mut: &pin mut NotUnpinFoo, foo_const: &pin const NotUnpinFoo) { - let NotUnpinFoo(_x, _) = foo_mut; //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] - let NotUnpinFoo(_x, _) = foo_const; //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] - let NotUnpinFoo(_x, _) = (|| foo_mut)(); //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] - let NotUnpinFoo(_x, _) = (|| foo_const)(); //~ ERROR the trait bound `NotUnpinFoo: !Unpin` is not satisfied [E0277] - let &mut _foo_mut = foo_mut; //~ ERROR mismatched types - let &_foo_const = foo_const; //~ ERROR mismatched types - // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready - // let &pin mut _foo_mut = foo_mut; // error - // let &pin mut _foo_const = foo_const; // error -} - -fn not_unpin2unpin( - foo_mut: &pin mut NotUnpinFoo, - foo_const: &pin const NotUnpinFoo, -) { - let NotUnpinFoo(_x, _) = foo_mut; // ok - let NotUnpinFoo(_x, _) = foo_const; // ok - let NotUnpinFoo(_x, _) = (|| foo_mut)(); // ok - let NotUnpinFoo(_x, _) = (|| foo_const)(); // ok - let &mut _foo_mut = foo_mut; //~ ERROR mismatched types - let &_foo_const = foo_const; //~ ERROR mismatched types - // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready - // let &pin mut _foo_mut = foo_mut; // ok - // let &pin mut _foo_const = foo_const; // ok -} - -fn neg_unpin2not_unpin(foo_mut: &pin mut NegUnpinFoo, foo_const: &pin const NegUnpinFoo) { - let NegUnpinFoo(_x) = foo_mut; // ok - let NegUnpinFoo(_x) = foo_const; // ok - let NegUnpinFoo(_x) = (|| foo_mut)(); // ok - let NegUnpinFoo(_x) = (|| foo_const)(); // ok - let &mut _foo_mut = foo_mut; //~ ERROR mismatched types - let &_foo_const = foo_const; //~ ERROR mismatched types - // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready - // let &pin mut _foo_mut = foo_mut; // ok - // let &pin mut _foo_const = foo_const; // ok -} - -fn neg_unpin2unpin( - foo_mut: &pin mut NegUnpinFoo, - foo_const: &pin const NegUnpinFoo, -) { - let NegUnpinFoo(_x) = foo_mut; // ok - let NegUnpinFoo(_x) = foo_const; // ok - let NegUnpinFoo(_x) = (|| foo_mut)(); // ok - let NegUnpinFoo(_x) = (|| foo_const)(); // ok - let &mut _foo_mut = foo_mut; //~ ERROR mismatched types - let &_foo_const = foo_const; //~ ERROR mismatched types - // FIXME(pin_ergonomics): add these tests since `&pin` pattern is ready - // let &pin mut _foo_mut = foo_mut; // ok - // let &pin mut _foo_const = foo_const; // ok -} - -fn tuple_ref_mut_pat_and_pin_mut_of_tuple_mut_ty<'a, T>( - (&mut x,): &'a pin mut (&'a mut NegUnpinFoo,), - //~^ ERROR the trait bound `&'a mut NegUnpinFoo: !Unpin` is not satisfied in `(&'a mut NegUnpinFoo,)` [E0277] -) -> &'a pin mut NegUnpinFoo { - x -} - -fn tuple_ref_mut_pat_and_pin_mut_of_mut_tuple_ty<'a, T>( - (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), - //~^ ERROR mismatched type - //~| ERROR the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied [E0277] -) -> &'a pin mut NegUnpinFoo { - x -} - -fn ref_mut_tuple_pat_and_pin_mut_of_tuple_mut_ty<'a, T>( - &mut (x,): &'a pin mut (&'a mut NegUnpinFoo,), //~ ERROR mismatched type -) -> &'a pin mut NegUnpinFoo { - x -} - -fn ref_mut_tuple_pat_and_pin_mut_of_mut_tuple_ty<'a, T>( - &mut (x,): &'a pin mut &'a mut (NegUnpinFoo,), //~ ERROR mismatched type -) -> &'a pin mut NegUnpinFoo { - x -} - -fn tuple_pat_and_pin_mut_of_tuple_mut_ty<'a, T>( - (x,): &'a pin mut (&'a mut NegUnpinFoo,), -) -> &'a pin mut &'a mut NegUnpinFoo { - x // ok -} - -fn tuple_pat_and_pin_mut_of_mut_tuple_ty<'a, T>( - (x,): &'a pin mut &'a mut (NegUnpinFoo,), - //~^ ERROR the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied [E0277] -) -> &'a pin mut NegUnpinFoo { - x -} - -fn main() {} diff --git a/tests/ui/pin-ergonomics/projection-unpin-checks.stderr b/tests/ui/pin-ergonomics/projection-unpin-checks.stderr deleted file mode 100644 index c79e1e11b0771..0000000000000 --- a/tests/ui/pin-ergonomics/projection-unpin-checks.stderr +++ /dev/null @@ -1,333 +0,0 @@ -error[E0277]: the trait bound `Foo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:15:9 - | -LL | let Foo(_x) = foo_mut; - | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied - -error[E0277]: the trait bound `Foo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:16:9 - | -LL | let Foo(_x) = foo_const; - | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied - -error[E0277]: the trait bound `Foo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:17:9 - | -LL | let Foo(_x) = (|| foo_mut)(); - | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied - -error[E0277]: the trait bound `Foo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:18:9 - | -LL | let Foo(_x) = (|| foo_const)(); - | ^^^^^^^ the trait bound `Foo: !Unpin` is not satisfied - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:19:9 - | -LL | let &mut _foo_mut = foo_mut; - | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` - | | - | expected `Pin<&mut Foo>`, found `&mut _` - | - = note: expected struct `Pin<&mut Foo>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&mut Foo` - | -LL | let &mut _foo_mut = foo_mut.pointer; - | ++++++++ -help: to declare a mutable variable use - | -LL - let &mut _foo_mut = foo_mut; -LL + let mut _foo_mut = foo_mut; - | - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:20:9 - | -LL | let &_foo_const = foo_const; - | ^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` - | | - | expected `Pin<&Foo>`, found `&_` - | - = note: expected struct `Pin<&Foo>` - found reference `&_` -help: you might have meant to use field `pointer` whose type is `&Foo` - | -LL | let &_foo_const = foo_const.pointer; - | ++++++++ - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:31:9 - | -LL | let &mut _foo_mut = foo_mut; - | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` - | | - | expected `Pin<&mut Foo>`, found `&mut _` - | - = note: expected struct `Pin<&mut Foo>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&mut Foo` - | -LL | let &mut _foo_mut = foo_mut.pointer; - | ++++++++ -help: to declare a mutable variable use - | -LL - let &mut _foo_mut = foo_mut; -LL + let mut _foo_mut = foo_mut; - | - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:32:9 - | -LL | let &_foo_const = foo_const; - | ^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` - | | - | expected `Pin<&Foo>`, found `&_` - | - = note: expected struct `Pin<&Foo>` - found reference `&_` -help: you might have meant to use field `pointer` whose type is `&Foo` - | -LL | let &_foo_const = foo_const.pointer; - | ++++++++ - -error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:39:9 - | -LL | let NotUnpinFoo(_x, _) = foo_mut; - | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied - -error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:40:9 - | -LL | let NotUnpinFoo(_x, _) = foo_const; - | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied - -error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:41:9 - | -LL | let NotUnpinFoo(_x, _) = (|| foo_mut)(); - | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied - -error[E0277]: the trait bound `NotUnpinFoo: !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:42:9 - | -LL | let NotUnpinFoo(_x, _) = (|| foo_const)(); - | ^^^^^^^^^^^^^^^^^^ the trait bound `NotUnpinFoo: !Unpin` is not satisfied - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:43:9 - | -LL | let &mut _foo_mut = foo_mut; - | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NotUnpinFoo>` - | | - | expected `Pin<&mut NotUnpinFoo>`, found `&mut _` - | - = note: expected struct `Pin<&mut NotUnpinFoo>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&mut NotUnpinFoo` - | -LL | let &mut _foo_mut = foo_mut.pointer; - | ++++++++ -help: to declare a mutable variable use - | -LL - let &mut _foo_mut = foo_mut; -LL + let mut _foo_mut = foo_mut; - | - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:44:9 - | -LL | let &_foo_const = foo_const; - | ^^^^^^^^^^^ --------- this expression has type `Pin<&NotUnpinFoo>` - | | - | expected `Pin<&NotUnpinFoo>`, found `&_` - | - = note: expected struct `Pin<&NotUnpinFoo>` - found reference `&_` -help: you might have meant to use field `pointer` whose type is `&NotUnpinFoo` - | -LL | let &_foo_const = foo_const.pointer; - | ++++++++ - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:58:9 - | -LL | let &mut _foo_mut = foo_mut; - | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NotUnpinFoo>` - | | - | expected `Pin<&mut NotUnpinFoo>`, found `&mut _` - | - = note: expected struct `Pin<&mut NotUnpinFoo>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&mut NotUnpinFoo` - | -LL | let &mut _foo_mut = foo_mut.pointer; - | ++++++++ -help: to declare a mutable variable use - | -LL - let &mut _foo_mut = foo_mut; -LL + let mut _foo_mut = foo_mut; - | - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:59:9 - | -LL | let &_foo_const = foo_const; - | ^^^^^^^^^^^ --------- this expression has type `Pin<&NotUnpinFoo>` - | | - | expected `Pin<&NotUnpinFoo>`, found `&_` - | - = note: expected struct `Pin<&NotUnpinFoo>` - found reference `&_` -help: you might have meant to use field `pointer` whose type is `&NotUnpinFoo` - | -LL | let &_foo_const = foo_const.pointer; - | ++++++++ - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:70:9 - | -LL | let &mut _foo_mut = foo_mut; - | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinFoo>` - | | - | expected `Pin<&mut NegUnpinFoo>`, found `&mut _` - | - = note: expected struct `Pin<&mut NegUnpinFoo>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&mut NegUnpinFoo` - | -LL | let &mut _foo_mut = foo_mut.pointer; - | ++++++++ -help: to declare a mutable variable use - | -LL - let &mut _foo_mut = foo_mut; -LL + let mut _foo_mut = foo_mut; - | - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:71:9 - | -LL | let &_foo_const = foo_const; - | ^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinFoo>` - | | - | expected `Pin<&NegUnpinFoo>`, found `&_` - | - = note: expected struct `Pin<&NegUnpinFoo>` - found reference `&_` -help: you might have meant to use field `pointer` whose type is `&NegUnpinFoo` - | -LL | let &_foo_const = foo_const.pointer; - | ++++++++ - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:85:9 - | -LL | let &mut _foo_mut = foo_mut; - | ^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut NegUnpinFoo>` - | | - | expected `Pin<&mut NegUnpinFoo>`, found `&mut _` - | - = note: expected struct `Pin<&mut NegUnpinFoo>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&mut NegUnpinFoo` - | -LL | let &mut _foo_mut = foo_mut.pointer; - | ++++++++ -help: to declare a mutable variable use - | -LL - let &mut _foo_mut = foo_mut; -LL + let mut _foo_mut = foo_mut; - | - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:86:9 - | -LL | let &_foo_const = foo_const; - | ^^^^^^^^^^^ --------- this expression has type `Pin<&NegUnpinFoo>` - | | - | expected `Pin<&NegUnpinFoo>`, found `&_` - | - = note: expected struct `Pin<&NegUnpinFoo>` - found reference `&_` -help: you might have meant to use field `pointer` whose type is `&NegUnpinFoo` - | -LL | let &_foo_const = foo_const.pointer; - | ++++++++ - -error[E0277]: the trait bound `&'a mut NegUnpinFoo: !Unpin` is not satisfied in `(&'a mut NegUnpinFoo,)` - --> $DIR/projection-unpin-checks.rs:93:5 - | -LL | (&mut x,): &'a pin mut (&'a mut NegUnpinFoo,), - | ^^^^^^^^^ within `(&'a mut NegUnpinFoo,)`, the trait bound `&'a mut NegUnpinFoo: !Unpin` is not satisfied - | - = note: required because it appears within the type `(&'a mut NegUnpinFoo,)` - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:100:6 - | -LL | (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), - | ^^^^^^ ------------------------------------- expected due to this - | | - | expected `NegUnpinFoo`, found `&mut _` - | - = note: expected struct `NegUnpinFoo` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/projection-unpin-checks.rs:100:6 - | -LL | (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), -LL + (x,): &'a pin mut &'a mut (NegUnpinFoo,), - | - -error[E0277]: the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:100:5 - | -LL | (&mut x,): &'a pin mut &'a mut (NegUnpinFoo,), - | ^^^^^^^^^ the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:108:5 - | -LL | &mut (x,): &'a pin mut (&'a mut NegUnpinFoo,), - | ^^^^^^^^^ ------------------------------------- expected due to this - | | - | expected `Pin<&mut (&mut NegUnpinFoo,)>`, found `&mut _` - | - = note: expected struct `Pin<&'a mut (&'a mut NegUnpinFoo,)>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&'a mut (&'a mut NegUnpinFoo,)` - | -LL | &mut (x,): &'a pin mut (&'a mut NegUnpinFoo,).pointer, - | ++++++++ - -error[E0308]: mismatched types - --> $DIR/projection-unpin-checks.rs:114:5 - | -LL | &mut (x,): &'a pin mut &'a mut (NegUnpinFoo,), - | ^^^^^^^^^ ------------------------------------- expected due to this - | | - | expected `Pin<&mut &mut (NegUnpinFoo,)>`, found `&mut _` - | - = note: expected struct `Pin<&'a mut &'a mut (NegUnpinFoo,)>` - found mutable reference `&mut _` -help: you might have meant to use field `pointer` whose type is `&'a mut &'a mut (NegUnpinFoo,)` - | -LL | &mut (x,): &'a pin mut &'a mut (NegUnpinFoo,).pointer, - | ++++++++ - -error[E0277]: the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied - --> $DIR/projection-unpin-checks.rs:126:5 - | -LL | (x,): &'a pin mut &'a mut (NegUnpinFoo,), - | ^^^^ the trait bound `&'a mut (NegUnpinFoo,): !Unpin` is not satisfied - -error: aborting due to 26 previous errors - -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. From cb369ab26f1ec2ec10f1feff484b9d4aae189c1d Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 3 Aug 2025 21:26:38 +0800 Subject: [PATCH 15/45] Fix `pin_ergonomics` tests --- compiler/rustc_hir_typeck/src/pat.rs | 29 +--- ...ttern-matching-deref-pattern.normal.stderr | 155 ++++++++++++++++++ .../pattern-matching-deref-pattern.rs | 110 ++++++++----- ...ern-matching-mix-deref-pattern.both.stderr | 74 +++++++++ ...ng-mix-deref-pattern.deref_patterns.stderr | 74 +++++++++ ...n-matching-mix-deref-pattern.normal.stderr | 151 +++++++++++------ ...ng-mix-deref-pattern.pin_ergonomics.stderr | 96 +++-------- .../pattern-matching-mix-deref-pattern.rs | 98 +++++------ .../pattern-matching.normal.stderr | 100 +++++++++-- .../pattern-matching.pin_ergonomics.stderr | 54 ++++++ tests/ui/pin-ergonomics/pattern-matching.rs | 37 ++++- 11 files changed, 726 insertions(+), 252 deletions(-) create mode 100644 tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr create mode 100644 tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr create mode 100644 tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr create mode 100644 tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 615e80f1ba0e5..12db66155f8a2 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -557,7 +557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let binding_mode = adjust_binding_mode(Pinnedness::Pinned, inner_mutability); // If the pinnedness is `Not`, it means the pattern is unpinned // and thus requires an `Unpin` bound. - if binding_mode == ByRef::Yes(Pinnedness::Not, Mutability::Mut) { + if matches!(binding_mode, ByRef::Yes(Pinnedness::Not, _)) { self.register_bound( inner_ty, self.tcx.require_lang_item(hir::LangItem::Unpin, pat.span), @@ -2683,9 +2683,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected = self.try_structurally_resolve_type(pat.span, expected); // Determine whether we're consuming an inherited reference and resetting the default // binding mode, based on edition and enabled experimental features. - // FIXME(pin_ergonomics): since `&pin` pattern is supported, the condition here - // should be adjusted to `pat_pin == inh_pin` - if let ByRef::Yes(Pinnedness::Not, inh_mut) = pat_info.binding_mode { + if let ByRef::Yes(inh_pin, inh_mut) = pat_info.binding_mode + // FIXME(pin_ergonomics): since `&pin` pattern is supported, the condition here + // should be adjusted to `pat_pin == inh_pin` + && (!self.tcx.features().pin_ergonomics() || inh_pin == Pinnedness::Not) + { match self.ref_pat_matches_inherited_ref(pat.span.edition()) { InheritedRefMatchRule::EatOuter => { // ref pattern attempts to consume inherited reference @@ -2704,22 +2706,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } InheritedRefMatchRule::EatInner => { - let expected_ref_or_pinned_ref = || { - if self.tcx.features().pin_ergonomics() - && let Some(ty::Ref(_, _, r_mutbl)) = - expected.pinned_ty().map(|ty| *ty.kind()) - && pat_mutbl <= r_mutbl - { - return Some((Pinnedness::Pinned, r_mutbl)); - } - if let ty::Ref(_, _, r_mutbl) = *expected.kind() - && pat_mutbl <= r_mutbl - { - return Some((Pinnedness::Not, r_mutbl)); - } - None - }; - if let Some((_, r_mutbl)) = expected_ref_or_pinned_ref() { + if let ty::Ref(_, _, r_mutbl) = *expected.kind() + && pat_mutbl <= r_mutbl + { // Match against the reference type; don't consume the inherited ref. // NB: The check for compatible pattern and ref type mutability assumes that // `&` patterns can match against mutable references (RFC 3627, Rule 5). If diff --git a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr new file mode 100644 index 0000000000000..559465bc13aba --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr @@ -0,0 +1,155 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:45:28 + | +LL | let Foo { x, y } = foo.as_mut(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Foo { ref x, y } = foo.as_mut(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Foo { x, ref y } = foo.as_mut(); + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:35:24 + | +LL | let Foo { x, y } = foo.as_mut(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Foo { ref x, y } = foo.as_mut(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Foo { x, ref y } = foo.as_mut(); + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:67:28 + | +LL | let Foo { x, y } = foo.as_ref(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Foo { ref x, y } = foo.as_ref(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Foo { x, ref y } = foo.as_ref(); + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:57:24 + | +LL | let Foo { x, y } = foo.as_ref(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Foo { ref x, y } = foo.as_ref(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Foo { x, ref y } = foo.as_ref(); + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:89:25 + | +LL | let Bar(x, y) = bar.as_mut(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Bar(ref x, y) = bar.as_mut(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Bar(x, ref y) = bar.as_mut(); + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:79:21 + | +LL | let Bar(x, y) = bar.as_mut(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Bar(ref x, y) = bar.as_mut(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Bar(x, ref y) = bar.as_mut(); + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:111:25 + | +LL | let Bar(x, y) = bar.as_ref(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Bar(ref x, y) = bar.as_ref(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Bar(x, ref y) = bar.as_ref(); + | +++ + +error[E0507]: cannot move out of a shared reference + --> $DIR/pattern-matching-deref-pattern.rs:101:21 + | +LL | let Bar(x, y) = bar.as_ref(); + | - - ^^^^^^^^^^^^ + | | | + | | ...and here + | data moved here + | + = note: move occurs because these variables have types that don't implement the `Copy` trait +help: consider borrowing the pattern binding + | +LL | let Bar(ref x, y) = bar.as_ref(); + | +++ +help: consider borrowing the pattern binding + | +LL | let Bar(x, ref y) = bar.as_ref(); + | +++ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs index 23d29e6f9dae4..6ecb22e535b13 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs +++ b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs @@ -1,8 +1,6 @@ //@ revisions: pin_ergonomics normal //@ edition:2024 -//@ check-pass -// //@[normal] check-pass -// //@[pin_ergonomics] rustc-env:RUSTC_LOG=rustc_hir_typeck::expr_use_visitor=DEBUG +//@[pin_ergonomics] check-pass #![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] #![feature(deref_patterns)] #![allow(incomplete_features)] @@ -24,67 +22,99 @@ enum Baz { Bar { x: T, y: U }, } -fn foo_mut(foo: Pin<&mut Foo>) { - let Foo { .. } = foo; - let Pin { .. } = foo; - let _ = || { - let Foo { .. } = foo; - let Pin { .. } = foo; - }; +trait IsPinMut {} +trait IsPinConst {} +impl IsPinMut for Pin<&mut T> {} +impl IsPinConst for Pin<&T> {} +fn assert_pin_mut(_: T) {} +fn assert_pin_const(_: T) {} + +fn foo_mut(mut foo: Pin<&mut Foo>) { + let Foo { .. } = foo.as_mut(); + let Foo { x, y } = foo.as_mut(); + //[normal]~^ ERROR cannot move out of a shared reference #[cfg(pin_ergonomics)] - let Foo { x, y } = foo; + assert_pin_mut(x); #[cfg(pin_ergonomics)] + assert_pin_mut(y); + let Pin { .. } = foo.as_mut(); + let _ = || { - let Foo { x, y } = foo; + let Foo { .. } = foo.as_mut(); + let Foo { x, y } = foo.as_mut(); + //[normal]~^ ERROR cannot move out of a shared reference + #[cfg(pin_ergonomics)] + assert_pin_mut(x); + #[cfg(pin_ergonomics)] + assert_pin_mut(y); + let Pin { .. } = foo.as_mut(); }; } fn foo_const(foo: Pin<&Foo>) { - let Foo { .. } = foo; - let Pin { .. } = foo; - let _ = || { - let Foo { .. } = foo; - let Pin { .. } = foo; - }; - + let Foo { .. } = foo.as_ref(); + let Foo { x, y } = foo.as_ref(); + //[normal]~^ ERROR cannot move out of a shared reference #[cfg(pin_ergonomics)] - let Foo { x, y } = foo; + assert_pin_const(x); #[cfg(pin_ergonomics)] - let _ = || { - let Foo { x, y } = foo; - }; -} + assert_pin_const(y); + let Pin { .. } = foo.as_ref(); -fn bar_mut(bar: Pin<&mut Bar>) { - let Bar(..) = bar; - let Pin { .. } = bar; let _ = || { - let Bar(..) = bar; - let Pin { .. } = bar; + let Foo { .. } = foo.as_ref(); + let Foo { x, y } = foo.as_ref(); + //[normal]~^ ERROR cannot move out of a shared reference + #[cfg(pin_ergonomics)] + assert_pin_const(x); + #[cfg(pin_ergonomics)] + assert_pin_const(y); + let Pin { .. } = foo.as_ref(); }; +} +fn bar_mut(mut bar: Pin<&mut Bar>) { + let Bar(..) = bar.as_mut(); + let Bar(x, y) = bar.as_mut(); + //[normal]~^ ERROR cannot move out of a shared reference #[cfg(pin_ergonomics)] - let Bar(x, y) = bar; + assert_pin_mut(x); #[cfg(pin_ergonomics)] + assert_pin_mut(y); + let Pin { .. } = bar.as_mut(); + let _ = || { - let Bar(x, y) = bar; + let Bar(..) = bar.as_mut(); + let Bar(x, y) = bar.as_mut(); + //[normal]~^ ERROR cannot move out of a shared reference + #[cfg(pin_ergonomics)] + assert_pin_mut(x); + #[cfg(pin_ergonomics)] + assert_pin_mut(y); + let Pin { .. } = bar.as_mut(); }; } fn bar_const(bar: Pin<&Bar>) { - let Bar(..) = bar; - let Pin { .. } = bar; - let _ = || { - let Bar(..) = bar; - let Pin { .. } = bar; - }; - + let Bar(..) = bar.as_ref(); + let Bar(x, y) = bar.as_ref(); + //[normal]~^ ERROR cannot move out of a shared reference #[cfg(pin_ergonomics)] - let Bar(x, y) = bar; + assert_pin_const(x); #[cfg(pin_ergonomics)] + assert_pin_const(y); + let Pin { .. } = bar.as_ref(); + let _ = || { - let Bar(x, y) = bar; + let Bar(..) = bar.as_ref(); + let Bar(x, y) = bar.as_ref(); + //[normal]~^ ERROR cannot move out of a shared reference + #[cfg(pin_ergonomics)] + assert_pin_const(x); + #[cfg(pin_ergonomics)] + assert_pin_const(y); + let Pin { .. } = bar.as_ref(); }; } diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr new file mode 100644 index 0000000000000..3e883fddb7a6b --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr @@ -0,0 +1,74 @@ +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr new file mode 100644 index 0000000000000..3e883fddb7a6b --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr @@ -0,0 +1,74 @@ +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 + | +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Foo>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 + | +LL | Bar(x, y) => {} + | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&Bar>` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr index 2389fe9ed98cd..a39d7d79916c5 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr @@ -1,66 +1,123 @@ -error: mix of deref patterns and normal constructors +error[E0308]: mismatched types --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` +LL | match foo { + | --- this expression has type `Pin<&mut Foo>` +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ expected `Pin<&mut Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&mut Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *foo { + | + -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:31:9 +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 + | +LL | let _ = || match foo { + | --- this expression has type `Pin<&mut Foo>` +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ expected `Pin<&mut Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&mut Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` +LL | let _ = || match *foo { + | + -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:49:9 +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Foo>` +LL | match foo { + | --- this expression has type `Pin<&Foo>` +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ expected `Pin<&Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *foo { + | + -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:53:9 +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 + | +LL | let _ = || match foo { + | --- this expression has type `Pin<&Foo>` +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ expected `Pin<&Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Foo>` +LL | let _ = || match *foo { + | + -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:71:9 +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` +LL | match bar { + | --- this expression has type `Pin<&mut Bar>` +LL | Bar(x, y) => {} + | ^^^^^^^^^ expected `Pin<&mut Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&mut Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *bar { + | + -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:75:9 +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 + | +LL | let _ = || match bar { + | --- this expression has type `Pin<&mut Bar>` +LL | Bar(x, y) => {} + | ^^^^^^^^^ expected `Pin<&mut Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&mut Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` +LL | let _ = || match *bar { + | + -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:93:9 +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Bar>` +LL | match bar { + | --- this expression has type `Pin<&Bar>` +LL | Bar(x, y) => {} + | ^^^^^^^^^ expected `Pin<&Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *bar { + | + -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:97:9 +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 + | +LL | let _ = || match bar { + | --- this expression has type `Pin<&Bar>` +LL | Bar(x, y) => {} + | ^^^^^^^^^ expected `Pin<&Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Bar>` +LL | let _ = || match *bar { + | + error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr index f23e5cf72a45e..3e883fddb7a6b 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr @@ -1,130 +1,74 @@ error: mix of deref patterns and normal constructors --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:37:9 - | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:31:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:42:9 - | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:49:9 - | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Foo>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:59:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:53:9 - | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Foo>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:64:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 | -LL | Foo { .. } => {} - | ^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +LL | Foo { x, y } => {} + | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:71:9 - | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:81:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:75:9 - | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:86:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:93:9 - | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Bar>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:103:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:97:9 - | -LL | Bar(..) => {} - | ^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` -LL | Pin { .. } => {} - | ^^^^^^^^^^ matches directly on `Pin<&Bar>` - -error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:108:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` +... LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` -error: aborting due to 16 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs index c5ba9dbeb2e6e..8945205bea176 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs @@ -1,7 +1,7 @@ -//@ revisions: pin_ergonomics normal +//@ revisions: normal pin_ergonomics deref_patterns both //@ edition:2024 -#![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] -#![feature(deref_patterns)] +#![cfg_attr(any(pin_ergonomics, both), feature(pin_ergonomics))] +#![cfg_attr(any(deref_patterns, both), feature(deref_patterns))] #![allow(incomplete_features)] // This test verifies that the `pin_ergonomics` feature works well @@ -24,88 +24,76 @@ enum Baz { fn foo_mut(foo: Pin<&mut Foo>) { match foo { - Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors + Foo { x, y } => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} } let _ = || match foo { - Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - }; - - #[cfg(pin_ergonomics)] - match foo { - Foo { x, y } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - } - #[cfg(pin_ergonomics)] - let _ = || match foo { - Foo { .. } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Foo { x, y } => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} }; } fn foo_const(foo: Pin<&Foo>) { match foo { - Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - } - let _ = || match foo { - Foo { .. } => {} //~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - }; - - #[cfg(pin_ergonomics)] - match foo { - Foo { x, y } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Foo { x, y } => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} } - #[cfg(pin_ergonomics)] let _ = || match foo { - Foo { .. } => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Foo { x, y } => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} }; } fn bar_mut(bar: Pin<&mut Bar>) { match bar { - Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors + Bar(x, y) => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} } let _ = || match bar { - Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - }; - - #[cfg(pin_ergonomics)] - match bar { - Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - } - #[cfg(pin_ergonomics)] - let _ = || match bar { - Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Bar(x, y) => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} }; } fn bar_const(bar: Pin<&Bar>) { match bar { - Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - } - let _ = || match bar { - Bar(..) => {} //~ ERROR mix of deref patterns and normal constructors - Pin { .. } => {} - }; - - #[cfg(pin_ergonomics)] - match bar { - Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Bar(x, y) => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} } - #[cfg(pin_ergonomics)] let _ = || match bar { - Bar(x, y) => {} //[pin_ergonomics]~ ERROR mix of deref patterns and normal constructors + Bar(x, y) => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR mix of deref patterns and normal constructors + //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} }; } diff --git a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr index 1b4908abdc176..26f057195a15e 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:35:9 + --> $DIR/pattern-matching.rs:34:9 | LL | let Foo { x, y } = foo_mut; | ^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` @@ -14,7 +14,7 @@ LL | let Foo { x, y } = *foo_mut; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:40:9 + --> $DIR/pattern-matching.rs:39:9 | LL | let Foo { x, y } = foo_const; | ^^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` @@ -29,7 +29,7 @@ LL | let Foo { x, y } = *foo_const; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:48:9 + --> $DIR/pattern-matching.rs:47:9 | LL | match bar_mut { | ------- this expression has type `Pin<&mut Bar>` @@ -44,7 +44,7 @@ LL | match *bar_mut { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:53:18 + --> $DIR/pattern-matching.rs:52:18 | LL | _ if let Bar::Bar { x, y } = bar_mut => { | ^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Bar>` @@ -59,7 +59,7 @@ LL | _ if let Bar::Bar { x, y } = *bar_mut => { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:61:9 + --> $DIR/pattern-matching.rs:60:9 | LL | match bar_const { | --------- this expression has type `Pin<&Bar>` @@ -74,7 +74,7 @@ LL | match *bar_const { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:66:18 + --> $DIR/pattern-matching.rs:65:18 | LL | _ if let Bar::Foo(x, y) = bar_const => { | ^^^^^^^^^^^^^^ --------- this expression has type `Pin<&Bar>` @@ -89,7 +89,7 @@ LL | _ if let Bar::Foo(x, y) = *bar_const => { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:76:9 + --> $DIR/pattern-matching.rs:75:9 | LL | let (Foo { x, y },) = foo_mut; | ^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut (Foo,)>` @@ -104,7 +104,7 @@ LL | let (Foo { x, y },) = *foo_mut; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:80:9 + --> $DIR/pattern-matching.rs:79:9 | LL | let (Foo { x, y },) = foo_const; | ^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&(Foo,)>` @@ -119,30 +119,104 @@ LL | let (Foo { x, y },) = *foo_const; | + error[E0529]: expected an array or slice, found `Pin<&mut [Foo; 1]>` - --> $DIR/pattern-matching.rs:87:9 + --> $DIR/pattern-matching.rs:86:9 | LL | let [Foo { x, y }] = foo_mut; | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [Foo; 1]>` error[E0529]: expected an array or slice, found `Pin<&[Foo; 1]>` - --> $DIR/pattern-matching.rs:91:9 + --> $DIR/pattern-matching.rs:90:9 | LL | let [Foo { x, y }] = foo_const; | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[Foo; 1]>` error[E0529]: expected an array or slice, found `Pin<&mut [Foo]>` - --> $DIR/pattern-matching.rs:98:12 + --> $DIR/pattern-matching.rs:97:12 | LL | if let [Foo { x, y }] = foo_mut { | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [Foo]>` error[E0529]: expected an array or slice, found `Pin<&[Foo]>` - --> $DIR/pattern-matching.rs:103:12 + --> $DIR/pattern-matching.rs:102:12 | LL | if let [Foo { x, y }] = foo_const { | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[Foo]>` -error: aborting due to 12 previous errors +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:110:5 + | +LL | (&mut x,): Pin<&'a mut (&'a mut Foo,)>, + | ^^^^^^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut (&mut Foo,)>`, found `(_,)` + | + = note: expected struct `Pin<&'a mut (&'a mut Foo,)>` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:116:5 + | +LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, + | ^^^^^^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut &mut (Foo,)>`, found `(_,)` + | + = note: expected struct `Pin<&'a mut &'a mut (Foo,)>` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:122:5 + | +LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>, + | ^^^^^^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut (&mut Foo,)>`, found `&mut _` + | + = note: expected struct `Pin<&'a mut (&'a mut Foo,)>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&'a mut (&'a mut Foo,)` + | +LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>.pointer, + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:128:5 + | +LL | &mut (x,): Pin<&'a mut &'a mut (Foo,)>, + | ^^^^^^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut &mut (Foo,)>`, found `&mut _` + | + = note: expected struct `Pin<&'a mut &'a mut (Foo,)>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&'a mut &'a mut (Foo,)` + | +LL | &mut (x,): Pin<&'a mut &'a mut (Foo,)>.pointer, + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:134:5 + | +LL | (x,): Pin<&'a mut (&'a mut Foo,)>, + | ^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut (&mut Foo,)>`, found `(_,)` + | + = note: expected struct `Pin<&'a mut (&'a mut Foo,)>` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:140:5 + | +LL | (x,): Pin<&'a mut &'a mut (Foo,)>, + | ^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut &mut (Foo,)>`, found `(_,)` + | + = note: expected struct `Pin<&'a mut &'a mut (Foo,)>` + found tuple `(_,)` + +error: aborting due to 18 previous errors Some errors have detailed explanations: E0308, E0529. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr b/tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr new file mode 100644 index 0000000000000..fd442b8263c05 --- /dev/null +++ b/tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr @@ -0,0 +1,54 @@ +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:116:6 + | +LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, + | ^^^^^^ --------------------------------- expected due to this + | | + | expected `Foo`, found `&mut _` + | + = note: expected struct `Foo` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-matching.rs:116:6 + | +LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - (&mut x,): Pin<&'a mut &'a mut (Foo,)>, +LL + (x,): Pin<&'a mut &'a mut (Foo,)>, + | + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:122:5 + | +LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>, + | ^^^^^^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut (&mut Foo,)>`, found `&mut _` + | + = note: expected struct `Pin<&'a mut (&'a mut Foo,)>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&'a mut (&'a mut Foo,)` + | +LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>.pointer, + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/pattern-matching.rs:128:5 + | +LL | &mut (x,): Pin<&'a mut &'a mut (Foo,)>, + | ^^^^^^^^^ --------------------------------- expected due to this + | | + | expected `Pin<&mut &mut (Foo,)>`, found `&mut _` + | + = note: expected struct `Pin<&'a mut &'a mut (Foo,)>` + found mutable reference `&mut _` +help: you might have meant to use field `pointer` whose type is `&'a mut &'a mut (Foo,)` + | +LL | &mut (x,): Pin<&'a mut &'a mut (Foo,)>.pointer, + | ++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching.rs b/tests/ui/pin-ergonomics/pattern-matching.rs index 8aff264aaa8e3..4f2a23afbb8ff 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.rs +++ b/tests/ui/pin-ergonomics/pattern-matching.rs @@ -1,6 +1,5 @@ //@ revisions: pin_ergonomics normal //@ edition:2024 -//@[pin_ergonomics] check-pass #![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] #![feature(if_let_guard, negative_impls)] #![allow(incomplete_features)] @@ -107,4 +106,40 @@ fn pin_mut_slice(foo_mut: Pin<&mut [Foo]>, foo_const: Pin<&[Foo( + (&mut x,): Pin<&'a mut (&'a mut Foo,)>, //[normal]~ ERROR mismatched type +) -> Pin<&'a mut Foo> { + x +} + +fn tuple_ref_mut_pat_and_pin_mut_of_mut_tuple_ty<'a, T, U>( + (&mut x,): Pin<&'a mut &'a mut (Foo,)>, //~ ERROR mismatched type +) -> Pin<&'a mut Foo> { + x +} + +fn ref_mut_tuple_pat_and_pin_mut_of_tuple_mut_ty<'a, T, U>( + &mut (x,): Pin<&'a mut (&'a mut Foo,)>, //~ ERROR mismatched type +) -> Pin<&'a mut Foo> { + x +} + +fn ref_mut_tuple_pat_and_pin_mut_of_mut_tuple_ty<'a, T, U>( + &mut (x,): Pin<&'a mut &'a mut (Foo,)>, //~ ERROR mismatched type +) -> Pin<&'a mut Foo> { + x +} + +fn tuple_pat_and_pin_mut_of_tuple_mut_ty<'a, T, U>( + (x,): Pin<&'a mut (&'a mut Foo,)>, //[normal]~ ERROR mismatched type +) -> Pin<&'a mut &'a mut Foo> { + x // ok +} + +fn tuple_pat_and_pin_mut_of_mut_tuple_ty<'a, T, U>( + (x,): Pin<&'a mut &'a mut (Foo,)>, //[normal]~ ERROR mismatched type +) -> Pin<&'a mut Foo> { + x +} + fn main() {} From b36f15e840be94a3aab523c92a35083053bc96fe Mon Sep 17 00:00:00 2001 From: Frank King Date: Sat, 27 Sep 2025 12:14:43 +0800 Subject: [PATCH 16/45] Add `#[pin_project]` attribute for structurally pinning --- .../rustc_attr_parsing/src/attributes/mod.rs | 1 + .../src/attributes/pin_project.rs | 21 ++ compiler/rustc_attr_parsing/src/context.rs | 2 + compiler/rustc_feature/src/builtin_attrs.rs | 9 + .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_hir_typeck/messages.ftl | 4 + compiler/rustc_hir_typeck/src/errors.rs | 11 + compiler/rustc_hir_typeck/src/pat.rs | 15 + compiler/rustc_middle/src/ty/adt.rs | 13 + .../rustc_middle/src/ty/typeck_results.rs | 26 -- compiler/rustc_passes/src/check_attr.rs | 3 +- compiler/rustc_span/src/symbol.rs | 1 + .../src/traits/select/mod.rs | 3 +- .../feature-gate-pin_ergonomics.rs | 8 +- .../feature-gate-pin_ergonomics.stderr | 16 +- ...ttern-matching-deref-pattern.normal.stderr | 16 +- .../pattern-matching-deref-pattern.rs | 3 + ...ern-matching-mix-deref-pattern.both.stderr | 86 ++++- ...ng-mix-deref-pattern.deref_patterns.stderr | 36 +- ...n-matching-mix-deref-pattern.normal.stderr | 162 +++++++-- ...ng-mix-deref-pattern.pin_ergonomics.stderr | 86 ++++- .../pattern-matching-mix-deref-pattern.rs | 57 +++- .../pattern-matching.normal.stderr | 60 ++-- .../pattern-matching.pin_ergonomics.stderr | 8 +- tests/ui/pin-ergonomics/pattern-matching.rs | 7 +- tests/ui/pin-ergonomics/pin_project-attr.rs | 144 ++++++++ .../ui/pin-ergonomics/pin_project-attr.stderr | 318 ++++++++++++++++++ 28 files changed, 995 insertions(+), 125 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/pin_project.rs create mode 100644 tests/ui/pin-ergonomics/pin_project-attr.rs create mode 100644 tests/ui/pin-ergonomics/pin_project-attr.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 639c75d7c5e47..207fdb7ccabd7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -48,6 +48,7 @@ pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; pub(crate) mod non_exhaustive; pub(crate) mod path; +pub(crate) mod pin_project; pub(crate) mod proc_macro_attrs; pub(crate) mod prototype; pub(crate) mod repr; diff --git a/compiler/rustc_attr_parsing/src/attributes/pin_project.rs b/compiler/rustc_attr_parsing/src/attributes/pin_project.rs new file mode 100644 index 0000000000000..9a81f82c9f54d --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/pin_project.rs @@ -0,0 +1,21 @@ +use rustc_hir::Target; +use rustc_hir::attrs::AttributeKind; +use rustc_span::{Span, Symbol, sym}; + +use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; +use crate::target_checking::AllowedTargets; +use crate::target_checking::Policy::Allow; + +pub(crate) struct PinProjectParser; + +impl NoArgsAttributeParser for PinProjectParser { + const PATH: &[Symbol] = &[sym::pin_project]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Enum), + Allow(Target::Struct), + Allow(Target::Union), + ]); + const CREATE: fn(Span) -> AttributeKind = AttributeKind::PinProject; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 6694dac8bb25a..b2bd5ffad8d43 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -47,6 +47,7 @@ use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; use crate::attributes::non_exhaustive::NonExhaustiveParser; use crate::attributes::path::PathParser as PathAttributeParser; +use crate::attributes::pin_project::PinProjectParser; use crate::attributes::proc_macro_attrs::{ ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser, }; @@ -233,6 +234,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a2acac8b3045d..c97c457086a40 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -893,6 +893,15 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, loop_match, experimental!(loop_match) ), + // The `#[pin_project]` attribute is part of the `pin_ergonomics` experiment + // that allows structurally pinning, tracked in: + // + // - https://github.com/rust-lang/rust/issues/130494 + gated!( + pin_project, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::Yes, pin_ergonomics, experimental!(pin_project), + ), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 828c15cc391dd..29b4d2d96dd20 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -637,6 +637,9 @@ pub enum AttributeKind { /// Represents `#[pattern_complexity_limit]` PatternComplexityLimit { attr_span: Span, limit_span: Span, limit: Limit }, + /// Represents `#[pin_project]` + PinProject(Span), + /// Represents `#[pointee]` Pointee(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 362ab407aab35..e9a183437693f 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -77,6 +77,7 @@ impl AttributeKind { PassByValue(..) => Yes, Path(..) => No, PatternComplexityLimit { .. } => No, + PinProject(..) => Yes, Pointee(..) => No, ProcMacro(..) => No, ProcMacroAttribute(..) => No, diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 1ed0756fdd6a7..f14441a6363e7 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -227,6 +227,10 @@ hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function .suggestion = cast the value to `{$cast_ty}` .teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules +hir_typeck_project_on_non_pin_project_type = cannot project on type that is not `#[pin_project]` + .note = type defined here + .suggestion = add `#[pin_project]` here + hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> [1] auto trait {$traits} *[other] auto traits {$traits} diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index d15d092b7d3da..34e0c9f0f68a6 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1156,3 +1156,14 @@ pub(crate) struct ConstContinueBadLabel { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_project_on_non_pin_project_type)] +pub(crate) struct ProjectOnNonPinProjectType { + #[primary_span] + pub span: Span, + #[note] + pub def_span: Option, + #[suggestion(code = "#[pin_project]\n", applicability = "machine-applicable")] + pub sugg_span: Option, +} diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 12db66155f8a2..d3867bda6fa0a 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -554,6 +554,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { debug!("scrutinee ty {expected:?} is a pinned reference, inserting pin deref"); + // if the inner_ty is an ADT, make sure that it can be structurally pinned + // (i.e., it is `#[pin_project]`). + if let Some(adt) = inner_ty.ty_adt_def() + && !adt.is_pin_project() + && !adt.is_pin() + { + let def_span: Option = self.tcx.hir_span_if_local(adt.did()); + let sugg_span = def_span.map(|span| span.shrink_to_lo()); + self.dcx().emit_err(crate::errors::ProjectOnNonPinProjectType { + span: pat.span, + def_span, + sugg_span, + }); + } + let binding_mode = adjust_binding_mode(Pinnedness::Pinned, inner_mutability); // If the pinnedness is `Not`, it means the pattern is unpinned // and thus requires an `Unpin` bound. diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index be909a08e8dae..8386504245cde 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -57,6 +57,8 @@ bitflags::bitflags! { const IS_UNSAFE_PINNED = 1 << 10; /// Indicates whether the type is `Pin`. const IS_PIN = 1 << 11; + /// Indicates whether the type is `#[pin_project]`. + const IS_PIN_PROJECT = 1 << 12; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } @@ -286,6 +288,10 @@ impl AdtDefData { debug!("found non-exhaustive variant list for {:?}", did); flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; } + if find_attr!(tcx.get_all_attrs(did), AttributeKind::PinProject(..)) { + debug!("found pin-project type {:?}", did); + flags |= AdtFlags::IS_PIN_PROJECT; + } flags |= match kind { AdtKind::Enum => AdtFlags::IS_ENUM, @@ -439,6 +445,13 @@ impl<'tcx> AdtDef<'tcx> { self.flags().contains(AdtFlags::IS_PIN) } + /// Returns `true` is this is `#[pin_project]` for the purposes + /// of structural pinning. + #[inline] + pub fn is_pin_project(self) -> bool { + self.flags().contains(AdtFlags::IS_PIN_PROJECT) + } + /// Returns `true` if this type has a destructor. pub fn has_dtor(self, tcx: TyCtxt<'tcx>) -> bool { self.destructor(tcx).is_some() diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 06e9e28d0fdc8..6a6ed702373d1 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -493,32 +493,6 @@ impl<'tcx> TypeckResults<'tcx> { has_ref_mut } - /// Visits the pattern recursively whether it contains a `ref pin` binding - /// of non-`Unpin` type in it. - /// - /// This is used to determined whether a `&pin` pattern should emit a `!Unpin` - /// call for its pattern scrutinee. - /// - /// This is computed from the typeck results since we want to make - /// sure to apply any match-ergonomics adjustments, which we cannot - /// determine from the HIR alone. - pub fn pat_walk_ref_pin_binding_of_non_unpin_type<'a>( - &self, - pat: &hir::Pat<'_>, - mut ty_visitor: impl FnMut(Ty<'tcx>) + 'a, - ) { - pat.walk(|pat| { - if let hir::PatKind::Binding(_, id, _, _) = pat.kind - && let Some(BindingMode(ByRef::Yes(Pinnedness::Pinned, _), _)) = - self.pat_binding_modes().get(id) - { - let ty = self.pat_ty(pat); - ty_visitor(ty); - } - true - }); - } - /// How should a deref pattern find the place for its inner pattern to match on? /// /// In most cases, if the pattern recursively contains a `ref mut` binding, we find the inner diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ef42c42f68b37..3cd1d5ba61b48 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -283,7 +283,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::ObjcSelector { .. } | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::DebuggerVisualizer(..) - | AttributeKind::RustcMain, + | AttributeKind::RustcMain + | AttributeKind::PinProject(..), ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 223d818a2949b..c378927ded895 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1667,6 +1667,7 @@ symbols! { pin, pin_ergonomics, pin_macro, + pin_project, platform_intrinsics, plugin, plugin_registrar, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ed63949ee022e..ea903bac9d617 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2466,8 +2466,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::TraitRef::new_from_args(tcx, trait_def_id, err_args) }; - let obligation = - Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref); + let obligation = Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref); obligations.push(obligation); obligations }) diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs index 7746654555dd8..47c4b36a07703 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs @@ -2,11 +2,11 @@ use std::pin::Pin; +#[pin_project] //~ ERROR the `#[pin_project]` attribute is an experimental feature struct Foo; impl Foo { - fn foo(self: Pin<&mut Self>) { - } + fn foo(self: Pin<&mut Self>) {} fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental } @@ -51,11 +51,11 @@ fn borrows() { mod not_compiled { use std::pin::Pin; + #[pin_project] struct Foo; impl Foo { - fn foo(self: Pin<&mut Self>) { - } + fn foo(self: Pin<&mut Self>) {} fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental } diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr index a8890254facea..3952ba78d3c17 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr @@ -148,6 +148,16 @@ LL | let x: Pin<&_> = &pin const Foo; = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: the `#[pin_project]` attribute is an experimental feature + --> $DIR/feature-gate-pin_ergonomics.rs:5:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0382]: use of moved value: `x` --> $DIR/feature-gate-pin_ergonomics.rs:28:9 | @@ -177,16 +187,16 @@ LL | x.foo(); | ^ value used here after move | note: `Foo::foo` takes ownership of the receiver `self`, which moves `x` - --> $DIR/feature-gate-pin_ergonomics.rs:8:12 + --> $DIR/feature-gate-pin_ergonomics.rs:9:12 | -LL | fn foo(self: Pin<&mut Self>) { +LL | fn foo(self: Pin<&mut Self>) {} | ^^^^ help: consider reborrowing the `Pin` instead of moving it | LL | x.as_mut().foo(); | +++++++++ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors Some errors have detailed explanations: E0382, E0658. For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr index 559465bc13aba..96bac039df723 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.normal.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:45:28 + --> $DIR/pattern-matching-deref-pattern.rs:48:28 | LL | let Foo { x, y } = foo.as_mut(); | - - ^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | let Foo { x, ref y } = foo.as_mut(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:35:24 + --> $DIR/pattern-matching-deref-pattern.rs:38:24 | LL | let Foo { x, y } = foo.as_mut(); | - - ^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | let Foo { x, ref y } = foo.as_mut(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:67:28 + --> $DIR/pattern-matching-deref-pattern.rs:70:28 | LL | let Foo { x, y } = foo.as_ref(); | - - ^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | let Foo { x, ref y } = foo.as_ref(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:57:24 + --> $DIR/pattern-matching-deref-pattern.rs:60:24 | LL | let Foo { x, y } = foo.as_ref(); | - - ^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL | let Foo { x, ref y } = foo.as_ref(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:89:25 + --> $DIR/pattern-matching-deref-pattern.rs:92:25 | LL | let Bar(x, y) = bar.as_mut(); | - - ^^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | let Bar(x, ref y) = bar.as_mut(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:79:21 + --> $DIR/pattern-matching-deref-pattern.rs:82:21 | LL | let Bar(x, y) = bar.as_mut(); | - - ^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | let Bar(x, ref y) = bar.as_mut(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:111:25 + --> $DIR/pattern-matching-deref-pattern.rs:114:25 | LL | let Bar(x, y) = bar.as_ref(); | - - ^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | let Bar(x, ref y) = bar.as_ref(); | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/pattern-matching-deref-pattern.rs:101:21 + --> $DIR/pattern-matching-deref-pattern.rs:104:21 | LL | let Bar(x, y) = bar.as_ref(); | - - ^^^^^^^^^^^^ diff --git a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs index 6ecb22e535b13..26f52a0c79cf6 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs +++ b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs @@ -10,13 +10,16 @@ use std::pin::Pin; +#[cfg_attr(pin_ergonomics, pin_project)] struct Foo { x: T, y: U, } +#[cfg_attr(pin_ergonomics, pin_project)] struct Bar(T, U); +#[cfg_attr(pin_ergonomics, pin_project)] enum Baz { Foo(T, U), Bar { x: T, y: U }, diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr index 3e883fddb7a6b..cc3be291580bb 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr @@ -1,5 +1,73 @@ +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:121:9 + | +LL | let NonPinProject { x } = foo; + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:125:9 + | +LL | let NonPinProject { x } = bar; + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:131:9 + | +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:139:9 + | +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:37:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` @@ -8,7 +76,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:45:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` @@ -17,7 +85,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:59:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` @@ -26,7 +94,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:67:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` @@ -35,7 +103,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:81:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` @@ -44,7 +112,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:89:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` @@ -53,7 +121,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:103:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` @@ -62,7 +130,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:111:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` @@ -70,5 +138,5 @@ LL | Bar(x, y) => {} LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` -error: aborting due to 8 previous errors +error: aborting due to 12 previous errors diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr index 3e883fddb7a6b..fa2e418591c1f 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.deref_patterns.stderr @@ -1,5 +1,5 @@ error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:37:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` @@ -8,7 +8,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:45:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` @@ -17,7 +17,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:59:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` @@ -26,7 +26,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:67:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` @@ -35,7 +35,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:81:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` @@ -44,7 +44,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:89:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` @@ -53,7 +53,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:103:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` @@ -62,7 +62,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:111:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` @@ -70,5 +70,23 @@ LL | Bar(x, y) => {} LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` -error: aborting due to 8 previous errors +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:131:9 + | +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut NonPinProject>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&mut NonPinProject>` + +error: mix of deref patterns and normal constructors + --> $DIR/pattern-matching-mix-deref-pattern.rs:139:9 + | +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&NonPinProject>` +... +LL | Pin { .. } => {} + | ^^^^^^^^^^ matches directly on `Pin<&NonPinProject>` + +error: aborting due to 10 previous errors diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr index a39d7d79916c5..0e55a51702842 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.normal.stderr @@ -1,8 +1,23 @@ error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:33:9 | -LL | match foo { - | --- this expression has type `Pin<&mut Foo>` +LL | let Foo { x, y } = foo.as_mut(); + | ^^^^^^^^^^^^ ------------ this expression has type `Pin<&mut Foo>` + | | + | expected `Pin<&mut Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&mut Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Foo { x, y } = *foo.as_mut(); + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:37:9 + | +LL | match foo.as_mut() { + | ------------ this expression has type `Pin<&mut Foo>` LL | Foo { x, y } => {} | ^^^^^^^^^^^^ expected `Pin<&mut Foo>`, found `Foo<_, _>` | @@ -10,14 +25,14 @@ LL | Foo { x, y } => {} found struct `Foo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *foo { +LL | match *foo.as_mut() { | + error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:45:9 | -LL | let _ = || match foo { - | --- this expression has type `Pin<&mut Foo>` +LL | let _ = || match foo.as_mut() { + | ------------ this expression has type `Pin<&mut Foo>` LL | Foo { x, y } => {} | ^^^^^^^^^^^^ expected `Pin<&mut Foo>`, found `Foo<_, _>` | @@ -25,11 +40,26 @@ LL | Foo { x, y } => {} found struct `Foo<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | let _ = || match *foo { +LL | let _ = || match *foo.as_mut() { | + error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:55:9 + | +LL | let Foo { x, y } = foo; + | ^^^^^^^^^^^^ --- this expression has type `Pin<&Foo>` + | | + | expected `Pin<&Foo>`, found `Foo<_, _>` + | + = note: expected struct `Pin<&Foo>` + found struct `Foo<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Foo { x, y } = *foo; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:59:9 | LL | match foo { | --- this expression has type `Pin<&Foo>` @@ -44,7 +74,7 @@ LL | match *foo { | + error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:67:9 | LL | let _ = || match foo { | --- this expression has type `Pin<&Foo>` @@ -59,10 +89,25 @@ LL | let _ = || match *foo { | + error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:77:9 | -LL | match bar { - | --- this expression has type `Pin<&mut Bar>` +LL | let Bar(x, y) = bar.as_mut(); + | ^^^^^^^^^ ------------ this expression has type `Pin<&mut Bar>` + | | + | expected `Pin<&mut Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&mut Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Bar(x, y) = *bar.as_mut(); + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:81:9 + | +LL | match bar.as_mut() { + | ------------ this expression has type `Pin<&mut Bar>` LL | Bar(x, y) => {} | ^^^^^^^^^ expected `Pin<&mut Bar>`, found `Bar<_, _>` | @@ -70,14 +115,14 @@ LL | Bar(x, y) => {} found struct `Bar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | match *bar { +LL | match *bar.as_mut() { | + error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:89:9 | -LL | let _ = || match bar { - | --- this expression has type `Pin<&mut Bar>` +LL | let _ = || match bar.as_mut() { + | ------------ this expression has type `Pin<&mut Bar>` LL | Bar(x, y) => {} | ^^^^^^^^^ expected `Pin<&mut Bar>`, found `Bar<_, _>` | @@ -85,11 +130,26 @@ LL | Bar(x, y) => {} found struct `Bar<_, _>` help: consider dereferencing to access the inner value using the Deref trait | -LL | let _ = || match *bar { +LL | let _ = || match *bar.as_mut() { | + error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:99:9 + | +LL | let Bar(x, y) = bar; + | ^^^^^^^^^ --- this expression has type `Pin<&Bar>` + | | + | expected `Pin<&Bar>`, found `Bar<_, _>` + | + = note: expected struct `Pin<&Bar>` + found struct `Bar<_, _>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let Bar(x, y) = *bar; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:103:9 | LL | match bar { | --- this expression has type `Pin<&Bar>` @@ -104,7 +164,7 @@ LL | match *bar { | + error[E0308]: mismatched types - --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:111:9 | LL | let _ = || match bar { | --- this expression has type `Pin<&Bar>` @@ -118,6 +178,66 @@ help: consider dereferencing to access the inner value using the Deref trait LL | let _ = || match *bar { | + -error: aborting due to 8 previous errors +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:121:9 + | +LL | let NonPinProject { x } = foo; + | ^^^^^^^^^^^^^^^^^^^ --- this expression has type `Pin<&mut NonPinProject>` + | | + | expected `Pin<&mut NonPinProject>`, found `NonPinProject<_>` + | + = note: expected struct `Pin<&mut NonPinProject>` + found struct `NonPinProject<_>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let NonPinProject { x } = *foo; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:125:9 + | +LL | let NonPinProject { x } = bar; + | ^^^^^^^^^^^^^^^^^^^ --- this expression has type `Pin<&NonPinProject>` + | | + | expected `Pin<&NonPinProject>`, found `NonPinProject<_>` + | + = note: expected struct `Pin<&NonPinProject>` + found struct `NonPinProject<_>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | let NonPinProject { x } = *bar; + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:131:9 + | +LL | match foo { + | --- this expression has type `Pin<&mut NonPinProject>` +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ expected `Pin<&mut NonPinProject>`, found `NonPinProject<_>` + | + = note: expected struct `Pin<&mut NonPinProject>` + found struct `NonPinProject<_>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *foo { + | + + +error[E0308]: mismatched types + --> $DIR/pattern-matching-mix-deref-pattern.rs:139:9 + | +LL | match bar { + | --- this expression has type `Pin<&NonPinProject>` +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ expected `Pin<&NonPinProject>`, found `NonPinProject<_>` + | + = note: expected struct `Pin<&NonPinProject>` + found struct `NonPinProject<_>` +help: consider dereferencing to access the inner value using the Deref trait + | +LL | match *bar { + | + + +error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr index 3e883fddb7a6b..cc3be291580bb 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr @@ -1,5 +1,73 @@ +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:121:9 + | +LL | let NonPinProject { x } = foo; + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:125:9 + | +LL | let NonPinProject { x } = bar; + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:131:9 + | +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + +error: cannot project on type that is not `#[pin_project]` + --> $DIR/pattern-matching-mix-deref-pattern.rs:139:9 + | +LL | NonPinProject { x } => {} + | ^^^^^^^^^^^^^^^^^^^ + | +note: type defined here + --> $DIR/pattern-matching-mix-deref-pattern.rs:28:1 + | +LL | struct NonPinProject { + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: add `#[pin_project]` here + | +LL + #[pin_project] +LL | struct NonPinProject { + | + error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:27:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:37:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` @@ -8,7 +76,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:35:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:45:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Foo>` @@ -17,7 +85,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:46:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:59:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` @@ -26,7 +94,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:54:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:67:9 | LL | Foo { x, y } => {} | ^^^^^^^^^^^^ matches on the result of dereferencing `Pin<&Foo>` @@ -35,7 +103,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Foo>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:65:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:81:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` @@ -44,7 +112,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:73:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:89:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&mut Bar>` @@ -53,7 +121,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&mut Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:84:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:103:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` @@ -62,7 +130,7 @@ LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` error: mix of deref patterns and normal constructors - --> $DIR/pattern-matching-mix-deref-pattern.rs:92:9 + --> $DIR/pattern-matching-mix-deref-pattern.rs:111:9 | LL | Bar(x, y) => {} | ^^^^^^^^^ matches on the result of dereferencing `Pin<&Bar>` @@ -70,5 +138,5 @@ LL | Bar(x, y) => {} LL | Pin { .. } => {} | ^^^^^^^^^^ matches directly on `Pin<&Bar>` -error: aborting due to 8 previous errors +error: aborting due to 12 previous errors diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs index 8945205bea176..691d5d51cafcd 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs @@ -10,20 +10,30 @@ use std::pin::Pin; +#[cfg_attr(any(pin_ergonomics, both), pin_project)] struct Foo { x: T, y: U, } +#[cfg_attr(any(pin_ergonomics, both), pin_project)] struct Bar(T, U); +#[cfg_attr(any(pin_ergonomics, both), pin_project)] enum Baz { Foo(T, U), Bar { x: T, y: U }, } -fn foo_mut(foo: Pin<&mut Foo>) { - match foo { +struct NonPinProject { + x: T, +} + +fn foo_mut(mut foo: Pin<&mut Foo>) { + let Foo { x, y } = foo.as_mut(); + //[normal]~^ ERROR mismatched types + + match foo.as_mut() { Foo { x, y } => {} //[normal]~^ ERROR mismatched types //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors @@ -31,7 +41,7 @@ fn foo_mut(foo: Pin<&mut Foo>) { //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} } - let _ = || match foo { + let _ = || match foo.as_mut() { Foo { x, y } => {} //[normal]~^ ERROR mismatched types //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors @@ -42,6 +52,9 @@ fn foo_mut(foo: Pin<&mut Foo>) { } fn foo_const(foo: Pin<&Foo>) { + let Foo { x, y } = foo; + //[normal]~^ ERROR mismatched types + match foo { Foo { x, y } => {} //[normal]~^ ERROR mismatched types @@ -61,7 +74,10 @@ fn foo_const(foo: Pin<&Foo>) { } fn bar_mut(bar: Pin<&mut Bar>) { - match bar { + let Bar(x, y) = bar.as_mut(); + //[normal]~^ ERROR mismatched types + + match bar.as_mut() { Bar(x, y) => {} //[normal]~^ ERROR mismatched types //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors @@ -69,7 +85,7 @@ fn bar_mut(bar: Pin<&mut Bar>) { //[both]~^^^^ ERROR mix of deref patterns and normal constructors Pin { .. } => {} } - let _ = || match bar { + let _ = || match bar.as_mut() { Bar(x, y) => {} //[normal]~^ ERROR mismatched types //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors @@ -80,6 +96,9 @@ fn bar_mut(bar: Pin<&mut Bar>) { } fn bar_const(bar: Pin<&Bar>) { + let Bar(x, y) = bar; + //[normal]~^ ERROR mismatched types + match bar { Bar(x, y) => {} //[normal]~^ ERROR mismatched types @@ -98,4 +117,32 @@ fn bar_const(bar: Pin<&Bar>) { }; } +fn non_pin_project(foo: Pin<&mut NonPinProject>, bar: Pin<&NonPinProject>) { + let NonPinProject { x } = foo; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR cannot project on type that is not `#[pin_project]` + //[both]~^^^ ERROR cannot project on type that is not `#[pin_project]` + let NonPinProject { x } = bar; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR cannot project on type that is not `#[pin_project]` + //[both]~^^^ ERROR cannot project on type that is not `#[pin_project]` + + match foo { + NonPinProject { x } => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR cannot project on type that is not `#[pin_project]` + //[both]~^^^^ ERROR cannot project on type that is not `#[pin_project]` + Pin { .. } => {} + } + match bar { + NonPinProject { x } => {} + //[normal]~^ ERROR mismatched types + //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors + //[pin_ergonomics]~^^^ ERROR cannot project on type that is not `#[pin_project]` + //[both]~^^^^ ERROR cannot project on type that is not `#[pin_project]` + Pin { .. } => {} + } +} + fn main() {} diff --git a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr index 26f057195a15e..5d2d133761c43 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr @@ -1,5 +1,25 @@ +error[E0658]: the `#[pin_project]` attribute is an experimental feature + --> $DIR/pattern-matching.rs:12:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[pin_project]` attribute is an experimental feature + --> $DIR/pattern-matching.rs:18:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:34:9 + --> $DIR/pattern-matching.rs:33:9 | LL | let Foo { x, y } = foo_mut; | ^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Foo>` @@ -14,7 +34,7 @@ LL | let Foo { x, y } = *foo_mut; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:39:9 + --> $DIR/pattern-matching.rs:38:9 | LL | let Foo { x, y } = foo_const; | ^^^^^^^^^^^^ --------- this expression has type `Pin<&Foo>` @@ -29,7 +49,7 @@ LL | let Foo { x, y } = *foo_const; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:47:9 + --> $DIR/pattern-matching.rs:46:9 | LL | match bar_mut { | ------- this expression has type `Pin<&mut Bar>` @@ -44,7 +64,7 @@ LL | match *bar_mut { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:52:18 + --> $DIR/pattern-matching.rs:51:18 | LL | _ if let Bar::Bar { x, y } = bar_mut => { | ^^^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut Bar>` @@ -59,7 +79,7 @@ LL | _ if let Bar::Bar { x, y } = *bar_mut => { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:60:9 + --> $DIR/pattern-matching.rs:59:9 | LL | match bar_const { | --------- this expression has type `Pin<&Bar>` @@ -74,7 +94,7 @@ LL | match *bar_const { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:65:18 + --> $DIR/pattern-matching.rs:64:18 | LL | _ if let Bar::Foo(x, y) = bar_const => { | ^^^^^^^^^^^^^^ --------- this expression has type `Pin<&Bar>` @@ -89,7 +109,7 @@ LL | _ if let Bar::Foo(x, y) = *bar_const => { | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:75:9 + --> $DIR/pattern-matching.rs:74:9 | LL | let (Foo { x, y },) = foo_mut; | ^^^^^^^^^^^^^^^ ------- this expression has type `Pin<&mut (Foo,)>` @@ -104,7 +124,7 @@ LL | let (Foo { x, y },) = *foo_mut; | + error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:79:9 + --> $DIR/pattern-matching.rs:78:9 | LL | let (Foo { x, y },) = foo_const; | ^^^^^^^^^^^^^^^ --------- this expression has type `Pin<&(Foo,)>` @@ -119,31 +139,31 @@ LL | let (Foo { x, y },) = *foo_const; | + error[E0529]: expected an array or slice, found `Pin<&mut [Foo; 1]>` - --> $DIR/pattern-matching.rs:86:9 + --> $DIR/pattern-matching.rs:85:9 | LL | let [Foo { x, y }] = foo_mut; | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [Foo; 1]>` error[E0529]: expected an array or slice, found `Pin<&[Foo; 1]>` - --> $DIR/pattern-matching.rs:90:9 + --> $DIR/pattern-matching.rs:89:9 | LL | let [Foo { x, y }] = foo_const; | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[Foo; 1]>` error[E0529]: expected an array or slice, found `Pin<&mut [Foo]>` - --> $DIR/pattern-matching.rs:97:12 + --> $DIR/pattern-matching.rs:96:12 | LL | if let [Foo { x, y }] = foo_mut { | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&mut [Foo]>` error[E0529]: expected an array or slice, found `Pin<&[Foo]>` - --> $DIR/pattern-matching.rs:102:12 + --> $DIR/pattern-matching.rs:101:12 | LL | if let [Foo { x, y }] = foo_const { | ^^^^^^^^^^^^^^ pattern cannot match with input type `Pin<&[Foo]>` error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:110:5 + --> $DIR/pattern-matching.rs:109:5 | LL | (&mut x,): Pin<&'a mut (&'a mut Foo,)>, | ^^^^^^^^^ --------------------------------- expected due to this @@ -154,7 +174,7 @@ LL | (&mut x,): Pin<&'a mut (&'a mut Foo,)>, found tuple `(_,)` error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:116:5 + --> $DIR/pattern-matching.rs:115:5 | LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, | ^^^^^^^^^ --------------------------------- expected due to this @@ -165,7 +185,7 @@ LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, found tuple `(_,)` error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:122:5 + --> $DIR/pattern-matching.rs:121:5 | LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>, | ^^^^^^^^^ --------------------------------- expected due to this @@ -180,7 +200,7 @@ LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>.pointer, | ++++++++ error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:128:5 + --> $DIR/pattern-matching.rs:127:5 | LL | &mut (x,): Pin<&'a mut &'a mut (Foo,)>, | ^^^^^^^^^ --------------------------------- expected due to this @@ -195,7 +215,7 @@ LL | &mut (x,): Pin<&'a mut &'a mut (Foo,)>.pointer, | ++++++++ error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:134:5 + --> $DIR/pattern-matching.rs:133:5 | LL | (x,): Pin<&'a mut (&'a mut Foo,)>, | ^^^^ --------------------------------- expected due to this @@ -206,7 +226,7 @@ LL | (x,): Pin<&'a mut (&'a mut Foo,)>, found tuple `(_,)` error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:140:5 + --> $DIR/pattern-matching.rs:139:5 | LL | (x,): Pin<&'a mut &'a mut (Foo,)>, | ^^^^ --------------------------------- expected due to this @@ -216,7 +236,7 @@ LL | (x,): Pin<&'a mut &'a mut (Foo,)>, = note: expected struct `Pin<&'a mut &'a mut (Foo,)>` found tuple `(_,)` -error: aborting due to 18 previous errors +error: aborting due to 20 previous errors -Some errors have detailed explanations: E0308, E0529. +Some errors have detailed explanations: E0308, E0529, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr b/tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr index fd442b8263c05..8cb032b73d859 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching.pin_ergonomics.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:116:6 + --> $DIR/pattern-matching.rs:115:6 | LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, | ^^^^^^ --------------------------------- expected due to this @@ -9,7 +9,7 @@ LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, = note: expected struct `Foo` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-matching.rs:116:6 + --> $DIR/pattern-matching.rs:115:6 | LL | (&mut x,): Pin<&'a mut &'a mut (Foo,)>, | ^^^^^^ @@ -20,7 +20,7 @@ LL + (x,): Pin<&'a mut &'a mut (Foo,)>, | error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:122:5 + --> $DIR/pattern-matching.rs:121:5 | LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>, | ^^^^^^^^^ --------------------------------- expected due to this @@ -35,7 +35,7 @@ LL | &mut (x,): Pin<&'a mut (&'a mut Foo,)>.pointer, | ++++++++ error[E0308]: mismatched types - --> $DIR/pattern-matching.rs:128:5 + --> $DIR/pattern-matching.rs:127:5 | LL | &mut (x,): Pin<&'a mut &'a mut (Foo,)>, | ^^^^^^^^^ --------------------------------- expected due to this diff --git a/tests/ui/pin-ergonomics/pattern-matching.rs b/tests/ui/pin-ergonomics/pattern-matching.rs index 4f2a23afbb8ff..8798e2ed7402e 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.rs +++ b/tests/ui/pin-ergonomics/pattern-matching.rs @@ -7,16 +7,15 @@ use std::pin::Pin; // This test verifies that a `&pin mut T` can be projected to a pinned -// reference field `&pin mut T.U`. -// FIXME(pin_ergonomics): it is unsound to project `&pin mut T` to -// `&pin mut T.U` when `U: !Unpin` but `T: Unpin`, or when there exists -// `impl Drop for T` that takes a `&mut self` receiver. +// reference field `&pin mut T.U` when `T` is marked with `#[pin_project]`. +#[pin_project] //[normal]~ ERROR the `#[pin_project]` attribute is an experimental feature struct Foo { x: T, y: U, } +#[pin_project] //[normal]~ ERROR the `#[pin_project]` attribute is an experimental feature enum Bar { Foo(T, U), Bar { x: T, y: U }, diff --git a/tests/ui/pin-ergonomics/pin_project-attr.rs b/tests/ui/pin-ergonomics/pin_project-attr.rs new file mode 100644 index 0000000000000..be9bcc34d4947 --- /dev/null +++ b/tests/ui/pin-ergonomics/pin_project-attr.rs @@ -0,0 +1,144 @@ +#![feature( + pin_ergonomics, + where_clause_attrs, + trait_alias, + extern_types, + associated_type_defaults, + fn_delegation, +)] +#![allow(incomplete_features)] +#![pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on crates + +// allowed + +#[pin_project] +struct Struct {} + +#[pin_project] +enum Enum {} + +#[pin_project] +union Union { + field: (), +} + +// disallowed + +enum Foo<#[pin_project] T, #[pin_project] U = ()> { + //~^ ERROR `#[pin_project]` attribute cannot be used on function params + //~| ERROR `#[pin_project]` attribute cannot be used on function params + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on enum variants + UnitVariant, + TupleVariant(#[pin_project] T), //~ ERROR `#[pin_project]` attribute cannot be used on struct fields + StructVariant { + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on struct fields + field: U, + }, +} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on traits +trait Trait { + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on associated consts + const ASSOC_CONST: () = (); + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on associated types + type AssocType = (); + + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on required trait methods + fn method(); + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on provided trait methods + fn method_with_body() {} +} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on trait aliases +trait TraitAlias = Trait; + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on inherent impl blocks +impl Struct { + // FIXME: delegation macros are not tested yet (how to?) + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on delegations + reuse ::type_id; + + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on inherent methods + fn method() {} +} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on trait impl blocks +impl Trait for Enum { + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on trait methods in impl blocks + fn method() {} +} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on extern crates +extern crate alloc; + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on use statements +use std::pin::Pin; + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on statics +static STATIC: () = (); + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on constants +const CONST: () = (); + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on functions +fn f(#[pin_project] param: Foo) +//~^ ERROR `#[pin_project]` attribute cannot be used on function params +//~| ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters +where + #[pin_project] + //~^ ERROR `#[pin_project]` attribute cannot be used on where predicates + T:, +{ + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on closures + || (); + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on expressions + [(), (), ()]; + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on statements + let _: Foo<(), ()> = Foo::StructVariant { + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on struct fields + field: (), + }; + match param { + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on match arms + Foo::UnitVariant => {} + Foo::TupleVariant(..) => {} + Foo::StructVariant { + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on pattern fields + field, + } => {} + } +} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on modules +mod m {} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign modules +extern "C" { + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign types + type ForeignTy; + + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign statics + static EXTERN_STATIC: (); + + #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign functions + fn extern_fn(); +} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on type alias +type Type = (); + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on macro defs +macro_rules! macro_def { + () => {}; +} + +#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on macro calls +macro_def!(); + +std::arch::global_asm! { + "{}", + #[pin_project] //~ ERROR this attribute is not supported on assembly + const 0 +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/pin_project-attr.stderr b/tests/ui/pin-ergonomics/pin_project-attr.stderr new file mode 100644 index 0000000000000..aa1c376401ba7 --- /dev/null +++ b/tests/ui/pin-ergonomics/pin_project-attr.stderr @@ -0,0 +1,318 @@ +error: `#[pin_project]` attribute cannot be used on macro calls + --> $DIR/pin_project-attr.rs:135:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: this attribute is not supported on assembly + --> $DIR/pin_project-attr.rs:140:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + +error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + --> $DIR/pin_project-attr.rs:84:12 + | +LL | fn f(#[pin_project] param: Foo) + | ^^^^^^^^^^^^^^ + +error: `#[pin_project]` attribute cannot be used on crates + --> $DIR/pin_project-attr.rs:10:1 + | +LL | #![pin_project] + | ^^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on function params + --> $DIR/pin_project-attr.rs:27:10 + | +LL | enum Foo<#[pin_project] T, #[pin_project] U = ()> { + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on function params + --> $DIR/pin_project-attr.rs:27:28 + | +LL | enum Foo<#[pin_project] T, #[pin_project] U = ()> { + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on enum variants + --> $DIR/pin_project-attr.rs:30:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on struct fields + --> $DIR/pin_project-attr.rs:32:18 + | +LL | TupleVariant(#[pin_project] T), + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on struct fields + --> $DIR/pin_project-attr.rs:34:9 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on traits + --> $DIR/pin_project-attr.rs:39:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on associated consts + --> $DIR/pin_project-attr.rs:41:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on associated types + --> $DIR/pin_project-attr.rs:43:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on required trait methods + --> $DIR/pin_project-attr.rs:46:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on provided trait methods + --> $DIR/pin_project-attr.rs:48:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on trait aliases + --> $DIR/pin_project-attr.rs:52:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on inherent impl blocks + --> $DIR/pin_project-attr.rs:55:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on delegations + --> $DIR/pin_project-attr.rs:58:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on inherent methods + --> $DIR/pin_project-attr.rs:61:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on trait impl blocks + --> $DIR/pin_project-attr.rs:65:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on trait methods in impl blocks + --> $DIR/pin_project-attr.rs:67:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on extern crates + --> $DIR/pin_project-attr.rs:71:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on use statements + --> $DIR/pin_project-attr.rs:74:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on statics + --> $DIR/pin_project-attr.rs:77:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on constants + --> $DIR/pin_project-attr.rs:80:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on functions + --> $DIR/pin_project-attr.rs:83:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on function params + --> $DIR/pin_project-attr.rs:84:12 + | +LL | fn f(#[pin_project] param: Foo) + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on closures + --> $DIR/pin_project-attr.rs:92:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on expressions + --> $DIR/pin_project-attr.rs:94:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on struct fields + --> $DIR/pin_project-attr.rs:98:9 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on statements + --> $DIR/pin_project-attr.rs:96:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on match arms + --> $DIR/pin_project-attr.rs:102:9 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on pattern fields + --> $DIR/pin_project-attr.rs:106:13 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on where predicates + --> $DIR/pin_project-attr.rs:88:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on modules + --> $DIR/pin_project-attr.rs:112:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on foreign modules + --> $DIR/pin_project-attr.rs:115:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on foreign types + --> $DIR/pin_project-attr.rs:117:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on foreign statics + --> $DIR/pin_project-attr.rs:120:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on foreign functions + --> $DIR/pin_project-attr.rs:123:5 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on type aliases + --> $DIR/pin_project-attr.rs:127:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: `#[pin_project]` attribute cannot be used on macro defs + --> $DIR/pin_project-attr.rs:130:1 + | +LL | #[pin_project] + | ^^^^^^^^^^^^^^ + | + = help: `#[pin_project]` can be applied to data types and unions + +error: aborting due to 40 previous errors + From ace83458a4d2a36681f2344677dc5b04dc78dd39 Mon Sep 17 00:00:00 2001 From: Frank King Date: Fri, 24 Oct 2025 20:59:33 +0800 Subject: [PATCH 17/45] Rename `#[pin_project]` to `#[pin_v2]` to avoid naming conflicts --- .../rustc_attr_parsing/src/attributes/mod.rs | 2 +- .../attributes/{pin_project.rs => pin_v2.rs} | 8 +- compiler/rustc_attr_parsing/src/context.rs | 4 +- compiler/rustc_feature/src/builtin_attrs.rs | 6 +- .../rustc_hir/src/attrs/data_structures.rs | 4 +- .../rustc_hir/src/attrs/encode_cross_crate.rs | 2 +- compiler/rustc_hir_typeck/messages.ftl | 4 +- compiler/rustc_hir_typeck/src/errors.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_middle/src/ty/adt.rs | 4 +- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- .../tests/ui/explicit_write_in_test.stderr | 0 .../feature-gate-pin_ergonomics.rs | 4 +- .../feature-gate-pin_ergonomics.stderr | 6 +- .../pattern-matching-deref-pattern.rs | 6 +- ...ern-matching-mix-deref-pattern.both.stderr | 24 +- ...ng-mix-deref-pattern.pin_ergonomics.stderr | 24 +- .../pattern-matching-mix-deref-pattern.rs | 22 +- .../pattern-matching.normal.stderr | 12 +- tests/ui/pin-ergonomics/pattern-matching.rs | 6 +- tests/ui/pin-ergonomics/pin_project-attr.rs | 144 -------- .../ui/pin-ergonomics/pin_project-attr.stderr | 318 ------------------ tests/ui/pin-ergonomics/pin_v2-attr.rs | 144 ++++++++ tests/ui/pin-ergonomics/pin_v2-attr.stderr | 318 ++++++++++++++++++ 25 files changed, 535 insertions(+), 535 deletions(-) rename compiler/rustc_attr_parsing/src/attributes/{pin_project.rs => pin_v2.rs} (78%) delete mode 100644 src/tools/clippy/tests/ui/explicit_write_in_test.stderr delete mode 100644 tests/ui/pin-ergonomics/pin_project-attr.rs delete mode 100644 tests/ui/pin-ergonomics/pin_project-attr.stderr create mode 100644 tests/ui/pin-ergonomics/pin_v2-attr.rs create mode 100644 tests/ui/pin-ergonomics/pin_v2-attr.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 207fdb7ccabd7..093969586596d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -48,7 +48,7 @@ pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; pub(crate) mod non_exhaustive; pub(crate) mod path; -pub(crate) mod pin_project; +pub(crate) mod pin_v2; pub(crate) mod proc_macro_attrs; pub(crate) mod prototype; pub(crate) mod repr; diff --git a/compiler/rustc_attr_parsing/src/attributes/pin_project.rs b/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs similarity index 78% rename from compiler/rustc_attr_parsing/src/attributes/pin_project.rs rename to compiler/rustc_attr_parsing/src/attributes/pin_v2.rs index 9a81f82c9f54d..597a9515b0048 100644 --- a/compiler/rustc_attr_parsing/src/attributes/pin_project.rs +++ b/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs @@ -7,15 +7,15 @@ use crate::context::Stage; use crate::target_checking::AllowedTargets; use crate::target_checking::Policy::Allow; -pub(crate) struct PinProjectParser; +pub(crate) struct PinV2Parser; -impl NoArgsAttributeParser for PinProjectParser { - const PATH: &[Symbol] = &[sym::pin_project]; +impl NoArgsAttributeParser for PinV2Parser { + const PATH: &[Symbol] = &[sym::pin_v2]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Struct), Allow(Target::Union), ]); - const CREATE: fn(Span) -> AttributeKind = AttributeKind::PinProject; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::PinV2; } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b2bd5ffad8d43..15904fd7d3348 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -47,7 +47,7 @@ use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; use crate::attributes::non_exhaustive::NonExhaustiveParser; use crate::attributes::path::PathParser as PathAttributeParser; -use crate::attributes::pin_project::PinProjectParser; +use crate::attributes::pin_v2::PinV2Parser; use crate::attributes::proc_macro_attrs::{ ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser, }; @@ -234,7 +234,7 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index c97c457086a40..2c472801aa044 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -893,13 +893,13 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::No, loop_match, experimental!(loop_match) ), - // The `#[pin_project]` attribute is part of the `pin_ergonomics` experiment + // The `#[pin_v2]` attribute is part of the `pin_ergonomics` experiment // that allows structurally pinning, tracked in: // // - https://github.com/rust-lang/rust/issues/130494 gated!( - pin_project, Normal, template!(Word), ErrorFollowing, - EncodeCrossCrate::Yes, pin_ergonomics, experimental!(pin_project), + pin_v2, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::Yes, pin_ergonomics, experimental!(pin_v2), ), // ========================================================================== diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 29b4d2d96dd20..1bb87673d52d2 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -637,8 +637,8 @@ pub enum AttributeKind { /// Represents `#[pattern_complexity_limit]` PatternComplexityLimit { attr_span: Span, limit_span: Span, limit: Limit }, - /// Represents `#[pin_project]` - PinProject(Span), + /// Represents `#[pin_v2]` + PinV2(Span), /// Represents `#[pointee]` Pointee(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e9a183437693f..11c54b0ac1da0 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -77,7 +77,7 @@ impl AttributeKind { PassByValue(..) => Yes, Path(..) => No, PatternComplexityLimit { .. } => No, - PinProject(..) => Yes, + PinV2(..) => Yes, Pointee(..) => No, ProcMacro(..) => No, ProcMacroAttribute(..) => No, diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index f14441a6363e7..60303d5ee81e4 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -227,9 +227,9 @@ hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function .suggestion = cast the value to `{$cast_ty}` .teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules -hir_typeck_project_on_non_pin_project_type = cannot project on type that is not `#[pin_project]` +hir_typeck_project_on_non_pin_project_type = cannot project on type that is not `#[pin_v2]` .note = type defined here - .suggestion = add `#[pin_project]` here + .suggestion = add `#[pin_v2]` here hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> [1] auto trait {$traits} diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 34e0c9f0f68a6..615a8c95056d1 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1164,6 +1164,6 @@ pub(crate) struct ProjectOnNonPinProjectType { pub span: Span, #[note] pub def_span: Option, - #[suggestion(code = "#[pin_project]\n", applicability = "machine-applicable")] + #[suggestion(code = "#[pin_v2]\n", applicability = "machine-applicable")] pub sugg_span: Option, } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index d3867bda6fa0a..f27085d59c0ed 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -555,7 +555,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("scrutinee ty {expected:?} is a pinned reference, inserting pin deref"); // if the inner_ty is an ADT, make sure that it can be structurally pinned - // (i.e., it is `#[pin_project]`). + // (i.e., it is `#[pin_v2]`). if let Some(adt) = inner_ty.ty_adt_def() && !adt.is_pin_project() && !adt.is_pin() diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 8386504245cde..510c546f82a4e 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -288,7 +288,7 @@ impl AdtDefData { debug!("found non-exhaustive variant list for {:?}", did); flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; } - if find_attr!(tcx.get_all_attrs(did), AttributeKind::PinProject(..)) { + if find_attr!(tcx.get_all_attrs(did), AttributeKind::PinV2(..)) { debug!("found pin-project type {:?}", did); flags |= AdtFlags::IS_PIN_PROJECT; } @@ -445,7 +445,7 @@ impl<'tcx> AdtDef<'tcx> { self.flags().contains(AdtFlags::IS_PIN) } - /// Returns `true` is this is `#[pin_project]` for the purposes + /// Returns `true` is this is `#[pin_v2]` for the purposes /// of structural pinning. #[inline] pub fn is_pin_project(self) -> bool { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3cd1d5ba61b48..c214104d60670 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -284,7 +284,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::DebuggerVisualizer(..) | AttributeKind::RustcMain - | AttributeKind::PinProject(..), + | AttributeKind::PinV2(..), ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c378927ded895..811bd1a6136e9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1667,7 +1667,7 @@ symbols! { pin, pin_ergonomics, pin_macro, - pin_project, + pin_v2, platform_intrinsics, plugin, plugin_registrar, diff --git a/src/tools/clippy/tests/ui/explicit_write_in_test.stderr b/src/tools/clippy/tests/ui/explicit_write_in_test.stderr deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs index 47c4b36a07703..07aba0d1d2815 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs @@ -2,7 +2,7 @@ use std::pin::Pin; -#[pin_project] //~ ERROR the `#[pin_project]` attribute is an experimental feature +#[pin_v2] //~ ERROR the `#[pin_v2]` attribute is an experimental feature struct Foo; impl Foo { @@ -51,7 +51,7 @@ fn borrows() { mod not_compiled { use std::pin::Pin; - #[pin_project] + #[pin_v2] struct Foo; impl Foo { diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr index 3952ba78d3c17..cff564c01fc6b 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr @@ -148,11 +148,11 @@ LL | let x: Pin<&_> = &pin const Foo; = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: the `#[pin_project]` attribute is an experimental feature +error[E0658]: the `#[pin_v2]` attribute is an experimental feature --> $DIR/feature-gate-pin_ergonomics.rs:5:1 | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ +LL | #[pin_v2] + | ^^^^^^^^^ | = note: see issue #130494 for more information = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable diff --git a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs index 26f52a0c79cf6..3ec9b8fe476f1 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs +++ b/tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs @@ -10,16 +10,16 @@ use std::pin::Pin; -#[cfg_attr(pin_ergonomics, pin_project)] +#[cfg_attr(pin_ergonomics, pin_v2)] struct Foo { x: T, y: U, } -#[cfg_attr(pin_ergonomics, pin_project)] +#[cfg_attr(pin_ergonomics, pin_v2)] struct Bar(T, U); -#[cfg_attr(pin_ergonomics, pin_project)] +#[cfg_attr(pin_ergonomics, pin_v2)] enum Baz { Foo(T, U), Bar { x: T, y: U }, diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr index cc3be291580bb..9bcb41299b7da 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.both.stderr @@ -1,4 +1,4 @@ -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:121:9 | LL | let NonPinProject { x } = foo; @@ -9,13 +9,13 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:125:9 | LL | let NonPinProject { x } = bar; @@ -26,13 +26,13 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:131:9 | LL | NonPinProject { x } => {} @@ -43,13 +43,13 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:139:9 | LL | NonPinProject { x } => {} @@ -60,9 +60,9 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr index cc3be291580bb..9bcb41299b7da 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.pin_ergonomics.stderr @@ -1,4 +1,4 @@ -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:121:9 | LL | let NonPinProject { x } = foo; @@ -9,13 +9,13 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:125:9 | LL | let NonPinProject { x } = bar; @@ -26,13 +26,13 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:131:9 | LL | NonPinProject { x } => {} @@ -43,13 +43,13 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | -error: cannot project on type that is not `#[pin_project]` +error: cannot project on type that is not `#[pin_v2]` --> $DIR/pattern-matching-mix-deref-pattern.rs:139:9 | LL | NonPinProject { x } => {} @@ -60,9 +60,9 @@ note: type defined here | LL | struct NonPinProject { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: add `#[pin_project]` here +help: add `#[pin_v2]` here | -LL + #[pin_project] +LL + #[pin_v2] LL | struct NonPinProject { | diff --git a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs index 691d5d51cafcd..2b2a4e61abfd1 100644 --- a/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs +++ b/tests/ui/pin-ergonomics/pattern-matching-mix-deref-pattern.rs @@ -10,16 +10,16 @@ use std::pin::Pin; -#[cfg_attr(any(pin_ergonomics, both), pin_project)] +#[cfg_attr(any(pin_ergonomics, both), pin_v2)] struct Foo { x: T, y: U, } -#[cfg_attr(any(pin_ergonomics, both), pin_project)] +#[cfg_attr(any(pin_ergonomics, both), pin_v2)] struct Bar(T, U); -#[cfg_attr(any(pin_ergonomics, both), pin_project)] +#[cfg_attr(any(pin_ergonomics, both), pin_v2)] enum Baz { Foo(T, U), Bar { x: T, y: U }, @@ -120,27 +120,27 @@ fn bar_const(bar: Pin<&Bar>) { fn non_pin_project(foo: Pin<&mut NonPinProject>, bar: Pin<&NonPinProject>) { let NonPinProject { x } = foo; //[normal]~^ ERROR mismatched types - //[pin_ergonomics]~^^ ERROR cannot project on type that is not `#[pin_project]` - //[both]~^^^ ERROR cannot project on type that is not `#[pin_project]` + //[pin_ergonomics]~^^ ERROR cannot project on type that is not `#[pin_v2]` + //[both]~^^^ ERROR cannot project on type that is not `#[pin_v2]` let NonPinProject { x } = bar; //[normal]~^ ERROR mismatched types - //[pin_ergonomics]~^^ ERROR cannot project on type that is not `#[pin_project]` - //[both]~^^^ ERROR cannot project on type that is not `#[pin_project]` + //[pin_ergonomics]~^^ ERROR cannot project on type that is not `#[pin_v2]` + //[both]~^^^ ERROR cannot project on type that is not `#[pin_v2]` match foo { NonPinProject { x } => {} //[normal]~^ ERROR mismatched types //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors - //[pin_ergonomics]~^^^ ERROR cannot project on type that is not `#[pin_project]` - //[both]~^^^^ ERROR cannot project on type that is not `#[pin_project]` + //[pin_ergonomics]~^^^ ERROR cannot project on type that is not `#[pin_v2]` + //[both]~^^^^ ERROR cannot project on type that is not `#[pin_v2]` Pin { .. } => {} } match bar { NonPinProject { x } => {} //[normal]~^ ERROR mismatched types //[deref_patterns]~^^ ERROR mix of deref patterns and normal constructors - //[pin_ergonomics]~^^^ ERROR cannot project on type that is not `#[pin_project]` - //[both]~^^^^ ERROR cannot project on type that is not `#[pin_project]` + //[pin_ergonomics]~^^^ ERROR cannot project on type that is not `#[pin_v2]` + //[both]~^^^^ ERROR cannot project on type that is not `#[pin_v2]` Pin { .. } => {} } } diff --git a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr index 5d2d133761c43..8ec481fba9e0d 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.normal.stderr +++ b/tests/ui/pin-ergonomics/pattern-matching.normal.stderr @@ -1,18 +1,18 @@ -error[E0658]: the `#[pin_project]` attribute is an experimental feature +error[E0658]: the `#[pin_v2]` attribute is an experimental feature --> $DIR/pattern-matching.rs:12:1 | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ +LL | #[pin_v2] + | ^^^^^^^^^ | = note: see issue #130494 for more information = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: the `#[pin_project]` attribute is an experimental feature +error[E0658]: the `#[pin_v2]` attribute is an experimental feature --> $DIR/pattern-matching.rs:18:1 | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ +LL | #[pin_v2] + | ^^^^^^^^^ | = note: see issue #130494 for more information = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable diff --git a/tests/ui/pin-ergonomics/pattern-matching.rs b/tests/ui/pin-ergonomics/pattern-matching.rs index 8798e2ed7402e..96a4705bf9b3b 100644 --- a/tests/ui/pin-ergonomics/pattern-matching.rs +++ b/tests/ui/pin-ergonomics/pattern-matching.rs @@ -7,15 +7,15 @@ use std::pin::Pin; // This test verifies that a `&pin mut T` can be projected to a pinned -// reference field `&pin mut T.U` when `T` is marked with `#[pin_project]`. +// reference field `&pin mut T.U` when `T` is marked with `#[pin_v2]`. -#[pin_project] //[normal]~ ERROR the `#[pin_project]` attribute is an experimental feature +#[pin_v2] //[normal]~ ERROR the `#[pin_v2]` attribute is an experimental feature struct Foo { x: T, y: U, } -#[pin_project] //[normal]~ ERROR the `#[pin_project]` attribute is an experimental feature +#[pin_v2] //[normal]~ ERROR the `#[pin_v2]` attribute is an experimental feature enum Bar { Foo(T, U), Bar { x: T, y: U }, diff --git a/tests/ui/pin-ergonomics/pin_project-attr.rs b/tests/ui/pin-ergonomics/pin_project-attr.rs deleted file mode 100644 index be9bcc34d4947..0000000000000 --- a/tests/ui/pin-ergonomics/pin_project-attr.rs +++ /dev/null @@ -1,144 +0,0 @@ -#![feature( - pin_ergonomics, - where_clause_attrs, - trait_alias, - extern_types, - associated_type_defaults, - fn_delegation, -)] -#![allow(incomplete_features)] -#![pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on crates - -// allowed - -#[pin_project] -struct Struct {} - -#[pin_project] -enum Enum {} - -#[pin_project] -union Union { - field: (), -} - -// disallowed - -enum Foo<#[pin_project] T, #[pin_project] U = ()> { - //~^ ERROR `#[pin_project]` attribute cannot be used on function params - //~| ERROR `#[pin_project]` attribute cannot be used on function params - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on enum variants - UnitVariant, - TupleVariant(#[pin_project] T), //~ ERROR `#[pin_project]` attribute cannot be used on struct fields - StructVariant { - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on struct fields - field: U, - }, -} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on traits -trait Trait { - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on associated consts - const ASSOC_CONST: () = (); - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on associated types - type AssocType = (); - - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on required trait methods - fn method(); - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on provided trait methods - fn method_with_body() {} -} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on trait aliases -trait TraitAlias = Trait; - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on inherent impl blocks -impl Struct { - // FIXME: delegation macros are not tested yet (how to?) - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on delegations - reuse ::type_id; - - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on inherent methods - fn method() {} -} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on trait impl blocks -impl Trait for Enum { - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on trait methods in impl blocks - fn method() {} -} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on extern crates -extern crate alloc; - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on use statements -use std::pin::Pin; - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on statics -static STATIC: () = (); - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on constants -const CONST: () = (); - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on functions -fn f(#[pin_project] param: Foo) -//~^ ERROR `#[pin_project]` attribute cannot be used on function params -//~| ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters -where - #[pin_project] - //~^ ERROR `#[pin_project]` attribute cannot be used on where predicates - T:, -{ - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on closures - || (); - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on expressions - [(), (), ()]; - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on statements - let _: Foo<(), ()> = Foo::StructVariant { - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on struct fields - field: (), - }; - match param { - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on match arms - Foo::UnitVariant => {} - Foo::TupleVariant(..) => {} - Foo::StructVariant { - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on pattern fields - field, - } => {} - } -} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on modules -mod m {} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign modules -extern "C" { - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign types - type ForeignTy; - - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign statics - static EXTERN_STATIC: (); - - #[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on foreign functions - fn extern_fn(); -} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on type alias -type Type = (); - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on macro defs -macro_rules! macro_def { - () => {}; -} - -#[pin_project] //~ ERROR `#[pin_project]` attribute cannot be used on macro calls -macro_def!(); - -std::arch::global_asm! { - "{}", - #[pin_project] //~ ERROR this attribute is not supported on assembly - const 0 -} - -fn main() {} diff --git a/tests/ui/pin-ergonomics/pin_project-attr.stderr b/tests/ui/pin-ergonomics/pin_project-attr.stderr deleted file mode 100644 index aa1c376401ba7..0000000000000 --- a/tests/ui/pin-ergonomics/pin_project-attr.stderr +++ /dev/null @@ -1,318 +0,0 @@ -error: `#[pin_project]` attribute cannot be used on macro calls - --> $DIR/pin_project-attr.rs:135:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: this attribute is not supported on assembly - --> $DIR/pin_project-attr.rs:140:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - -error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/pin_project-attr.rs:84:12 - | -LL | fn f(#[pin_project] param: Foo) - | ^^^^^^^^^^^^^^ - -error: `#[pin_project]` attribute cannot be used on crates - --> $DIR/pin_project-attr.rs:10:1 - | -LL | #![pin_project] - | ^^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on function params - --> $DIR/pin_project-attr.rs:27:10 - | -LL | enum Foo<#[pin_project] T, #[pin_project] U = ()> { - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on function params - --> $DIR/pin_project-attr.rs:27:28 - | -LL | enum Foo<#[pin_project] T, #[pin_project] U = ()> { - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on enum variants - --> $DIR/pin_project-attr.rs:30:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on struct fields - --> $DIR/pin_project-attr.rs:32:18 - | -LL | TupleVariant(#[pin_project] T), - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on struct fields - --> $DIR/pin_project-attr.rs:34:9 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on traits - --> $DIR/pin_project-attr.rs:39:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on associated consts - --> $DIR/pin_project-attr.rs:41:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on associated types - --> $DIR/pin_project-attr.rs:43:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on required trait methods - --> $DIR/pin_project-attr.rs:46:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on provided trait methods - --> $DIR/pin_project-attr.rs:48:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on trait aliases - --> $DIR/pin_project-attr.rs:52:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on inherent impl blocks - --> $DIR/pin_project-attr.rs:55:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on delegations - --> $DIR/pin_project-attr.rs:58:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on inherent methods - --> $DIR/pin_project-attr.rs:61:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on trait impl blocks - --> $DIR/pin_project-attr.rs:65:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on trait methods in impl blocks - --> $DIR/pin_project-attr.rs:67:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on extern crates - --> $DIR/pin_project-attr.rs:71:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on use statements - --> $DIR/pin_project-attr.rs:74:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on statics - --> $DIR/pin_project-attr.rs:77:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on constants - --> $DIR/pin_project-attr.rs:80:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on functions - --> $DIR/pin_project-attr.rs:83:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on function params - --> $DIR/pin_project-attr.rs:84:12 - | -LL | fn f(#[pin_project] param: Foo) - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on closures - --> $DIR/pin_project-attr.rs:92:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on expressions - --> $DIR/pin_project-attr.rs:94:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on struct fields - --> $DIR/pin_project-attr.rs:98:9 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on statements - --> $DIR/pin_project-attr.rs:96:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on match arms - --> $DIR/pin_project-attr.rs:102:9 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on pattern fields - --> $DIR/pin_project-attr.rs:106:13 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on where predicates - --> $DIR/pin_project-attr.rs:88:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on modules - --> $DIR/pin_project-attr.rs:112:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on foreign modules - --> $DIR/pin_project-attr.rs:115:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on foreign types - --> $DIR/pin_project-attr.rs:117:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on foreign statics - --> $DIR/pin_project-attr.rs:120:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on foreign functions - --> $DIR/pin_project-attr.rs:123:5 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on type aliases - --> $DIR/pin_project-attr.rs:127:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: `#[pin_project]` attribute cannot be used on macro defs - --> $DIR/pin_project-attr.rs:130:1 - | -LL | #[pin_project] - | ^^^^^^^^^^^^^^ - | - = help: `#[pin_project]` can be applied to data types and unions - -error: aborting due to 40 previous errors - diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.rs b/tests/ui/pin-ergonomics/pin_v2-attr.rs new file mode 100644 index 0000000000000..af958952d0840 --- /dev/null +++ b/tests/ui/pin-ergonomics/pin_v2-attr.rs @@ -0,0 +1,144 @@ +#![feature( + pin_ergonomics, + where_clause_attrs, + trait_alias, + extern_types, + associated_type_defaults, + fn_delegation, +)] +#![allow(incomplete_features)] +#![pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on crates + +// allowed + +#[pin_v2] +struct Struct {} + +#[pin_v2] +enum Enum {} + +#[pin_v2] +union Union { + field: (), +} + +// disallowed + +enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { + //~^ ERROR `#[pin_v2]` attribute cannot be used on function params + //~| ERROR `#[pin_v2]` attribute cannot be used on function params + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on enum variants + UnitVariant, + TupleVariant(#[pin_v2] T), //~ ERROR `#[pin_v2]` attribute cannot be used on struct fields + StructVariant { + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on struct fields + field: U, + }, +} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on traits +trait Trait { + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on associated consts + const ASSOC_CONST: () = (); + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on associated types + type AssocType = (); + + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on required trait methods + fn method(); + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on provided trait methods + fn method_with_body() {} +} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on trait aliases +trait TraitAlias = Trait; + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on inherent impl blocks +impl Struct { + // FIXME: delegation macros are not tested yet (how to?) + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on delegations + reuse ::type_id; + + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on inherent methods + fn method() {} +} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on trait impl blocks +impl Trait for Enum { + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on trait methods in impl blocks + fn method() {} +} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on extern crates +extern crate alloc; + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on use statements +use std::pin::Pin; + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on statics +static STATIC: () = (); + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on constants +const CONST: () = (); + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on functions +fn f(#[pin_v2] param: Foo) +//~^ ERROR `#[pin_v2]` attribute cannot be used on function params +//~| ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters +where + #[pin_v2] + //~^ ERROR `#[pin_v2]` attribute cannot be used on where predicates + T:, +{ + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on closures + || (); + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on expressions + [(), (), ()]; + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on statements + let _: Foo<(), ()> = Foo::StructVariant { + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on struct fields + field: (), + }; + match param { + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on match arms + Foo::UnitVariant => {} + Foo::TupleVariant(..) => {} + Foo::StructVariant { + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on pattern fields + field, + } => {} + } +} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on modules +mod m {} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on foreign modules +extern "C" { + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on foreign types + type ForeignTy; + + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on foreign statics + static EXTERN_STATIC: (); + + #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on foreign functions + fn extern_fn(); +} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on type alias +type Type = (); + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on macro defs +macro_rules! macro_def { + () => {}; +} + +#[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on macro calls +macro_def!(); + +std::arch::global_asm! { + "{}", + #[pin_v2] //~ ERROR this attribute is not supported on assembly + const 0 +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.stderr b/tests/ui/pin-ergonomics/pin_v2-attr.stderr new file mode 100644 index 0000000000000..fb3e50a23fe74 --- /dev/null +++ b/tests/ui/pin-ergonomics/pin_v2-attr.stderr @@ -0,0 +1,318 @@ +error: `#[pin_v2]` attribute cannot be used on macro calls + --> $DIR/pin_v2-attr.rs:135:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: this attribute is not supported on assembly + --> $DIR/pin_v2-attr.rs:140:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + +error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + --> $DIR/pin_v2-attr.rs:84:12 + | +LL | fn f(#[pin_v2] param: Foo) + | ^^^^^^^^^ + +error: `#[pin_v2]` attribute cannot be used on crates + --> $DIR/pin_v2-attr.rs:10:1 + | +LL | #![pin_v2] + | ^^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on function params + --> $DIR/pin_v2-attr.rs:27:10 + | +LL | enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on function params + --> $DIR/pin_v2-attr.rs:27:23 + | +LL | enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on enum variants + --> $DIR/pin_v2-attr.rs:30:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on struct fields + --> $DIR/pin_v2-attr.rs:32:18 + | +LL | TupleVariant(#[pin_v2] T), + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on struct fields + --> $DIR/pin_v2-attr.rs:34:9 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on traits + --> $DIR/pin_v2-attr.rs:39:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on associated consts + --> $DIR/pin_v2-attr.rs:41:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on associated types + --> $DIR/pin_v2-attr.rs:43:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on required trait methods + --> $DIR/pin_v2-attr.rs:46:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on provided trait methods + --> $DIR/pin_v2-attr.rs:48:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on trait aliases + --> $DIR/pin_v2-attr.rs:52:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on inherent impl blocks + --> $DIR/pin_v2-attr.rs:55:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on delegations + --> $DIR/pin_v2-attr.rs:58:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on inherent methods + --> $DIR/pin_v2-attr.rs:61:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on trait impl blocks + --> $DIR/pin_v2-attr.rs:65:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on trait methods in impl blocks + --> $DIR/pin_v2-attr.rs:67:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on extern crates + --> $DIR/pin_v2-attr.rs:71:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on use statements + --> $DIR/pin_v2-attr.rs:74:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on statics + --> $DIR/pin_v2-attr.rs:77:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on constants + --> $DIR/pin_v2-attr.rs:80:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on functions + --> $DIR/pin_v2-attr.rs:83:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on function params + --> $DIR/pin_v2-attr.rs:84:12 + | +LL | fn f(#[pin_v2] param: Foo) + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on closures + --> $DIR/pin_v2-attr.rs:92:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on expressions + --> $DIR/pin_v2-attr.rs:94:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on struct fields + --> $DIR/pin_v2-attr.rs:98:9 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on statements + --> $DIR/pin_v2-attr.rs:96:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on match arms + --> $DIR/pin_v2-attr.rs:102:9 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on pattern fields + --> $DIR/pin_v2-attr.rs:106:13 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on where predicates + --> $DIR/pin_v2-attr.rs:88:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on modules + --> $DIR/pin_v2-attr.rs:112:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on foreign modules + --> $DIR/pin_v2-attr.rs:115:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on foreign types + --> $DIR/pin_v2-attr.rs:117:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on foreign statics + --> $DIR/pin_v2-attr.rs:120:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on foreign functions + --> $DIR/pin_v2-attr.rs:123:5 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on type aliases + --> $DIR/pin_v2-attr.rs:127:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: `#[pin_v2]` attribute cannot be used on macro defs + --> $DIR/pin_v2-attr.rs:130:1 + | +LL | #[pin_v2] + | ^^^^^^^^^ + | + = help: `#[pin_v2]` can be applied to data types and unions + +error: aborting due to 40 previous errors + From 731981178d8a9b4a30aae70fb2bd91e0e016bb33 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 30 Oct 2025 16:01:58 +0100 Subject: [PATCH 18/45] [rustdoc search] Include extern crates when filtering on `import` --- src/librustdoc/html/static/js/search.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 0a73d32dac2de..e281139ca38ff 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -3906,6 +3906,8 @@ class DocSearch { return name === "traitalias"; case "macro": return name === "attr" || name === "derive"; + case "import": + return name === "externcrate"; } // No match From d5839f968c4bccac336a3f7de2bcc8c4541af6a1 Mon Sep 17 00:00:00 2001 From: apiraino Date: Tue, 21 Oct 2025 17:09:46 +0200 Subject: [PATCH 19/45] Enable regression labeling aliases --- triagebot.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 7a4e0bb5f43ba..5a96d96b346d4 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -38,6 +38,14 @@ allow-unauthenticated = [ "has-merge-commits", ] +[relabel.to-stable] +add-labels = ["regression-from-stable-to-stable"] +rem-labels = ["regression-from-stable-to-beta", "regression-from-stable-to-nightly"] + +[relabel.to-beta] +add-labels = ["regression-from-stable-to-beta"] +rem-labels = ["regression-from-stable-to-stable", "regression-from-stable-to-nightly"] + [review-submitted] # This label is added when a "request changes" review is submitted. reviewed_label = "S-waiting-on-author" From e614ed4456c944dc1afd0a0b26a216aa0f76093f Mon Sep 17 00:00:00 2001 From: Frank King Date: Fri, 31 Oct 2025 08:31:55 +0800 Subject: [PATCH 20/45] Restrict `#[pin_v2]` test on `global_asm!` to stablized archs only --- tests/ui/pin-ergonomics/pin_v2-attr.rs | 14 ++++++++++++++ tests/ui/pin-ergonomics/pin_v2-attr.stderr | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.rs b/tests/ui/pin-ergonomics/pin_v2-attr.rs index af958952d0840..eccb9b6a87bfa 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.rs +++ b/tests/ui/pin-ergonomics/pin_v2-attr.rs @@ -135,6 +135,20 @@ macro_rules! macro_def { #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on macro calls macro_def!(); +// Restricted on architectures where inline assembly is stable +// accroding to `compiler/rustc_ast_lowering/src/asm.rs` +#[cfg(any( + target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "arm64ec", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64", + target_arch = "s390x", +))] std::arch::global_asm! { "{}", #[pin_v2] //~ ERROR this attribute is not supported on assembly diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.stderr b/tests/ui/pin-ergonomics/pin_v2-attr.stderr index fb3e50a23fe74..607dccd4019b7 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.stderr +++ b/tests/ui/pin-ergonomics/pin_v2-attr.stderr @@ -7,7 +7,7 @@ LL | #[pin_v2] = help: `#[pin_v2]` can be applied to data types and unions error: this attribute is not supported on assembly - --> $DIR/pin_v2-attr.rs:140:5 + --> $DIR/pin_v2-attr.rs:154:5 | LL | #[pin_v2] | ^^^^^^^^^ From d8ace32252c8ca49d9e41be46e5758fbcf666770 Mon Sep 17 00:00:00 2001 From: Frank King Date: Fri, 31 Oct 2025 08:48:01 +0800 Subject: [PATCH 21/45] Remove the `#[pin_v2]` test since it produces different errors on different archs --- tests/ui/pin-ergonomics/pin_v2-attr.rs | 20 -------------------- tests/ui/pin-ergonomics/pin_v2-attr.stderr | 8 +------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.rs b/tests/ui/pin-ergonomics/pin_v2-attr.rs index eccb9b6a87bfa..cfafe4b0b8999 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.rs +++ b/tests/ui/pin-ergonomics/pin_v2-attr.rs @@ -135,24 +135,4 @@ macro_rules! macro_def { #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on macro calls macro_def!(); -// Restricted on architectures where inline assembly is stable -// accroding to `compiler/rustc_ast_lowering/src/asm.rs` -#[cfg(any( - target_arch = "x86", - target_arch = "x86_64", - target_arch = "arm", - target_arch = "aarch64", - target_arch = "arm64ec", - target_arch = "riscv32", - target_arch = "riscv64", - target_arch = "loongarch32", - target_arch = "loongarch64", - target_arch = "s390x", -))] -std::arch::global_asm! { - "{}", - #[pin_v2] //~ ERROR this attribute is not supported on assembly - const 0 -} - fn main() {} diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.stderr b/tests/ui/pin-ergonomics/pin_v2-attr.stderr index 607dccd4019b7..81e086f5a7ef8 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.stderr +++ b/tests/ui/pin-ergonomics/pin_v2-attr.stderr @@ -6,12 +6,6 @@ LL | #[pin_v2] | = help: `#[pin_v2]` can be applied to data types and unions -error: this attribute is not supported on assembly - --> $DIR/pin_v2-attr.rs:154:5 - | -LL | #[pin_v2] - | ^^^^^^^^^ - error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters --> $DIR/pin_v2-attr.rs:84:12 | @@ -314,5 +308,5 @@ LL | #[pin_v2] | = help: `#[pin_v2]` can be applied to data types and unions -error: aborting due to 40 previous errors +error: aborting due to 39 previous errors From c5b30c3b978f7de2ae386d7e8b4d0c7d9b2404ad Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Fri, 31 Oct 2025 14:42:03 +0900 Subject: [PATCH 22/45] docs: Fix argument names for `carrying_mul_add` --- library/core/src/num/int_macros.rs | 2 +- library/core/src/num/uint_macros.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index c3460a6409069..509d7e335fb23 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2705,7 +2705,7 @@ macro_rules! int_impl { Self::carrying_mul_add(self, rhs, carry, 0) } - /// Calculates the "full multiplication" `self * rhs + carry1 + carry2` + /// Calculates the "full multiplication" `self * rhs + carry + add` /// without the possibility to overflow. /// /// This returns the low-order (wrapping) bits and the high-order (overflow) bits diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index b5b768cf677aa..793d84d5139cc 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3000,7 +3000,7 @@ macro_rules! uint_impl { Self::carrying_mul_add(self, rhs, carry, 0) } - /// Calculates the "full multiplication" `self * rhs + carry1 + carry2`. + /// Calculates the "full multiplication" `self * rhs + carry + add`. /// /// This returns the low-order (wrapping) bits and the high-order (overflow) bits /// of the result as two separate values, in that order. From 761ae9a7ebf5062617303c07fc2be5830ff7cbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Volf?= Date: Thu, 5 Jun 2025 11:29:35 +0200 Subject: [PATCH 23/45] add tier 3 HelenOS compiler targets Targets theoretically possible, but not provided yet: - 32-bit arm See also notes in the PR, I was unable to run anything non-trivial on ARM HelenOS, there are issues with the linker/loader, incomplete support of atomics, and overall a lot of confusion about the precise version of ARM architecture that the HelenOS builds target. - riscv, mips (These targets currently don't run HelenOS at all. HelenOS says it should work, but the builds are broken for quite some time now.) --- .../rustc_target/src/spec/base/helenos.rs | 17 +++++ compiler/rustc_target/src/spec/base/mod.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 6 ++ .../spec/targets/aarch64_unknown_helenos.rs | 22 ++++++ .../src/spec/targets/i686_unknown_helenos.rs | 26 +++++++ .../spec/targets/powerpc_unknown_helenos.rs | 24 +++++++ .../spec/targets/sparc64_unknown_helenos.rs | 26 +++++++ .../spec/targets/x86_64_unknown_helenos.rs | 25 +++++++ src/bootstrap/src/core/sanity.rs | 5 ++ src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 5 ++ src/doc/rustc/src/platform-support/helenos.md | 68 +++++++++++++++++++ tests/assembly-llvm/targets/targets-elf.rs | 15 ++++ tests/ui/check-cfg/cfg-crate-features.stderr | 2 +- tests/ui/check-cfg/well-known-values.stderr | 4 +- 15 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 compiler/rustc_target/src/spec/base/helenos.rs create mode 100644 compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs create mode 100644 compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs create mode 100644 compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs create mode 100644 compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs create mode 100644 src/doc/rustc/src/platform-support/helenos.md diff --git a/compiler/rustc_target/src/spec/base/helenos.rs b/compiler/rustc_target/src/spec/base/helenos.rs new file mode 100644 index 0000000000000..8d6f406e41f73 --- /dev/null +++ b/compiler/rustc_target/src/spec/base/helenos.rs @@ -0,0 +1,17 @@ +use crate::spec::{PanicStrategy, RelroLevel, StackProbeType, TargetOptions}; + +pub(crate) fn opts() -> TargetOptions { + TargetOptions { + os: "helenos".into(), + + dynamic_linking: true, + // we need the linker to keep libgcc and friends + no_default_libraries: false, + has_rpath: true, + relro_level: RelroLevel::Full, + panic_strategy: PanicStrategy::Abort, + stack_probes: StackProbeType::Inline, + + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index 6ab8597a4ecb0..ca1c9649ee4d7 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -8,6 +8,7 @@ pub(crate) mod dragonfly; pub(crate) mod freebsd; pub(crate) mod fuchsia; pub(crate) mod haiku; +pub(crate) mod helenos; pub(crate) mod hermit; pub(crate) mod hurd; pub(crate) mod hurd_gnu; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 39a260f9a9b44..b49e7fc9cff66 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1534,6 +1534,12 @@ supported_targets! { ("i686-unknown-haiku", i686_unknown_haiku), ("x86_64-unknown-haiku", x86_64_unknown_haiku), + ("aarch64-unknown-helenos", aarch64_unknown_helenos), + ("i686-unknown-helenos", i686_unknown_helenos), + ("powerpc-unknown-helenos", powerpc_unknown_helenos), + ("sparc64-unknown-helenos", sparc64_unknown_helenos), + ("x86_64-unknown-helenos", x86_64_unknown_helenos), + ("i686-unknown-hurd-gnu", i686_unknown_hurd_gnu), ("x86_64-unknown-hurd-gnu", x86_64_unknown_hurd_gnu), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs new file mode 100644 index 0000000000000..31b4a2111cbf6 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_helenos.rs @@ -0,0 +1,22 @@ +use crate::spec::{Target, base}; + +pub(crate) fn target() -> Target { + let mut base = base::helenos::opts(); + base.max_atomic_width = Some(128); + base.features = "+v8a".into(); + base.linker = Some("aarch64-helenos-gcc".into()); + + Target { + llvm_target: "aarch64-unknown-helenos".into(), + metadata: crate::spec::TargetMetadata { + description: Some("ARM64 HelenOS".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }, + pointer_width: 64, + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + arch: "aarch64".into(), + options: base, + } +} diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs new file mode 100644 index 0000000000000..1cd32d6f78d93 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_helenos.rs @@ -0,0 +1,26 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, RustcAbi, Target, base}; + +pub(crate) fn target() -> Target { + let mut base = base::helenos::opts(); + base.cpu = "pentium4".into(); + base.max_atomic_width = Some(64); + base.linker = Some("i686-helenos-gcc".into()); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.rustc_abi = Some(RustcAbi::X86Sse2); + + Target { + llvm_target: "i686-unknown-helenos".into(), + metadata: crate::spec::TargetMetadata { + description: Some("IA-32 (i686) HelenOS".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + i128:128-f64:32:64-f80:32-n8:16:32-S128" + .into(), + arch: "x86".into(), + options: base, + } +} diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs new file mode 100644 index 0000000000000..2b713e8a5ff2f --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_helenos.rs @@ -0,0 +1,24 @@ +use rustc_abi::Endian; + +use crate::spec::{Target, TargetMetadata, base}; + +pub(crate) fn target() -> Target { + let mut base = base::helenos::opts(); + base.endian = Endian::Big; + base.max_atomic_width = Some(32); + base.linker = Some("ppc-helenos-gcc".into()); + + Target { + llvm_target: "powerpc-unknown-helenos".into(), + metadata: TargetMetadata { + description: Some("PowerPC HelenOS".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }, + pointer_width: 32, + data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(), + arch: "powerpc".into(), + options: base, + } +} diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs new file mode 100644 index 0000000000000..8c3def57d0cf4 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_helenos.rs @@ -0,0 +1,26 @@ +use rustc_abi::Endian; + +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetMetadata, base}; + +pub(crate) fn target() -> Target { + let mut base = base::helenos::opts(); + base.endian = Endian::Big; + base.cpu = "v9".into(); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.max_atomic_width = Some(64); + base.linker = Some("sparc64-helenos-gcc".into()); + + Target { + llvm_target: "sparc64-unknown-helenos".into(), + metadata: TargetMetadata { + description: Some("SPARC HelenOS".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }, + pointer_width: 64, + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), + arch: "sparc64".into(), + options: base, + } +} diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs new file mode 100644 index 0000000000000..82c9807f73e3e --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_helenos.rs @@ -0,0 +1,25 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, Target, base}; + +pub(crate) fn target() -> Target { + let mut base = base::helenos::opts(); + base.cpu = "x86-64".into(); + base.plt_by_default = false; + base.max_atomic_width = Some(64); + base.linker = Some("amd64-helenos-gcc".into()); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + + Target { + llvm_target: "x86_64-unknown-helenos".into(), + metadata: crate::spec::TargetMetadata { + description: Some("64-bit HelenOS".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }, + pointer_width: 64, + data_layout: + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + options: base, + } +} diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 08e5abc0a03b1..ed63b2aae452c 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -33,6 +33,11 @@ pub struct Finder { // // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ + "aarch64-unknown-helenos", + "i686-unknown-helenos", + "x86_64-unknown-helenos", + "powerpc-unknown-helenos", + "sparc64-unknown-helenos", // just a dummy comment so the list doesn't get onelined "riscv64gc-unknown-redox", ]; diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 6622ef2cf82f0..e4623a2a87f48 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -120,6 +120,7 @@ - [solaris](platform-support/solaris.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [\*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md) + - [\*-unknown-helenos](platform-support/helenos.md) - [\*-unknown-hermit](platform-support/hermit.md) - [\*-unknown-freebsd](platform-support/freebsd.md) - [\*-unknown-managarm-mlibc](platform-support/managarm.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 99739ee734e4c..0d91095fbbb92 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -255,6 +255,7 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD +[`aarch64-unknown-helenos`](platform-support/helenos.md) | ✓ | | ARM64 HelenOS [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit [`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) @@ -320,6 +321,7 @@ target | std | host | notes [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI] [`i686-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI] +[`i686-unknown-helenos`](platform-support/helenos.md) | ✓ | | HelenOS IA-32 (see docs for pending issues) [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI] @@ -356,6 +358,7 @@ target | std | host | notes [`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers [`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD +[`powerpc-unknown-helenos`](platform-support/helenos.md) | ✓ | | PowerPC HelenOS [`powerpc-unknown-linux-gnuspe`](platform-support/powerpc-unknown-linux-gnuspe.md) | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3 [`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux with musl 1.2.3 @@ -399,6 +402,7 @@ target | std | host | notes [`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.3) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ +[`sparc64-unknown-helenos`](platform-support/helenos.md) | ✓ | | sparc64 HelenOS [`sparc64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/sparc64 [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64 [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T @@ -429,6 +433,7 @@ target | std | host | notes `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku [`x86_64-unknown-hermit`](platform-support/hermit.md) | ✓ | | x86_64 Hermit +[`x86_64-unknown-helenos`](platform-support/helenos.md) | ✓ | | x86_64 (amd64) HelenOS [`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd `x86_64-unknown-l4re-uclibc` | ? | | [`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc diff --git a/src/doc/rustc/src/platform-support/helenos.md b/src/doc/rustc/src/platform-support/helenos.md new file mode 100644 index 0000000000000..0dce4f6928ffb --- /dev/null +++ b/src/doc/rustc/src/platform-support/helenos.md @@ -0,0 +1,68 @@ +# `*-unknown-helenos` + +**Tier: 3** + +Targets for [HelenOS](https://www.helenos.org). +These targets allow compiling user-space applications, that you can then copy into your HelenOS ISO image to run them. + +Target triplets available: + +- `x86_64-unknown-helenos` +- `sparc64-unknown-helenos` +- `powerpc-unknown-helenos` +- `aarch64-unknown-helenos` +- `i686-unknown-helenos`* + + +On i686, some portions of native HelenOS libraries run into issues due to vector instructions accessing variables from the stack that seems +to be misaligned. It is not clear if this is fault of HelenOS or Rust. Most programs work, but for example calling `ui_window_create` from HelenOS +libui does not work. + +## Target maintainers + +- Matěj Volf ([@mvolfik](https://github.com/mvolfik)) + +## Requirements + +These targets only support cross-compilation. The targets will[^helenos-libstd-pending] support libstd, although support of some platform features (filesystem, networking) may be limited. + +You need to have a local clone of the HelenOS repository and the HelenOS toolchain set up, no HelenOS-Rust development artifacts are available. + +[^helenos-libstd-pending]: libstd is not yet available, because it needs to be done in a separate PR, because compiler support needs to be merged first to allow creating libc bindings + +## Building + +If you want to avoid the full setup, fully automated Docker-based build system is available at https://github.com/mvolfik/helenos-rust-autobuild + +### HelenOS toolchain setup + +For compilation of standard library, you need to build the HelenOS toolchain (because Rust needs to use `*-helenos-gcc` as linker) and its libraries (libc and a few others). See [this HelenOS wiki page](https://www.helenos.org/wiki/UsersGuide/CompilingFromSource#a2.Buildasupportedcross-compiler) for instruction on setting up the build. At the end of step 4 (_Configure and build_), after `ninja image_path`, invoke `ninja export-dev` to build the shared libraries. + +Copy the libraries to the path where the compiler automatically searches for them. This will be the directory where you installed the toolchain (for example `~/.local/share/HelenOS/cross/i686-helenos/lib`). In the folder where you built HelenOS, you can run these commands: + +```sh +touch /tmp/test.c +HELENOS_LIB_PATH="$(realpath "$(amd64-helenos-gcc -v -c /tmp/test.c 2>&1 | grep LIBRARY_PATH | cut -d= -f2 | cut -d: -f2)")" +# use sparc64-helenos-gcc above for the SPARC toolchain, etc +cp -P export-dev/lib/* "$HELENOS_LIB_PATH" +``` + +### Building the target + +When you have the HelenOS toolchain set up and installed in your path, you can build the Rust toolchain using the standard procedure. See [rustc dev guide](https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html). + +In the most simple case, this means that you can run `./x build library --stage 1 --target x86_64-unknown-linux-gnu,-unknown-helenos` (the first target triple should be your host machine, adjust accordingly). Then run `rustup toolchain link mytoolchain build/host/stage1` to allow using your toolchain for building Rust programs. + +### Building Rust programs + +If you linked the toolchain above as `mytoolchain`, run `cargo +mytoolchain build --target -unknown-helenos`. + +## Testing + +After you build a Rust program for HelenOS, you can put it into the `dist` directory of the HelenOS build, build the ISO image, and then run it either in an emulator, or on real hardware. See HelenOS wiki for further instructions on running the OS. + +Running the Rust testsuite has not been attempted yet due to missing host tools (thus the test suite can't be run natively) and insufficient networking support (thus we can't use the `remote-test-server` tool). + +## Cross-compilation toolchains and C code + +You should be able to cross-compile and link any needed C code using `-helenos-gcc` that you built above. However, note that clang support is highly lacking. Therefore, to run tools such as `bindgen`, you will need to provide flag `-nostdinc` and manually specify the include paths to HelenOS headers, which you will find in the `export-dev` folder + in the cross-compilation toolchain (e.g. `~/.local/share/HelenOS/cross/lib/gcc/i686-helenos/14.2.0/include`). You can see an example of proper build.rs at https://github.com/mvolfik/helenos-ui-rs/blob/master/build.rs diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index 6c85dbcfed1a5..d2f22fd8d1a50 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -34,6 +34,9 @@ //@ revisions: aarch64_unknown_fuchsia //@ [aarch64_unknown_fuchsia] compile-flags: --target aarch64-unknown-fuchsia //@ [aarch64_unknown_fuchsia] needs-llvm-components: aarch64 +//@ revisions: aarch64_unknown_helenos +//@ [aarch64_unknown_helenos] compile-flags: --target aarch64-unknown-helenos +//@ [aarch64_unknown_helenos] needs-llvm-components: aarch64 //@ revisions: aarch64_unknown_hermit //@ [aarch64_unknown_hermit] compile-flags: --target aarch64-unknown-hermit //@ [aarch64_unknown_hermit] needs-llvm-components: aarch64 @@ -256,6 +259,9 @@ //@ revisions: i686_unknown_haiku //@ [i686_unknown_haiku] compile-flags: --target i686-unknown-haiku //@ [i686_unknown_haiku] needs-llvm-components: x86 +//@ revisions: i686_unknown_helenos +//@ [i686_unknown_helenos] compile-flags: --target i686-unknown-helenos +//@ [i686_unknown_helenos] needs-llvm-components: x86 //@ revisions: i686_unknown_hurd_gnu //@ [i686_unknown_hurd_gnu] compile-flags: --target i686-unknown-hurd-gnu //@ [i686_unknown_hurd_gnu] needs-llvm-components: x86 @@ -394,6 +400,9 @@ //@ revisions: powerpc_unknown_freebsd //@ [powerpc_unknown_freebsd] compile-flags: --target powerpc-unknown-freebsd //@ [powerpc_unknown_freebsd] needs-llvm-components: powerpc +//@ revisions: powerpc_unknown_helenos +//@ [powerpc_unknown_helenos] compile-flags: --target powerpc-unknown-helenos +//@ [powerpc_unknown_helenos] needs-llvm-components: powerpc //@ revisions: powerpc_unknown_linux_gnu //@ [powerpc_unknown_linux_gnu] compile-flags: --target powerpc-unknown-linux-gnu //@ [powerpc_unknown_linux_gnu] needs-llvm-components: powerpc @@ -517,6 +526,9 @@ //@ revisions: s390x_unknown_linux_musl //@ [s390x_unknown_linux_musl] compile-flags: --target s390x-unknown-linux-musl //@ [s390x_unknown_linux_musl] needs-llvm-components: systemz +//@ revisions: sparc64_unknown_helenos +//@ [sparc64_unknown_helenos] compile-flags: --target sparc64-unknown-helenos +//@ [sparc64_unknown_helenos] needs-llvm-components: sparc //@ revisions: sparc64_unknown_linux_gnu //@ [sparc64_unknown_linux_gnu] compile-flags: --target sparc64-unknown-linux-gnu //@ [sparc64_unknown_linux_gnu] needs-llvm-components: sparc @@ -634,6 +646,9 @@ //@ revisions: x86_64_unknown_haiku //@ [x86_64_unknown_haiku] compile-flags: --target x86_64-unknown-haiku //@ [x86_64_unknown_haiku] needs-llvm-components: x86 +//@ revisions: x86_64_unknown_helenos +//@ [x86_64_unknown_helenos] compile-flags: --target x86_64-unknown-helenos +//@ [x86_64_unknown_helenos] needs-llvm-components: x86 //@ revisions: x86_64_unknown_hurd_gnu //@ [x86_64_unknown_hurd_gnu] compile-flags: --target x86_64-unknown-hurd-gnu //@ [x86_64_unknown_hurd_gnu] needs-llvm-components: x86 diff --git a/tests/ui/check-cfg/cfg-crate-features.stderr b/tests/ui/check-cfg/cfg-crate-features.stderr index 39fee52a909b6..38301f470bf73 100644 --- a/tests/ui/check-cfg/cfg-crate-features.stderr +++ b/tests/ui/check-cfg/cfg-crate-features.stderr @@ -24,7 +24,7 @@ warning: unexpected `cfg` condition value: `does_not_exist` LL | #![cfg(not(target(os = "does_not_exist")))] | ^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, and `trusty` and 12 more + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, and `teeos` and 13 more = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 3f14c7b08eac6..8205756d64dd1 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 28 warnings emitted From 3d9c69b594ef411e9dc623bc56aab30d0c8d5111 Mon Sep 17 00:00:00 2001 From: Emily Albini Date: Fri, 31 Oct 2025 10:07:23 +0100 Subject: [PATCH 24/45] enable flock for illumos --- library/std/src/fs/tests.rs | 6 ++++++ library/std/src/sys/fs/unix.rs | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 4d67ba9248998..0517760c35501 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -5,6 +5,7 @@ use rand::RngCore; target_os = "freebsd", target_os = "linux", target_os = "netbsd", + target_os = "illumos", target_vendor = "apple", ))] use crate::assert_matches::assert_matches; @@ -14,6 +15,7 @@ use crate::char::MAX_LEN_UTF8; target_os = "freebsd", target_os = "linux", target_os = "netbsd", + target_os = "illumos", target_vendor = "apple", ))] use crate::fs::TryLockError; @@ -227,6 +229,7 @@ fn file_test_io_seek_and_write() { target_os = "linux", target_os = "netbsd", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", ))] fn file_lock_multiple_shared() { @@ -251,6 +254,7 @@ fn file_lock_multiple_shared() { target_os = "linux", target_os = "netbsd", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", ))] fn file_lock_blocking() { @@ -276,6 +280,7 @@ fn file_lock_blocking() { target_os = "linux", target_os = "netbsd", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", ))] fn file_lock_drop() { @@ -298,6 +303,7 @@ fn file_lock_drop() { target_os = "linux", target_os = "netbsd", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", ))] fn file_lock_dup() { diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index d9a7fcb0e2d39..3efe67390d7dd 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1292,6 +1292,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "cygwin", + target_os = "illumos", target_vendor = "apple", ))] pub fn lock(&self) -> io::Result<()> { @@ -1316,6 +1317,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", )))] pub fn lock(&self) -> io::Result<()> { @@ -1329,6 +1331,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "cygwin", + target_os = "illumos", target_vendor = "apple", ))] pub fn lock_shared(&self) -> io::Result<()> { @@ -1353,6 +1356,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", )))] pub fn lock_shared(&self) -> io::Result<()> { @@ -1366,6 +1370,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "cygwin", + target_os = "illumos", target_vendor = "apple", ))] pub fn try_lock(&self) -> Result<(), TryLockError> { @@ -1406,6 +1411,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", )))] pub fn try_lock(&self) -> Result<(), TryLockError> { @@ -1422,6 +1428,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "cygwin", + target_os = "illumos", target_vendor = "apple", ))] pub fn try_lock_shared(&self) -> Result<(), TryLockError> { @@ -1462,6 +1469,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", )))] pub fn try_lock_shared(&self) -> Result<(), TryLockError> { @@ -1478,6 +1486,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "cygwin", + target_os = "illumos", target_vendor = "apple", ))] pub fn unlock(&self) -> io::Result<()> { @@ -1502,6 +1511,7 @@ impl File { target_os = "openbsd", target_os = "cygwin", target_os = "solaris", + target_os = "illumos", target_vendor = "apple", )))] pub fn unlock(&self) -> io::Result<()> { From 06a2e721096becc8dedf412a9b39713f0d158eaa Mon Sep 17 00:00:00 2001 From: tison Date: Thu, 16 Oct 2025 23:05:12 +0800 Subject: [PATCH 25/45] Implement VecDeque::extract_if Signed-off-by: tison --- .../src/collections/vec_deque/extract_if.rs | 149 ++++++++++ .../alloc/src/collections/vec_deque/mod.rs | 94 ++++++ .../alloc/src/collections/vec_deque/tests.rs | 272 +++++++++++++++++- 3 files changed, 514 insertions(+), 1 deletion(-) create mode 100644 library/alloc/src/collections/vec_deque/extract_if.rs diff --git a/library/alloc/src/collections/vec_deque/extract_if.rs b/library/alloc/src/collections/vec_deque/extract_if.rs new file mode 100644 index 0000000000000..bed7d46482cf4 --- /dev/null +++ b/library/alloc/src/collections/vec_deque/extract_if.rs @@ -0,0 +1,149 @@ +use core::ops::{Range, RangeBounds}; +use core::{fmt, ptr, slice}; + +use super::VecDeque; +use crate::alloc::{Allocator, Global}; + +/// An iterator which uses a closure to determine if an element should be removed. +/// +/// This struct is created by [`VecDeque::extract_if`]. +/// See its documentation for more. +/// +/// # Example +/// +/// ``` +/// #![feature(vec_deque_extract_if)] +/// +/// use std::collections::vec_deque::ExtractIf; +/// use std::collections::vec_deque::VecDeque; +/// +/// let mut v = VecDeque::from([0, 1, 2]); +/// let iter: ExtractIf<'_, _, _> = v.extract_if(.., |x| *x % 2 == 0); +/// ``` +#[unstable(feature = "vec_deque_extract_if", issue = "147750")] +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf< + 'a, + T, + F, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + vec: &'a mut VecDeque, + /// The index of the item that will be inspected by the next call to `next`. + idx: usize, + /// Elements at and beyond this point will be retained. Must be equal or smaller than `old_len`. + end: usize, + /// The number of items that have been drained (removed) thus far. + del: usize, + /// The original length of `vec` prior to draining. + old_len: usize, + /// The filter test predicate. + pred: F, +} + +impl<'a, T, F, A: Allocator> ExtractIf<'a, T, F, A> { + pub(super) fn new>( + vec: &'a mut VecDeque, + pred: F, + range: R, + ) -> Self { + let old_len = vec.len(); + let Range { start, end } = slice::range(range, ..old_len); + + // Guard against the deque getting leaked (leak amplification) + vec.len = 0; + ExtractIf { vec, idx: start, del: 0, end, old_len, pred } + } + + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn allocator(&self) -> &A { + self.vec.allocator() + } +} + +#[unstable(feature = "vec_deque_extract_if", issue = "147750")] +impl Iterator for ExtractIf<'_, T, F, A> +where + F: FnMut(&mut T) -> bool, +{ + type Item = T; + + fn next(&mut self) -> Option { + while self.idx < self.end { + let i = self.idx; + // SAFETY: + // We know that `i < self.end` from the if guard and that `self.end <= self.old_len` from + // the validity of `Self`. Therefore `i` points to an element within `vec`. + // + // Additionally, the i-th element is valid because each element is visited at most once + // and it is the first time we access vec[i]. + // + // Note: we can't use `vec.get_mut(i).unwrap()` here since the precondition for that + // function is that i < vec.len, but we've set vec's length to zero. + let idx = self.vec.to_physical_idx(i); + let cur = unsafe { &mut *self.vec.ptr().add(idx) }; + let drained = (self.pred)(cur); + // Update the index *after* the predicate is called. If the index + // is updated prior and the predicate panics, the element at this + // index would be leaked. + self.idx += 1; + if drained { + self.del += 1; + // SAFETY: We never touch this element again after returning it. + return Some(unsafe { ptr::read(cur) }); + } else if self.del > 0 { + let hole_slot = self.vec.to_physical_idx(i - self.del); + // SAFETY: `self.del` > 0, so the hole slot must not overlap with current element. + // We use copy for move, and never touch this element again. + unsafe { self.vec.wrap_copy(idx, hole_slot, 1) }; + } + } + None + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.end - self.idx)) + } +} + +#[unstable(feature = "vec_deque_extract_if", issue = "147750")] +impl Drop for ExtractIf<'_, T, F, A> { + fn drop(&mut self) { + if self.del > 0 { + let src = self.vec.to_physical_idx(self.idx); + let dst = self.vec.to_physical_idx(self.idx - self.del); + let len = self.old_len - self.idx; + // SAFETY: Trailing unchecked items must be valid since we never touch them. + unsafe { self.vec.wrap_copy(src, dst, len) }; + } + self.vec.len = self.old_len - self.del; + } +} + +#[unstable(feature = "vec_deque_extract_if", issue = "147750")] +impl fmt::Debug for ExtractIf<'_, T, F, A> +where + T: fmt::Debug, + A: Allocator, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let peek = if self.idx < self.end { + let idx = self.vec.to_physical_idx(self.idx); + // This has to use pointer arithmetic as `self.vec[self.idx]` or + // `self.vec.get_unchecked(self.idx)` wouldn't work since we + // temporarily set the length of `self.vec` to zero. + // + // SAFETY: + // Since `self.idx` is smaller than `self.end` and `self.end` is + // smaller than `self.old_len`, `idx` is valid for indexing the + // buffer. Also, per the invariant of `self.idx`, this element + // has not been inspected/moved out yet. + Some(unsafe { &*self.vec.ptr().add(idx) }) + } else { + None + }; + f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive() + } +} diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index ac619a42d356d..3bdb7415f0c2a 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -32,6 +32,11 @@ pub use self::drain::Drain; mod drain; +#[unstable(feature = "vec_deque_extract_if", issue = "147750")] +pub use self::extract_if::ExtractIf; + +mod extract_if; + #[stable(feature = "rust1", since = "1.0.0")] pub use self::iter_mut::IterMut; @@ -542,6 +547,95 @@ impl VecDeque { } debug_assert!(self.head < self.capacity() || self.capacity() == 0); } + + /// Creates an iterator which uses a closure to determine if an element in the range should be removed. + /// + /// If the closure returns `true`, the element is removed from the deque and yielded. If the closure + /// returns `false`, or panics, the element remains in the deque and will not be yielded. + /// + /// Only elements that fall in the provided range are considered for extraction, but any elements + /// after the range will still have to be moved if any element has been extracted. + /// + /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating + /// or the iteration short-circuits, then the remaining elements will be retained. + /// Use [`retain_mut`] with a negated predicate if you do not need the returned iterator. + /// + /// [`retain_mut`]: VecDeque::retain_mut + /// + /// Using this method is equivalent to the following code: + /// + /// ``` + /// #![feature(vec_deque_extract_if)] + /// # use std::collections::VecDeque; + /// # let some_predicate = |x: &mut i32| { *x % 2 == 1 }; + /// # let mut deq: VecDeque<_> = (0..10).collect(); + /// # let mut deq2 = deq.clone(); + /// # let range = 1..5; + /// let mut i = range.start; + /// let end_items = deq.len() - range.end; + /// # let mut extracted = vec![]; + /// + /// while i < deq.len() - end_items { + /// if some_predicate(&mut deq[i]) { + /// let val = deq.remove(i).unwrap(); + /// // your code here + /// # extracted.push(val); + /// } else { + /// i += 1; + /// } + /// } + /// + /// # let extracted2: Vec<_> = deq2.extract_if(range, some_predicate).collect(); + /// # assert_eq!(deq, deq2); + /// # assert_eq!(extracted, extracted2); + /// ``` + /// + /// But `extract_if` is easier to use. `extract_if` is also more efficient, + /// because it can backshift the elements of the array in bulk. + /// + /// The iterator also lets you mutate the value of each element in the + /// closure, regardless of whether you choose to keep or remove it. + /// + /// # Panics + /// + /// If `range` is out of bounds. + /// + /// # Examples + /// + /// Splitting a deque into even and odd values, reusing the original deque: + /// + /// ``` + /// #![feature(vec_deque_extract_if)] + /// use std::collections::VecDeque; + /// + /// let mut numbers = VecDeque::from([1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]); + /// + /// let evens = numbers.extract_if(.., |x| *x % 2 == 0).collect::>(); + /// let odds = numbers; + /// + /// assert_eq!(evens, VecDeque::from([2, 4, 6, 8, 14])); + /// assert_eq!(odds, VecDeque::from([1, 3, 5, 9, 11, 13, 15])); + /// ``` + /// + /// Using the range argument to only process a part of the deque: + /// + /// ``` + /// #![feature(vec_deque_extract_if)] + /// use std::collections::VecDeque; + /// + /// let mut items = VecDeque::from([0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2]); + /// let ones = items.extract_if(7.., |x| *x == 1).collect::>(); + /// assert_eq!(items, VecDeque::from([0, 0, 0, 0, 0, 0, 0, 2, 2, 2])); + /// assert_eq!(ones.len(), 3); + /// ``` + #[unstable(feature = "vec_deque_extract_if", issue = "147750")] + pub fn extract_if(&mut self, range: R, filter: F) -> ExtractIf<'_, T, F, A> + where + F: FnMut(&mut T) -> bool, + R: RangeBounds, + { + ExtractIf::new(self, filter, range) + } } impl VecDeque { diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 2501534e95080..dc50cc34d9dac 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -1,6 +1,8 @@ -use core::iter::TrustedLen; +use std::iter::TrustedLen; +use std::panic::{AssertUnwindSafe, catch_unwind}; use super::*; +use crate::testing::crash_test::{CrashTestDummy, Panic}; use crate::testing::macros::struct_with_counted_drop; #[bench] @@ -1161,3 +1163,271 @@ fn issue_80303() { assert_eq!(vda, vdb); assert_eq!(hash_code(vda), hash_code(vdb)); } + +#[test] +fn extract_if_test() { + let mut m: VecDeque = VecDeque::from([1, 2, 3, 4, 5, 6]); + let deleted = m.extract_if(.., |v| *v < 4).collect::>(); + + assert_eq!(deleted, &[1, 2, 3]); + assert_eq!(m, &[4, 5, 6]); +} + +#[test] +fn drain_to_empty_test() { + let mut m: VecDeque = VecDeque::from([1, 2, 3, 4, 5, 6]); + let deleted = m.extract_if(.., |_| true).collect::>(); + + assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]); + assert_eq!(m, &[]); +} + +#[test] +fn extract_if_empty() { + let mut list: VecDeque = VecDeque::new(); + + { + let mut iter = list.extract_if(.., |_| true); + assert_eq!(iter.size_hint(), (0, Some(0))); + assert_eq!(iter.next(), None); + assert_eq!(iter.size_hint(), (0, Some(0))); + assert_eq!(iter.next(), None); + assert_eq!(iter.size_hint(), (0, Some(0))); + } + + assert_eq!(list.len(), 0); + assert_eq!(list, vec![]); +} + +#[test] +fn extract_if_zst() { + let mut list: VecDeque<_> = [(), (), (), (), ()].into_iter().collect(); + let initial_len = list.len(); + let mut count = 0; + + { + let mut iter = list.extract_if(.., |_| true); + assert_eq!(iter.size_hint(), (0, Some(initial_len))); + while let Some(_) = iter.next() { + count += 1; + assert_eq!(iter.size_hint(), (0, Some(initial_len - count))); + } + assert_eq!(iter.size_hint(), (0, Some(0))); + assert_eq!(iter.next(), None); + assert_eq!(iter.size_hint(), (0, Some(0))); + } + + assert_eq!(count, initial_len); + assert_eq!(list.len(), 0); + assert_eq!(list, vec![]); +} + +#[test] +fn extract_if_false() { + let mut list: VecDeque<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); + + let initial_len = list.len(); + let mut count = 0; + + { + let mut iter = list.extract_if(.., |_| false); + assert_eq!(iter.size_hint(), (0, Some(initial_len))); + for _ in iter.by_ref() { + count += 1; + } + assert_eq!(iter.size_hint(), (0, Some(0))); + assert_eq!(iter.next(), None); + assert_eq!(iter.size_hint(), (0, Some(0))); + } + + assert_eq!(count, 0); + assert_eq!(list.len(), initial_len); + assert_eq!(list, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); +} + +#[test] +fn extract_if_true() { + let mut list: VecDeque<_> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); + + let initial_len = list.len(); + let mut count = 0; + + { + let mut iter = list.extract_if(.., |_| true); + assert_eq!(iter.size_hint(), (0, Some(initial_len))); + while let Some(_) = iter.next() { + count += 1; + assert_eq!(iter.size_hint(), (0, Some(initial_len - count))); + } + assert_eq!(iter.size_hint(), (0, Some(0))); + assert_eq!(iter.next(), None); + assert_eq!(iter.size_hint(), (0, Some(0))); + } + + assert_eq!(count, initial_len); + assert_eq!(list.len(), 0); + assert_eq!(list, vec![]); +} + +#[test] +fn extract_if_non_contiguous() { + let mut list = + [1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39] + .into_iter() + .collect::>(); + list.rotate_left(3); + + assert!(!list.is_contiguous()); + assert_eq!( + list, + [6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39, 1, 2, 4] + ); + + let removed = list.extract_if(.., |x| *x % 2 == 0).collect::>(); + assert_eq!(removed.len(), 10); + assert_eq!(removed, vec![6, 18, 20, 22, 24, 26, 34, 36, 2, 4]); + + assert_eq!(list.len(), 14); + assert_eq!(list, vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39, 1]); +} + +#[test] +fn extract_if_complex() { + { + // [+xxx++++++xxxxx++++x+x++] + let mut list = [ + 1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, + 39, + ] + .into_iter() + .collect::>(); + + let removed = list.extract_if(.., |x| *x % 2 == 0).collect::>(); + assert_eq!(removed.len(), 10); + assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); + + assert_eq!(list.len(), 14); + assert_eq!(list, vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]); + } + + { + // [xxx++++++xxxxx++++x+x++] + let mut list = + [2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39] + .into_iter() + .collect::>(); + + let removed = list.extract_if(.., |x| *x % 2 == 0).collect::>(); + assert_eq!(removed.len(), 10); + assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); + + assert_eq!(list.len(), 13); + assert_eq!(list, vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]); + } + + { + // [xxx++++++xxxxx++++x+x] + let mut list = + [2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36] + .into_iter() + .collect::>(); + + let removed = list.extract_if(.., |x| *x % 2 == 0).collect::>(); + assert_eq!(removed.len(), 10); + assert_eq!(removed, vec![2, 4, 6, 18, 20, 22, 24, 26, 34, 36]); + + assert_eq!(list.len(), 11); + assert_eq!(list, vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]); + } + + { + // [xxxxxxxxxx+++++++++++] + let mut list = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19] + .into_iter() + .collect::>(); + + let removed = list.extract_if(.., |x| *x % 2 == 0).collect::>(); + assert_eq!(removed.len(), 10); + assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); + + assert_eq!(list.len(), 10); + assert_eq!(list, vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]); + } + + { + // [+++++++++++xxxxxxxxxx] + let mut list = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20] + .into_iter() + .collect::>(); + + let removed = list.extract_if(.., |x| *x % 2 == 0).collect::>(); + assert_eq!(removed.len(), 10); + assert_eq!(removed, vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20]); + + assert_eq!(list.len(), 10); + assert_eq!(list, vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]); + } +} + +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn extract_if_drop_panic_leak() { + let d0 = CrashTestDummy::new(0); + let d1 = CrashTestDummy::new(1); + let d2 = CrashTestDummy::new(2); + let d3 = CrashTestDummy::new(3); + let d4 = CrashTestDummy::new(4); + let d5 = CrashTestDummy::new(5); + let d6 = CrashTestDummy::new(6); + let d7 = CrashTestDummy::new(7); + let mut q = VecDeque::new(); + q.push_back(d3.spawn(Panic::Never)); + q.push_back(d4.spawn(Panic::Never)); + q.push_back(d5.spawn(Panic::Never)); + q.push_back(d6.spawn(Panic::Never)); + q.push_back(d7.spawn(Panic::Never)); + q.push_front(d2.spawn(Panic::Never)); + q.push_front(d1.spawn(Panic::InDrop)); + q.push_front(d0.spawn(Panic::Never)); + + catch_unwind(AssertUnwindSafe(|| q.extract_if(.., |_| true).for_each(drop))).unwrap_err(); + + assert_eq!(d0.dropped(), 1); + assert_eq!(d1.dropped(), 1); + assert_eq!(d2.dropped(), 0); + assert_eq!(d3.dropped(), 0); + assert_eq!(d4.dropped(), 0); + assert_eq!(d5.dropped(), 0); + assert_eq!(d6.dropped(), 0); + assert_eq!(d7.dropped(), 0); + drop(q); + assert_eq!(d2.dropped(), 1); + assert_eq!(d3.dropped(), 1); + assert_eq!(d4.dropped(), 1); + assert_eq!(d5.dropped(), 1); + assert_eq!(d6.dropped(), 1); + assert_eq!(d7.dropped(), 1); +} + +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn extract_if_pred_panic_leak() { + struct_with_counted_drop!(D(u32), DROPS); + + let mut q = VecDeque::new(); + q.push_back(D(3)); + q.push_back(D(4)); + q.push_back(D(5)); + q.push_back(D(6)); + q.push_back(D(7)); + q.push_front(D(2)); + q.push_front(D(1)); + q.push_front(D(0)); + + _ = catch_unwind(AssertUnwindSafe(|| { + q.extract_if(.., |item| if item.0 >= 2 { panic!() } else { true }).for_each(drop) + })); + + assert_eq!(DROPS.get(), 2); // 0 and 1 + assert_eq!(q.len(), 6); +} From bf7b05c97bbb9466eb96bb5b098635d244e3590b Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Sat, 11 Oct 2025 01:31:25 +0100 Subject: [PATCH 26/45] refactor: move runtime functions to core Instead of `include_str!()`ing `range_search.rs`, just make it a normal module under `core::unicode`. This means the same source code doesn't have to be checked in twice, and it plays nicer with IDEs. Also rename it to `rt` since it includes functions for searching the bitsets and case conversion tables as well as the range represesentation. --- library/core/src/unicode/mod.rs | 1 + .../core/src/unicode/rt.rs | 46 +++- library/core/src/unicode/unicode_data.rs | 208 ++++-------------- .../src/case_mapping.rs | 80 ++++--- src/tools/unicode-table-generator/src/main.rs | 7 +- 5 files changed, 130 insertions(+), 212 deletions(-) rename src/tools/unicode-table-generator/src/range_search.rs => library/core/src/unicode/rt.rs (76%) diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index c71fa754e68fb..9bc4136517fae 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs @@ -18,6 +18,7 @@ pub(crate) use unicode_data::white_space::lookup as White_Space; pub(crate) mod printable; +mod rt; #[allow(unreachable_pub)] mod unicode_data; diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/library/core/src/unicode/rt.rs similarity index 76% rename from src/tools/unicode-table-generator/src/range_search.rs rename to library/core/src/unicode/rt.rs index 4d1dd9b423b59..c438635cd794e 100644 --- a/src/tools/unicode-table-generator/src/range_search.rs +++ b/library/core/src/unicode/rt.rs @@ -1,5 +1,7 @@ +//! Runtime support for `unicode_data`. + #[inline(always)] -const fn bitset_search< +pub(super) const fn bitset_search< const N: usize, const CHUNK_SIZE: usize, const N1: usize, @@ -46,10 +48,10 @@ const fn bitset_search< } #[repr(transparent)] -struct ShortOffsetRunHeader(u32); +pub(super) struct ShortOffsetRunHeader(pub(super) u32); impl ShortOffsetRunHeader { - const fn new(start_index: usize, prefix_sum: u32) -> Self { + pub(super) const fn new(start_index: usize, prefix_sum: u32) -> Self { assert!(start_index < (1 << 11)); assert!(prefix_sum < (1 << 21)); @@ -57,12 +59,12 @@ impl ShortOffsetRunHeader { } #[inline] - const fn start_index(&self) -> usize { + pub(super) const fn start_index(&self) -> usize { (self.0 >> 21) as usize } #[inline] - const fn prefix_sum(&self) -> u32 { + pub(super) const fn prefix_sum(&self) -> u32 { self.0 & ((1 << 21) - 1) } } @@ -72,7 +74,7 @@ impl ShortOffsetRunHeader { /// - The last element of `short_offset_runs` must be greater than `std::char::MAX`. /// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`. #[inline(always)] -unsafe fn skip_search( +pub(super) unsafe fn skip_search( needle: char, short_offset_runs: &[ShortOffsetRunHeader; SOR], offsets: &[u8; OFFSETS], @@ -126,3 +128,35 @@ unsafe fn skip_search( } offset_idx % 2 == 1 } + +/// # Safety +/// The second component of each tuple in `table` must either be: +/// - A valid `char` +/// - A value with the high bit (1 << 22) set, and the lower 22 bits +/// being a valid index into `multi`. +#[inline(always)] +pub(super) unsafe fn case_conversion( + c: char, + ascii_fn: fn(char) -> char, + table: &[(char, u32)], + multi: &[[char; 3]], +) -> [char; 3] { + const INDEX_MASK: u32 = 1 << 22; + + if c.is_ascii() { + return [ascii_fn(c), '\0', '\0']; + } + + let Ok(i) = table.binary_search_by(|&(key, _)| key.cmp(&c)) else { + return [c, '\0', '\0']; + }; + + let u = table[i].1; + match char::from_u32(u) { + Option::Some(c) => [c, '\0', '\0'], + Option::None => { + // SAFETY: Index comes from statically generated table + unsafe { *multi.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + } + } +} diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 3c38b44224f87..f9ab1585039e9 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -11,135 +11,7 @@ // to_upper : 13656 bytes // Total : 31911 bytes -#[inline(always)] -const fn bitset_search< - const N: usize, - const CHUNK_SIZE: usize, - const N1: usize, - const CANONICAL: usize, - const CANONICALIZED: usize, ->( - needle: u32, - chunk_idx_map: &[u8; N], - bitset_chunk_idx: &[[u8; CHUNK_SIZE]; N1], - bitset_canonical: &[u64; CANONICAL], - bitset_canonicalized: &[(u8, u8); CANONICALIZED], -) -> bool { - let bucket_idx = (needle / 64) as usize; - let chunk_map_idx = bucket_idx / CHUNK_SIZE; - let chunk_piece = bucket_idx % CHUNK_SIZE; - // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const. - let chunk_idx = if chunk_map_idx < chunk_idx_map.len() { - chunk_idx_map[chunk_map_idx] - } else { - return false; - }; - let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize; - // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const. - let word = if idx < bitset_canonical.len() { - bitset_canonical[idx] - } else { - let (real_idx, mapping) = bitset_canonicalized[idx - bitset_canonical.len()]; - let mut word = bitset_canonical[real_idx as usize]; - let should_invert = mapping & (1 << 6) != 0; - if should_invert { - word = !word; - } - // Lower 6 bits - let quantity = mapping & ((1 << 6) - 1); - if mapping & (1 << 7) != 0 { - // shift - word >>= quantity as u64; - } else { - word = word.rotate_left(quantity as u32); - } - word - }; - (word & (1 << (needle % 64) as u64)) != 0 -} - -#[repr(transparent)] -struct ShortOffsetRunHeader(u32); - -impl ShortOffsetRunHeader { - const fn new(start_index: usize, prefix_sum: u32) -> Self { - assert!(start_index < (1 << 11)); - assert!(prefix_sum < (1 << 21)); - - Self((start_index as u32) << 21 | prefix_sum) - } - - #[inline] - const fn start_index(&self) -> usize { - (self.0 >> 21) as usize - } - - #[inline] - const fn prefix_sum(&self) -> u32 { - self.0 & ((1 << 21) - 1) - } -} - -/// # Safety -/// -/// - The last element of `short_offset_runs` must be greater than `std::char::MAX`. -/// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`. -#[inline(always)] -unsafe fn skip_search( - needle: char, - short_offset_runs: &[ShortOffsetRunHeader; SOR], - offsets: &[u8; OFFSETS], -) -> bool { - let needle = needle as u32; - - let last_idx = - match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) { - Ok(idx) => idx + 1, - Err(idx) => idx, - }; - // SAFETY: `last_idx` *cannot* be past the end of the array, as the last - // element is greater than `std::char::MAX` (the largest possible needle) - // as guaranteed by the caller. - // - // So, we cannot have found it (i.e. `Ok(idx) => idx + 1 != length`) and the - // correct location cannot be past it, so `Err(idx) => idx != length` either. - // - // This means that we can avoid bounds checking for the accesses below, too. - // - // We need to use `intrinsics::assume` since the `panic_nounwind` contained - // in `hint::assert_unchecked` may not be optimized out. - unsafe { crate::intrinsics::assume(last_idx < SOR) }; - - let mut offset_idx = short_offset_runs[last_idx].start_index(); - let length = if let Some(next) = short_offset_runs.get(last_idx + 1) { - (*next).start_index() - offset_idx - } else { - offsets.len() - offset_idx - }; - - let prev = - last_idx.checked_sub(1).map(|prev| short_offset_runs[prev].prefix_sum()).unwrap_or(0); - - let total = needle - prev; - let mut prefix_sum = 0; - for _ in 0..(length - 1) { - // SAFETY: It is guaranteed that `length <= OFFSETS - offset_idx`, - // so it follows that `length - 1 + offset_idx < OFFSETS`, therefore - // `offset_idx < OFFSETS` is always true in this loop. - // - // We need to use `intrinsics::assume` since the `panic_nounwind` contained - // in `hint::assert_unchecked` may not be optimized out. - unsafe { crate::intrinsics::assume(offset_idx < OFFSETS) }; - let offset = offsets[offset_idx]; - prefix_sum += offset as u32; - if prefix_sum > total { - break; - } - offset_idx += 1; - } - offset_idx % 2 == 1 -} - +use super::rt::*; pub const UNICODE_VERSION: (u8, u8, u8) = (17, 0, 0); #[rustfmt::skip] @@ -758,42 +630,32 @@ pub mod white_space { #[rustfmt::skip] pub mod conversions { - const INDEX_MASK: u32 = 0x400000; - + #[inline] pub fn to_lower(c: char) -> [char; 3] { - if c.is_ascii() { - [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] - } else { - LOWERCASE_TABLE - .binary_search_by(|&(key, _)| key.cmp(&c)) - .map(|i| { - let u = LOWERCASE_TABLE[i].1; - char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { - // SAFETY: Index comes from statically generated table - unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } - }) - }) - .unwrap_or([c, '\0', '\0']) + const { + let mut i = 0; + while i < LOWERCASE_TABLE.len() { + let (_, val) = LOWERCASE_TABLE[i]; + if val & (1 << 22) == 0 { + assert!(char::from_u32(val).is_some()); + } else { + let index = val & ((1 << 22) - 1); + assert!((index as usize) < LOWERCASE_TABLE_MULTI.len()); + } + i += 1; + } } - } - pub fn to_upper(c: char) -> [char; 3] { - if c.is_ascii() { - [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] - } else { - UPPERCASE_TABLE - .binary_search_by(|&(key, _)| key.cmp(&c)) - .map(|i| { - let u = UPPERCASE_TABLE[i].1; - char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { - // SAFETY: Index comes from statically generated table - unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } - }) - }) - .unwrap_or([c, '\0', '\0']) + // SAFETY: Just checked that the tables are valid + unsafe { + super::case_conversion( + c, + |c| c.to_ascii_lowercase(), + LOWERCASE_TABLE, + LOWERCASE_TABLE_MULTI, + ) } } - 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), @@ -1155,6 +1017,32 @@ pub mod conversions { ['i', '\u{307}', '\u{0}'], ]; + #[inline] + pub fn to_upper(c: char) -> [char; 3] { + const { + let mut i = 0; + while i < UPPERCASE_TABLE.len() { + let (_, val) = UPPERCASE_TABLE[i]; + if val & (1 << 22) == 0 { + assert!(char::from_u32(val).is_some()); + } else { + let index = val & ((1 << 22) - 1); + assert!((index as usize) < UPPERCASE_TABLE_MULTI.len()); + } + i += 1; + } + } + + // SAFETY: Just checked that the tables are valid + unsafe { + super::case_conversion( + c, + |c| c.to_ascii_uppercase(), + UPPERCASE_TABLE, + UPPERCASE_TABLE_MULTI, + ) + } + } 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), diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 49aef3ec33ec7..784dff0fc43eb 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -9,10 +9,6 @@ const INDEX_MASK: u32 = 1 << 22; pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [usize; 2]) { let mut file = String::new(); - write!(file, "const INDEX_MASK: u32 = 0x{INDEX_MASK:x};").unwrap(); - file.push_str("\n\n"); - file.push_str(HEADER.trim_start()); - file.push('\n'); let (lower_tables, lower_size) = generate_tables("LOWER", &data.to_lower); file.push_str(&lower_tables); file.push_str("\n\n"); @@ -22,6 +18,9 @@ pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [usize; 2]) } fn generate_tables(case: &str, data: &BTreeMap) -> (String, usize) { + let case_lower = case.to_lowercase(); + let case_upper = case.to_uppercase(); + let mut mappings = Vec::with_capacity(data.len()); let mut multis = Vec::new(); @@ -47,8 +46,43 @@ fn generate_tables(case: &str, data: &BTreeMap) -> (String, usize mappings.push((CharEscape(key), value)); } - let mut tables = String::new(); let mut size = 0; + let mut tables = String::new(); + writeln!( + tables, + "\ +#[inline] +pub fn to_{case_lower}(c: char) -> [char; 3] {{ + const {{ + let mut i = 0; + while i < {case_upper}CASE_TABLE.len() {{ + let (_, val) = {case_upper}CASE_TABLE[i]; + if val & (1 << 22) == 0 {{ + assert!(char::from_u32(val).is_some()); + }} else {{ + let index = val & ((1 << 22) - 1); + assert!((index as usize) < {case_upper}CASE_TABLE_MULTI.len()); + }} + i += 1; + }} + }} + + // SAFETY: Just checked that the tables are valid + unsafe {{ + super::case_conversion( + c, + |c| c.to_ascii_{case_lower}case(), + {case_upper}CASE_TABLE, + {case_upper}CASE_TABLE_MULTI, + ) + }} +}}", + mappings = fmt_list(&mappings), + mappings_len = mappings.len(), + multis = fmt_list(&multis), + multis_len = multis.len(), + ) + .unwrap(); size += size_of_val(mappings.as_slice()); write!( @@ -82,39 +116,3 @@ impl fmt::Debug for CharEscape { write!(f, "'{}'", self.0.escape_default()) } } - -static HEADER: &str = r" -pub fn to_lower(c: char) -> [char; 3] { - if c.is_ascii() { - [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] - } else { - LOWERCASE_TABLE - .binary_search_by(|&(key, _)| key.cmp(&c)) - .map(|i| { - let u = LOWERCASE_TABLE[i].1; - char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { - // SAFETY: Index comes from statically generated table - unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } - }) - }) - .unwrap_or([c, '\0', '\0']) - } -} - -pub fn to_upper(c: char) -> [char; 3] { - if c.is_ascii() { - [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] - } else { - UPPERCASE_TABLE - .binary_search_by(|&(key, _)| key.cmp(&c)) - .map(|i| { - let u = UPPERCASE_TABLE[i].1; - char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { - // SAFETY: Index comes from statically generated table - unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } - }) - }) - .unwrap_or([c, '\0', '\0']) - } -} -"; diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index ded9205ffc4b9..182e61cf3c0d8 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -264,13 +264,9 @@ fn main() { } table_file.push_str(&format!("// {:16}: {:5} bytes\n", "Total", total_bytes)); - // Include the range search function table_file.push('\n'); - table_file.push_str(include_str!("range_search.rs")); - table_file.push('\n'); - + table_file.push_str("use super::rt::*;\n"); table_file.push_str(&version()); - table_file.push('\n'); modules.push((String::from("conversions"), conversions)); @@ -334,6 +330,7 @@ fn generate_tests(data: &UnicodeData) -> Result { writeln!(s, "#![allow(internal_features, dead_code)]")?; writeln!(s, "// ignore-tidy-filelength")?; writeln!(s, "use std::intrinsics;")?; + writeln!(s, "mod rt;")?; writeln!(s, "mod unicode_data;")?; writeln!(s, "fn main() {{")?; for (property, ranges) in &data.ranges { From c8ab4279a5999de4f8f18d43f7062763a7d6fb5f Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Sat, 11 Oct 2025 03:41:46 +0100 Subject: [PATCH 27/45] refactor: format `unicode_data` Remove `#[rustfmt::skip]` from all the generated modules in `unicode_data.rs`. This means we won't have to worry so much about getting indetation and formatting right when generating code. Exempted for now some tables which would be too big when formatted by `rustfmt`. --- library/core/src/unicode/unicode_data.rs | 669 +++++++++++------- .../src/case_mapping.rs | 2 + src/tools/unicode-table-generator/src/main.rs | 6 +- 3 files changed, 406 insertions(+), 271 deletions(-) diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index f9ab1585039e9..9d03529229bf1 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -14,36 +14,60 @@ use super::rt::*; pub const UNICODE_VERSION: (u8, u8, u8) = (17, 0, 0); -#[rustfmt::skip] pub mod alphabetic { use super::ShortOffsetRunHeader; 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(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, 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(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(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, 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; 1519] = [ @@ -52,57 +76,58 @@ pub mod alphabetic { 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, 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, 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, - 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33, - 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2, 17, 1, 26, - 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4, 1, 67, 89, - 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2, 20, 50, 1, - 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3, 10, 36, 2, - 11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, 0, 2, 6, 2, 38, 2, 6, 2, 8, 1, - 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116, 1, - 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2, 4, 5, 5, - 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23, 9, 7, 1, - 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4, 86, 6, 3, - 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10, 2, 20, 47, - 5, 8, 3, 113, 39, 9, 2, 103, 2, 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, + 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, 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, 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, + 2, 41, 1, 4, 2, 33, 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, + 6, 3, 0, 2, 17, 1, 26, 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, + 19, 14, 1, 4, 1, 67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, + 54, 28, 4, 63, 2, 20, 50, 1, 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, + 11, 14, 55, 22, 3, 10, 36, 2, 11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, + 0, 2, 6, 2, 38, 2, 6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, + 2, 6, 4, 13, 5, 3, 1, 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, + 1, 1, 1, 1, 4, 1, 11, 2, 4, 5, 5, 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, + 1, 2, 56, 7, 1, 16, 23, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, + 25, 9, 7, 5, 2, 5, 4, 86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, + 46, 2, 0, 3, 16, 10, 2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 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 { @@ -126,65 +151,82 @@ pub mod alphabetic { } } -#[rustfmt::skip] pub mod case_ignorable { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 36] = [ - ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(11, 4957), - ShortOffsetRunHeader::new(263, 5906), ShortOffsetRunHeader::new(265, 8125), - 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), + ShortOffsetRunHeader::new(0, 688), + ShortOffsetRunHeader::new(11, 4957), + ShortOffsetRunHeader::new(263, 5906), + ShortOffsetRunHeader::new(265, 8125), + 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; 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, - 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2, - 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, - 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3, - 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1, - 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 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, 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, 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, + 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, 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1, 20, 2, + 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, + 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3, 1, + 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, + 4, 4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 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, 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, 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 { @@ -208,36 +250,46 @@ pub mod case_ignorable { } } -#[rustfmt::skip] pub mod cased { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 22] = [ - ShortOffsetRunHeader::new(0, 4256), ShortOffsetRunHeader::new(51, 5024), - 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(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), + ShortOffsetRunHeader::new(0, 4256), + ShortOffsetRunHeader::new(51, 5024), + 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(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; 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, 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, + 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, 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, ]; #[inline] pub fn lookup(c: char) -> bool { @@ -261,58 +313,73 @@ pub mod cased { } } -#[rustfmt::skip] pub mod grapheme_extend { use super::ShortOffsetRunHeader; 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(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(0, 768), + ShortOffsetRunHeader::new(1, 1155), + ShortOffsetRunHeader::new(3, 1425), + ShortOffsetRunHeader::new(5, 4957), + ShortOffsetRunHeader::new(249, 5906), + ShortOffsetRunHeader::new(251, 8204), + 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; 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, - 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, - 1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1, - 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 2, 1, 1, 3, 3, 1, 4, 7, 2, 11, 2, 28, - 2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7, - 12, 8, 98, 1, 2, 9, 11, 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, 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, + 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, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, + 22, 6, 1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, + 3, 1, 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 2, 1, 1, 3, 3, 1, 4, 7, 2, 11, + 2, 28, 2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, + 1, 2, 7, 12, 8, 98, 1, 2, 9, 11, 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, 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 { @@ -336,14 +403,13 @@ pub mod grapheme_extend { } } -#[rustfmt::skip] pub mod lowercase { static BITSET_CHUNKS_MAP: [u8; 123] = [ 12, 17, 0, 0, 9, 0, 0, 13, 14, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, - 3, 18, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 0, 3, 18, 0, 7, ]; static BITSET_INDEX_CHUNKS: [[u8; 16]; 20] = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -427,65 +493,105 @@ pub mod lowercase { 0b1110101111000000000000000000000000001111111111111111111111111100, ]; 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), + (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 { debug_assert!(!c.is_ascii()); - (c as u32) >= 0xaa && - super::bitset_search( - c as u32, - &BITSET_CHUNKS_MAP, - &BITSET_INDEX_CHUNKS, - &BITSET_CANONICAL, - &BITSET_MAPPING, - ) + (c as u32) >= 0xaa + && super::bitset_search( + c as u32, + &BITSET_CHUNKS_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET_CANONICAL, + &BITSET_MAPPING, + ) } } -#[rustfmt::skip] pub mod n { use super::ShortOffsetRunHeader; 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), - ShortOffsetRunHeader::new(61, 8304), ShortOffsetRunHeader::new(77, 9312), - ShortOffsetRunHeader::new(87, 10102), ShortOffsetRunHeader::new(91, 11517), - ShortOffsetRunHeader::new(93, 12295), ShortOffsetRunHeader::new(95, 12690), - ShortOffsetRunHeader::new(101, 42528), ShortOffsetRunHeader::new(113, 43056), - ShortOffsetRunHeader::new(117, 44016), ShortOffsetRunHeader::new(129, 65296), - ShortOffsetRunHeader::new(131, 65799), ShortOffsetRunHeader::new(133, 66273), - ShortOffsetRunHeader::new(139, 67672), ShortOffsetRunHeader::new(151, 68858), - 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(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(0, 1632), + ShortOffsetRunHeader::new(7, 2406), + ShortOffsetRunHeader::new(13, 4160), + ShortOffsetRunHeader::new(47, 4969), + ShortOffsetRunHeader::new(51, 5870), + ShortOffsetRunHeader::new(53, 6470), + ShortOffsetRunHeader::new(61, 8304), + ShortOffsetRunHeader::new(77, 9312), + ShortOffsetRunHeader::new(87, 10102), + ShortOffsetRunHeader::new(91, 11517), + ShortOffsetRunHeader::new(93, 12295), + ShortOffsetRunHeader::new(95, 12690), + ShortOffsetRunHeader::new(101, 42528), + ShortOffsetRunHeader::new(113, 43056), + ShortOffsetRunHeader::new(117, 44016), + ShortOffsetRunHeader::new(129, 65296), + ShortOffsetRunHeader::new(131, 65799), + ShortOffsetRunHeader::new(133, 66273), + ShortOffsetRunHeader::new(139, 67672), + ShortOffsetRunHeader::new(151, 68858), + 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(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; 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, - 86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, 1, 0, 1, - 25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, 154, 10, - 38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, 29, 1, 8, - 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, 52, 2, - 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 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, 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, + 0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, 182, + 10, 86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, 1, + 0, 1, 25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, 154, + 10, 38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, 29, + 1, 8, 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, + 52, 2, 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 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, 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 { @@ -509,14 +615,13 @@ pub mod n { } } -#[rustfmt::skip] pub mod uppercase { static BITSET_CHUNKS_MAP: [u8; 125] = [ 3, 14, 6, 6, 0, 6, 6, 2, 5, 12, 6, 15, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 7, 6, 13, 6, 11, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16, 6, 6, - 6, 6, 10, 6, 4, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 7, 6, 13, 6, 11, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16, 6, + 6, 6, 6, 10, 6, 4, ]; static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [ [44, 44, 5, 35, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 5, 0], @@ -584,36 +689,57 @@ pub mod uppercase { 0b1111111100000000111111110000000000111111000000001111111100000000, ]; 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, 146), (2, 140), (2, 134), - (2, 130), (3, 164), (3, 146), (3, 20), (4, 178), (4, 171), + (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, 146), + (2, 140), + (2, 134), + (2, 130), + (3, 164), + (3, 146), + (3, 20), + (4, 178), + (4, 171), ]; pub const fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); - (c as u32) >= 0xc0 && - super::bitset_search( - c as u32, - &BITSET_CHUNKS_MAP, - &BITSET_INDEX_CHUNKS, - &BITSET_CANONICAL, - &BITSET_MAPPING, - ) + (c as u32) >= 0xc0 + && super::bitset_search( + c as u32, + &BITSET_CHUNKS_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET_CANONICAL, + &BITSET_MAPPING, + ) } } -#[rustfmt::skip] pub mod white_space { static WHITESPACE_MAP: [u8; 256] = [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; #[inline] pub const fn lookup(c: char) -> bool { @@ -628,7 +754,6 @@ pub mod white_space { } } -#[rustfmt::skip] pub mod conversions { #[inline] pub fn to_lower(c: char) -> [char; 3] { @@ -656,6 +781,7 @@ pub mod conversions { ) } } + #[rustfmt::skip] 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), @@ -1013,6 +1139,7 @@ pub mod conversions { ('\u{1e921}', 125251), ]; + #[rustfmt::skip] static LOWERCASE_TABLE_MULTI: &[[char; 3]; 1] = &[ ['i', '\u{307}', '\u{0}'], ]; @@ -1043,6 +1170,7 @@ pub mod conversions { ) } } + #[rustfmt::skip] 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), @@ -1423,6 +1551,7 @@ pub mod conversions { ('\u{1e941}', 125215), ('\u{1e942}', 125216), ('\u{1e943}', 125217), ]; + #[rustfmt::skip] static UPPERCASE_TABLE_MULTI: &[[char; 3]; 102] = &[ ['S', 'S', '\u{0}'], ['\u{2bc}', 'N', '\u{0}'], ['J', '\u{30c}', '\u{0}'], ['\u{399}', '\u{308}', '\u{301}'], ['\u{3a5}', '\u{308}', '\u{301}'], diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 784dff0fc43eb..ae9705d67f83b 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -85,6 +85,7 @@ pub fn to_{case_lower}(c: char) -> [char; 3] {{ .unwrap(); size += size_of_val(mappings.as_slice()); + writeln!(tables, "#[rustfmt::skip]").unwrap(); write!( tables, "static {}CASE_TABLE: &[(char, u32); {}] = &[{}];", @@ -97,6 +98,7 @@ pub fn to_{case_lower}(c: char) -> [char; 3] {{ tables.push_str("\n\n"); size += size_of_val(multis.as_slice()); + writeln!(tables, "#[rustfmt::skip]").unwrap(); write!( tables, "static {}CASE_TABLE_MULTI: &[[char; 3]; {}] = &[{}];", diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index 182e61cf3c0d8..2f6cde9d49b6f 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -272,7 +272,6 @@ fn main() { modules.push((String::from("conversions"), conversions)); for (name, contents) in modules { - table_file.push_str("#[rustfmt::skip]\n"); table_file.push_str(&format!("pub mod {name} {{\n")); for line in contents.lines() { if !line.trim().is_empty() { @@ -285,6 +284,11 @@ fn main() { } std::fs::write(&write_location, format!("{}\n", table_file.trim_end())).unwrap(); + rustfmt(&write_location); +} + +fn rustfmt(path: &str) { + std::process::Command::new("rustfmt").arg(path).status().expect("rustfmt failed"); } fn version() -> String { From 6d75cd2c2256fc9d6dd136feb8e5e529f13f841e Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Sat, 11 Oct 2025 22:50:52 +0100 Subject: [PATCH 28/45] refactor: remove check that `first_code_point` is non-ascii This check was made redundant (it will always be true) when we removed all ASCII characters from the tables (https://github.com/rust-lang/rust/pull/146173/commits/a8c669461f0c71985c72dd5b05f70b8d4d149e3b). --- .../unicode-table-generator/src/skiplist.rs | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/tools/unicode-table-generator/src/skiplist.rs b/src/tools/unicode-table-generator/src/skiplist.rs index 660a8f342f7a7..9b38fd4864f10 100644 --- a/src/tools/unicode-table-generator/src/skiplist.rs +++ b/src/tools/unicode-table-generator/src/skiplist.rs @@ -88,28 +88,21 @@ impl RawEmitter { // The inlining in this code works like the following: // - // The `skip_search` function is always inlined into the parent `lookup` fn, + // The `skip_search` function is always inlined into the parent `lookup_slow` fn, // thus the compiler can generate optimal code based on the referenced `static`s. // - // In the case of ASCII optimization, the lower-bounds check is inlined into - // the caller, and slower-path `skip_search` is outlined into a separate `lookup_slow` fn. - // - // Thus, in both cases, the `skip_search` function is specialized for the `static`s, - // and outlined into the prebuilt `std`. - if first_code_point > 0x7f { - writeln!(&mut self.file, "#[inline]").unwrap(); - writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); - writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); - writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} && lookup_slow(c)") - .unwrap(); - writeln!(&mut self.file, "}}").unwrap(); - writeln!(&mut self.file).unwrap(); - writeln!(&mut self.file, "#[inline(never)]").unwrap(); - writeln!(&mut self.file, "fn lookup_slow(c: char) -> bool {{").unwrap(); - } else { - writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); - writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); - } + // The lower-bounds check is inlined into the caller, and slower-path + // `skip_search` is outlined into a separate `lookup_slow` fn. + assert!(first_code_point > 0x7f); + writeln!(&mut self.file, "#[inline]").unwrap(); + writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); + writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} && lookup_slow(c)") + .unwrap(); + writeln!(&mut self.file, "}}").unwrap(); + writeln!(&mut self.file).unwrap(); + writeln!(&mut self.file, "#[inline(never)]").unwrap(); + writeln!(&mut self.file, "fn lookup_slow(c: char) -> bool {{").unwrap(); writeln!(&mut self.file, " const {{").unwrap(); writeln!( &mut self.file, From 9a80731094896f67ddb09d1ffa8496dbd2246b2d Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Sat, 11 Oct 2025 02:03:44 +0100 Subject: [PATCH 29/45] refactor: make string formatting more readable To make the final output code easier to see: * Get rid of the unnecessary line-noise of `.unwrap()`ing calls to `write!()` by moving the `.unwrap()` into a macro. * Join consecutive `write!()` calls using a single multiline format string. * Replace `.push()` and `.push_str(format!())` with `write!()`. * If after doing all of the above, there is only a single `write!()` call in the function, just construct the string directly with `format!()`. --- library/core/src/unicode/unicode_data.rs | 1676 +++++++++-------- .../src/cascading_map.rs | 39 +- .../src/case_mapping.rs | 66 +- .../src/fmt_helpers.rs | 82 + src/tools/unicode-table-generator/src/main.rs | 147 +- .../src/raw_emitter.rs | 96 +- .../unicode-table-generator/src/skiplist.rs | 89 +- 7 files changed, 1121 insertions(+), 1074 deletions(-) create mode 100644 src/tools/unicode-table-generator/src/fmt_helpers.rs diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 9d03529229bf1..81d0484310cf1 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -12,6 +12,7 @@ // Total : 31911 bytes use super::rt::*; + pub const UNICODE_VERSION: (u8, u8, u8) = (17, 0, 0); pub mod alphabetic { @@ -129,6 +130,7 @@ pub mod alphabetic { 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 { debug_assert!(!c.is_ascii()); @@ -228,6 +230,7 @@ pub mod case_ignorable { 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 { debug_assert!(!c.is_ascii()); @@ -291,6 +294,7 @@ pub mod cased { 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, ]; + #[inline] pub fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); @@ -381,6 +385,7 @@ pub mod grapheme_extend { 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 { debug_assert!(!c.is_ascii()); @@ -593,6 +598,7 @@ pub mod n { 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 { debug_assert!(!c.is_ascii()); @@ -741,20 +747,420 @@ pub mod white_space { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; + #[inline] pub const fn lookup(c: char) -> bool { debug_assert!(!c.is_ascii()); match c as u32 >> 8 { - 0 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0, - 22 => c as u32 == 0x1680, - 32 => WHITESPACE_MAP[c as usize & 0xff] & 2 != 0, - 48 => c as u32 == 0x3000, + 0x00 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0, + 0x16 => c as u32 == 0x1680, + 0x20 => WHITESPACE_MAP[c as usize & 0xff] & 2 != 0, + 0x30 => c as u32 == 0x3000, _ => false, } } } pub mod conversions { + #[rustfmt::skip] + static LOWERCASE_TABLE: &[(char, u32); 1462] = &[ + ('\u{c0}', 0xe0), ('\u{c1}', 0xe1), ('\u{c2}', 0xe2), ('\u{c3}', 0xe3), ('\u{c4}', 0xe4), + ('\u{c5}', 0xe5), ('\u{c6}', 0xe6), ('\u{c7}', 0xe7), ('\u{c8}', 0xe8), ('\u{c9}', 0xe9), + ('\u{ca}', 0xea), ('\u{cb}', 0xeb), ('\u{cc}', 0xec), ('\u{cd}', 0xed), ('\u{ce}', 0xee), + ('\u{cf}', 0xef), ('\u{d0}', 0xf0), ('\u{d1}', 0xf1), ('\u{d2}', 0xf2), ('\u{d3}', 0xf3), + ('\u{d4}', 0xf4), ('\u{d5}', 0xf5), ('\u{d6}', 0xf6), ('\u{d8}', 0xf8), ('\u{d9}', 0xf9), + ('\u{da}', 0xfa), ('\u{db}', 0xfb), ('\u{dc}', 0xfc), ('\u{dd}', 0xfd), ('\u{de}', 0xfe), + ('\u{100}', 0x101), ('\u{102}', 0x103), ('\u{104}', 0x105), ('\u{106}', 0x107), + ('\u{108}', 0x109), ('\u{10a}', 0x10b), ('\u{10c}', 0x10d), ('\u{10e}', 0x10f), + ('\u{110}', 0x111), ('\u{112}', 0x113), ('\u{114}', 0x115), ('\u{116}', 0x117), + ('\u{118}', 0x119), ('\u{11a}', 0x11b), ('\u{11c}', 0x11d), ('\u{11e}', 0x11f), + ('\u{120}', 0x121), ('\u{122}', 0x123), ('\u{124}', 0x125), ('\u{126}', 0x127), + ('\u{128}', 0x129), ('\u{12a}', 0x12b), ('\u{12c}', 0x12d), ('\u{12e}', 0x12f), + ('\u{130}', 0x400000), ('\u{132}', 0x133), ('\u{134}', 0x135), ('\u{136}', 0x137), + ('\u{139}', 0x13a), ('\u{13b}', 0x13c), ('\u{13d}', 0x13e), ('\u{13f}', 0x140), + ('\u{141}', 0x142), ('\u{143}', 0x144), ('\u{145}', 0x146), ('\u{147}', 0x148), + ('\u{14a}', 0x14b), ('\u{14c}', 0x14d), ('\u{14e}', 0x14f), ('\u{150}', 0x151), + ('\u{152}', 0x153), ('\u{154}', 0x155), ('\u{156}', 0x157), ('\u{158}', 0x159), + ('\u{15a}', 0x15b), ('\u{15c}', 0x15d), ('\u{15e}', 0x15f), ('\u{160}', 0x161), + ('\u{162}', 0x163), ('\u{164}', 0x165), ('\u{166}', 0x167), ('\u{168}', 0x169), + ('\u{16a}', 0x16b), ('\u{16c}', 0x16d), ('\u{16e}', 0x16f), ('\u{170}', 0x171), + ('\u{172}', 0x173), ('\u{174}', 0x175), ('\u{176}', 0x177), ('\u{178}', 0xff), + ('\u{179}', 0x17a), ('\u{17b}', 0x17c), ('\u{17d}', 0x17e), ('\u{181}', 0x253), + ('\u{182}', 0x183), ('\u{184}', 0x185), ('\u{186}', 0x254), ('\u{187}', 0x188), + ('\u{189}', 0x256), ('\u{18a}', 0x257), ('\u{18b}', 0x18c), ('\u{18e}', 0x1dd), + ('\u{18f}', 0x259), ('\u{190}', 0x25b), ('\u{191}', 0x192), ('\u{193}', 0x260), + ('\u{194}', 0x263), ('\u{196}', 0x269), ('\u{197}', 0x268), ('\u{198}', 0x199), + ('\u{19c}', 0x26f), ('\u{19d}', 0x272), ('\u{19f}', 0x275), ('\u{1a0}', 0x1a1), + ('\u{1a2}', 0x1a3), ('\u{1a4}', 0x1a5), ('\u{1a6}', 0x280), ('\u{1a7}', 0x1a8), + ('\u{1a9}', 0x283), ('\u{1ac}', 0x1ad), ('\u{1ae}', 0x288), ('\u{1af}', 0x1b0), + ('\u{1b1}', 0x28a), ('\u{1b2}', 0x28b), ('\u{1b3}', 0x1b4), ('\u{1b5}', 0x1b6), + ('\u{1b7}', 0x292), ('\u{1b8}', 0x1b9), ('\u{1bc}', 0x1bd), ('\u{1c4}', 0x1c6), + ('\u{1c5}', 0x1c6), ('\u{1c7}', 0x1c9), ('\u{1c8}', 0x1c9), ('\u{1ca}', 0x1cc), + ('\u{1cb}', 0x1cc), ('\u{1cd}', 0x1ce), ('\u{1cf}', 0x1d0), ('\u{1d1}', 0x1d2), + ('\u{1d3}', 0x1d4), ('\u{1d5}', 0x1d6), ('\u{1d7}', 0x1d8), ('\u{1d9}', 0x1da), + ('\u{1db}', 0x1dc), ('\u{1de}', 0x1df), ('\u{1e0}', 0x1e1), ('\u{1e2}', 0x1e3), + ('\u{1e4}', 0x1e5), ('\u{1e6}', 0x1e7), ('\u{1e8}', 0x1e9), ('\u{1ea}', 0x1eb), + ('\u{1ec}', 0x1ed), ('\u{1ee}', 0x1ef), ('\u{1f1}', 0x1f3), ('\u{1f2}', 0x1f3), + ('\u{1f4}', 0x1f5), ('\u{1f6}', 0x195), ('\u{1f7}', 0x1bf), ('\u{1f8}', 0x1f9), + ('\u{1fa}', 0x1fb), ('\u{1fc}', 0x1fd), ('\u{1fe}', 0x1ff), ('\u{200}', 0x201), + ('\u{202}', 0x203), ('\u{204}', 0x205), ('\u{206}', 0x207), ('\u{208}', 0x209), + ('\u{20a}', 0x20b), ('\u{20c}', 0x20d), ('\u{20e}', 0x20f), ('\u{210}', 0x211), + ('\u{212}', 0x213), ('\u{214}', 0x215), ('\u{216}', 0x217), ('\u{218}', 0x219), + ('\u{21a}', 0x21b), ('\u{21c}', 0x21d), ('\u{21e}', 0x21f), ('\u{220}', 0x19e), + ('\u{222}', 0x223), ('\u{224}', 0x225), ('\u{226}', 0x227), ('\u{228}', 0x229), + ('\u{22a}', 0x22b), ('\u{22c}', 0x22d), ('\u{22e}', 0x22f), ('\u{230}', 0x231), + ('\u{232}', 0x233), ('\u{23a}', 0x2c65), ('\u{23b}', 0x23c), ('\u{23d}', 0x19a), + ('\u{23e}', 0x2c66), ('\u{241}', 0x242), ('\u{243}', 0x180), ('\u{244}', 0x289), + ('\u{245}', 0x28c), ('\u{246}', 0x247), ('\u{248}', 0x249), ('\u{24a}', 0x24b), + ('\u{24c}', 0x24d), ('\u{24e}', 0x24f), ('\u{370}', 0x371), ('\u{372}', 0x373), + ('\u{376}', 0x377), ('\u{37f}', 0x3f3), ('\u{386}', 0x3ac), ('\u{388}', 0x3ad), + ('\u{389}', 0x3ae), ('\u{38a}', 0x3af), ('\u{38c}', 0x3cc), ('\u{38e}', 0x3cd), + ('\u{38f}', 0x3ce), ('\u{391}', 0x3b1), ('\u{392}', 0x3b2), ('\u{393}', 0x3b3), + ('\u{394}', 0x3b4), ('\u{395}', 0x3b5), ('\u{396}', 0x3b6), ('\u{397}', 0x3b7), + ('\u{398}', 0x3b8), ('\u{399}', 0x3b9), ('\u{39a}', 0x3ba), ('\u{39b}', 0x3bb), + ('\u{39c}', 0x3bc), ('\u{39d}', 0x3bd), ('\u{39e}', 0x3be), ('\u{39f}', 0x3bf), + ('\u{3a0}', 0x3c0), ('\u{3a1}', 0x3c1), ('\u{3a3}', 0x3c3), ('\u{3a4}', 0x3c4), + ('\u{3a5}', 0x3c5), ('\u{3a6}', 0x3c6), ('\u{3a7}', 0x3c7), ('\u{3a8}', 0x3c8), + ('\u{3a9}', 0x3c9), ('\u{3aa}', 0x3ca), ('\u{3ab}', 0x3cb), ('\u{3cf}', 0x3d7), + ('\u{3d8}', 0x3d9), ('\u{3da}', 0x3db), ('\u{3dc}', 0x3dd), ('\u{3de}', 0x3df), + ('\u{3e0}', 0x3e1), ('\u{3e2}', 0x3e3), ('\u{3e4}', 0x3e5), ('\u{3e6}', 0x3e7), + ('\u{3e8}', 0x3e9), ('\u{3ea}', 0x3eb), ('\u{3ec}', 0x3ed), ('\u{3ee}', 0x3ef), + ('\u{3f4}', 0x3b8), ('\u{3f7}', 0x3f8), ('\u{3f9}', 0x3f2), ('\u{3fa}', 0x3fb), + ('\u{3fd}', 0x37b), ('\u{3fe}', 0x37c), ('\u{3ff}', 0x37d), ('\u{400}', 0x450), + ('\u{401}', 0x451), ('\u{402}', 0x452), ('\u{403}', 0x453), ('\u{404}', 0x454), + ('\u{405}', 0x455), ('\u{406}', 0x456), ('\u{407}', 0x457), ('\u{408}', 0x458), + ('\u{409}', 0x459), ('\u{40a}', 0x45a), ('\u{40b}', 0x45b), ('\u{40c}', 0x45c), + ('\u{40d}', 0x45d), ('\u{40e}', 0x45e), ('\u{40f}', 0x45f), ('\u{410}', 0x430), + ('\u{411}', 0x431), ('\u{412}', 0x432), ('\u{413}', 0x433), ('\u{414}', 0x434), + ('\u{415}', 0x435), ('\u{416}', 0x436), ('\u{417}', 0x437), ('\u{418}', 0x438), + ('\u{419}', 0x439), ('\u{41a}', 0x43a), ('\u{41b}', 0x43b), ('\u{41c}', 0x43c), + ('\u{41d}', 0x43d), ('\u{41e}', 0x43e), ('\u{41f}', 0x43f), ('\u{420}', 0x440), + ('\u{421}', 0x441), ('\u{422}', 0x442), ('\u{423}', 0x443), ('\u{424}', 0x444), + ('\u{425}', 0x445), ('\u{426}', 0x446), ('\u{427}', 0x447), ('\u{428}', 0x448), + ('\u{429}', 0x449), ('\u{42a}', 0x44a), ('\u{42b}', 0x44b), ('\u{42c}', 0x44c), + ('\u{42d}', 0x44d), ('\u{42e}', 0x44e), ('\u{42f}', 0x44f), ('\u{460}', 0x461), + ('\u{462}', 0x463), ('\u{464}', 0x465), ('\u{466}', 0x467), ('\u{468}', 0x469), + ('\u{46a}', 0x46b), ('\u{46c}', 0x46d), ('\u{46e}', 0x46f), ('\u{470}', 0x471), + ('\u{472}', 0x473), ('\u{474}', 0x475), ('\u{476}', 0x477), ('\u{478}', 0x479), + ('\u{47a}', 0x47b), ('\u{47c}', 0x47d), ('\u{47e}', 0x47f), ('\u{480}', 0x481), + ('\u{48a}', 0x48b), ('\u{48c}', 0x48d), ('\u{48e}', 0x48f), ('\u{490}', 0x491), + ('\u{492}', 0x493), ('\u{494}', 0x495), ('\u{496}', 0x497), ('\u{498}', 0x499), + ('\u{49a}', 0x49b), ('\u{49c}', 0x49d), ('\u{49e}', 0x49f), ('\u{4a0}', 0x4a1), + ('\u{4a2}', 0x4a3), ('\u{4a4}', 0x4a5), ('\u{4a6}', 0x4a7), ('\u{4a8}', 0x4a9), + ('\u{4aa}', 0x4ab), ('\u{4ac}', 0x4ad), ('\u{4ae}', 0x4af), ('\u{4b0}', 0x4b1), + ('\u{4b2}', 0x4b3), ('\u{4b4}', 0x4b5), ('\u{4b6}', 0x4b7), ('\u{4b8}', 0x4b9), + ('\u{4ba}', 0x4bb), ('\u{4bc}', 0x4bd), ('\u{4be}', 0x4bf), ('\u{4c0}', 0x4cf), + ('\u{4c1}', 0x4c2), ('\u{4c3}', 0x4c4), ('\u{4c5}', 0x4c6), ('\u{4c7}', 0x4c8), + ('\u{4c9}', 0x4ca), ('\u{4cb}', 0x4cc), ('\u{4cd}', 0x4ce), ('\u{4d0}', 0x4d1), + ('\u{4d2}', 0x4d3), ('\u{4d4}', 0x4d5), ('\u{4d6}', 0x4d7), ('\u{4d8}', 0x4d9), + ('\u{4da}', 0x4db), ('\u{4dc}', 0x4dd), ('\u{4de}', 0x4df), ('\u{4e0}', 0x4e1), + ('\u{4e2}', 0x4e3), ('\u{4e4}', 0x4e5), ('\u{4e6}', 0x4e7), ('\u{4e8}', 0x4e9), + ('\u{4ea}', 0x4eb), ('\u{4ec}', 0x4ed), ('\u{4ee}', 0x4ef), ('\u{4f0}', 0x4f1), + ('\u{4f2}', 0x4f3), ('\u{4f4}', 0x4f5), ('\u{4f6}', 0x4f7), ('\u{4f8}', 0x4f9), + ('\u{4fa}', 0x4fb), ('\u{4fc}', 0x4fd), ('\u{4fe}', 0x4ff), ('\u{500}', 0x501), + ('\u{502}', 0x503), ('\u{504}', 0x505), ('\u{506}', 0x507), ('\u{508}', 0x509), + ('\u{50a}', 0x50b), ('\u{50c}', 0x50d), ('\u{50e}', 0x50f), ('\u{510}', 0x511), + ('\u{512}', 0x513), ('\u{514}', 0x515), ('\u{516}', 0x517), ('\u{518}', 0x519), + ('\u{51a}', 0x51b), ('\u{51c}', 0x51d), ('\u{51e}', 0x51f), ('\u{520}', 0x521), + ('\u{522}', 0x523), ('\u{524}', 0x525), ('\u{526}', 0x527), ('\u{528}', 0x529), + ('\u{52a}', 0x52b), ('\u{52c}', 0x52d), ('\u{52e}', 0x52f), ('\u{531}', 0x561), + ('\u{532}', 0x562), ('\u{533}', 0x563), ('\u{534}', 0x564), ('\u{535}', 0x565), + ('\u{536}', 0x566), ('\u{537}', 0x567), ('\u{538}', 0x568), ('\u{539}', 0x569), + ('\u{53a}', 0x56a), ('\u{53b}', 0x56b), ('\u{53c}', 0x56c), ('\u{53d}', 0x56d), + ('\u{53e}', 0x56e), ('\u{53f}', 0x56f), ('\u{540}', 0x570), ('\u{541}', 0x571), + ('\u{542}', 0x572), ('\u{543}', 0x573), ('\u{544}', 0x574), ('\u{545}', 0x575), + ('\u{546}', 0x576), ('\u{547}', 0x577), ('\u{548}', 0x578), ('\u{549}', 0x579), + ('\u{54a}', 0x57a), ('\u{54b}', 0x57b), ('\u{54c}', 0x57c), ('\u{54d}', 0x57d), + ('\u{54e}', 0x57e), ('\u{54f}', 0x57f), ('\u{550}', 0x580), ('\u{551}', 0x581), + ('\u{552}', 0x582), ('\u{553}', 0x583), ('\u{554}', 0x584), ('\u{555}', 0x585), + ('\u{556}', 0x586), ('\u{10a0}', 0x2d00), ('\u{10a1}', 0x2d01), ('\u{10a2}', 0x2d02), + ('\u{10a3}', 0x2d03), ('\u{10a4}', 0x2d04), ('\u{10a5}', 0x2d05), ('\u{10a6}', 0x2d06), + ('\u{10a7}', 0x2d07), ('\u{10a8}', 0x2d08), ('\u{10a9}', 0x2d09), ('\u{10aa}', 0x2d0a), + ('\u{10ab}', 0x2d0b), ('\u{10ac}', 0x2d0c), ('\u{10ad}', 0x2d0d), ('\u{10ae}', 0x2d0e), + ('\u{10af}', 0x2d0f), ('\u{10b0}', 0x2d10), ('\u{10b1}', 0x2d11), ('\u{10b2}', 0x2d12), + ('\u{10b3}', 0x2d13), ('\u{10b4}', 0x2d14), ('\u{10b5}', 0x2d15), ('\u{10b6}', 0x2d16), + ('\u{10b7}', 0x2d17), ('\u{10b8}', 0x2d18), ('\u{10b9}', 0x2d19), ('\u{10ba}', 0x2d1a), + ('\u{10bb}', 0x2d1b), ('\u{10bc}', 0x2d1c), ('\u{10bd}', 0x2d1d), ('\u{10be}', 0x2d1e), + ('\u{10bf}', 0x2d1f), ('\u{10c0}', 0x2d20), ('\u{10c1}', 0x2d21), ('\u{10c2}', 0x2d22), + ('\u{10c3}', 0x2d23), ('\u{10c4}', 0x2d24), ('\u{10c5}', 0x2d25), ('\u{10c7}', 0x2d27), + ('\u{10cd}', 0x2d2d), ('\u{13a0}', 0xab70), ('\u{13a1}', 0xab71), ('\u{13a2}', 0xab72), + ('\u{13a3}', 0xab73), ('\u{13a4}', 0xab74), ('\u{13a5}', 0xab75), ('\u{13a6}', 0xab76), + ('\u{13a7}', 0xab77), ('\u{13a8}', 0xab78), ('\u{13a9}', 0xab79), ('\u{13aa}', 0xab7a), + ('\u{13ab}', 0xab7b), ('\u{13ac}', 0xab7c), ('\u{13ad}', 0xab7d), ('\u{13ae}', 0xab7e), + ('\u{13af}', 0xab7f), ('\u{13b0}', 0xab80), ('\u{13b1}', 0xab81), ('\u{13b2}', 0xab82), + ('\u{13b3}', 0xab83), ('\u{13b4}', 0xab84), ('\u{13b5}', 0xab85), ('\u{13b6}', 0xab86), + ('\u{13b7}', 0xab87), ('\u{13b8}', 0xab88), ('\u{13b9}', 0xab89), ('\u{13ba}', 0xab8a), + ('\u{13bb}', 0xab8b), ('\u{13bc}', 0xab8c), ('\u{13bd}', 0xab8d), ('\u{13be}', 0xab8e), + ('\u{13bf}', 0xab8f), ('\u{13c0}', 0xab90), ('\u{13c1}', 0xab91), ('\u{13c2}', 0xab92), + ('\u{13c3}', 0xab93), ('\u{13c4}', 0xab94), ('\u{13c5}', 0xab95), ('\u{13c6}', 0xab96), + ('\u{13c7}', 0xab97), ('\u{13c8}', 0xab98), ('\u{13c9}', 0xab99), ('\u{13ca}', 0xab9a), + ('\u{13cb}', 0xab9b), ('\u{13cc}', 0xab9c), ('\u{13cd}', 0xab9d), ('\u{13ce}', 0xab9e), + ('\u{13cf}', 0xab9f), ('\u{13d0}', 0xaba0), ('\u{13d1}', 0xaba1), ('\u{13d2}', 0xaba2), + ('\u{13d3}', 0xaba3), ('\u{13d4}', 0xaba4), ('\u{13d5}', 0xaba5), ('\u{13d6}', 0xaba6), + ('\u{13d7}', 0xaba7), ('\u{13d8}', 0xaba8), ('\u{13d9}', 0xaba9), ('\u{13da}', 0xabaa), + ('\u{13db}', 0xabab), ('\u{13dc}', 0xabac), ('\u{13dd}', 0xabad), ('\u{13de}', 0xabae), + ('\u{13df}', 0xabaf), ('\u{13e0}', 0xabb0), ('\u{13e1}', 0xabb1), ('\u{13e2}', 0xabb2), + ('\u{13e3}', 0xabb3), ('\u{13e4}', 0xabb4), ('\u{13e5}', 0xabb5), ('\u{13e6}', 0xabb6), + ('\u{13e7}', 0xabb7), ('\u{13e8}', 0xabb8), ('\u{13e9}', 0xabb9), ('\u{13ea}', 0xabba), + ('\u{13eb}', 0xabbb), ('\u{13ec}', 0xabbc), ('\u{13ed}', 0xabbd), ('\u{13ee}', 0xabbe), + ('\u{13ef}', 0xabbf), ('\u{13f0}', 0x13f8), ('\u{13f1}', 0x13f9), ('\u{13f2}', 0x13fa), + ('\u{13f3}', 0x13fb), ('\u{13f4}', 0x13fc), ('\u{13f5}', 0x13fd), ('\u{1c89}', 0x1c8a), + ('\u{1c90}', 0x10d0), ('\u{1c91}', 0x10d1), ('\u{1c92}', 0x10d2), ('\u{1c93}', 0x10d3), + ('\u{1c94}', 0x10d4), ('\u{1c95}', 0x10d5), ('\u{1c96}', 0x10d6), ('\u{1c97}', 0x10d7), + ('\u{1c98}', 0x10d8), ('\u{1c99}', 0x10d9), ('\u{1c9a}', 0x10da), ('\u{1c9b}', 0x10db), + ('\u{1c9c}', 0x10dc), ('\u{1c9d}', 0x10dd), ('\u{1c9e}', 0x10de), ('\u{1c9f}', 0x10df), + ('\u{1ca0}', 0x10e0), ('\u{1ca1}', 0x10e1), ('\u{1ca2}', 0x10e2), ('\u{1ca3}', 0x10e3), + ('\u{1ca4}', 0x10e4), ('\u{1ca5}', 0x10e5), ('\u{1ca6}', 0x10e6), ('\u{1ca7}', 0x10e7), + ('\u{1ca8}', 0x10e8), ('\u{1ca9}', 0x10e9), ('\u{1caa}', 0x10ea), ('\u{1cab}', 0x10eb), + ('\u{1cac}', 0x10ec), ('\u{1cad}', 0x10ed), ('\u{1cae}', 0x10ee), ('\u{1caf}', 0x10ef), + ('\u{1cb0}', 0x10f0), ('\u{1cb1}', 0x10f1), ('\u{1cb2}', 0x10f2), ('\u{1cb3}', 0x10f3), + ('\u{1cb4}', 0x10f4), ('\u{1cb5}', 0x10f5), ('\u{1cb6}', 0x10f6), ('\u{1cb7}', 0x10f7), + ('\u{1cb8}', 0x10f8), ('\u{1cb9}', 0x10f9), ('\u{1cba}', 0x10fa), ('\u{1cbd}', 0x10fd), + ('\u{1cbe}', 0x10fe), ('\u{1cbf}', 0x10ff), ('\u{1e00}', 0x1e01), ('\u{1e02}', 0x1e03), + ('\u{1e04}', 0x1e05), ('\u{1e06}', 0x1e07), ('\u{1e08}', 0x1e09), ('\u{1e0a}', 0x1e0b), + ('\u{1e0c}', 0x1e0d), ('\u{1e0e}', 0x1e0f), ('\u{1e10}', 0x1e11), ('\u{1e12}', 0x1e13), + ('\u{1e14}', 0x1e15), ('\u{1e16}', 0x1e17), ('\u{1e18}', 0x1e19), ('\u{1e1a}', 0x1e1b), + ('\u{1e1c}', 0x1e1d), ('\u{1e1e}', 0x1e1f), ('\u{1e20}', 0x1e21), ('\u{1e22}', 0x1e23), + ('\u{1e24}', 0x1e25), ('\u{1e26}', 0x1e27), ('\u{1e28}', 0x1e29), ('\u{1e2a}', 0x1e2b), + ('\u{1e2c}', 0x1e2d), ('\u{1e2e}', 0x1e2f), ('\u{1e30}', 0x1e31), ('\u{1e32}', 0x1e33), + ('\u{1e34}', 0x1e35), ('\u{1e36}', 0x1e37), ('\u{1e38}', 0x1e39), ('\u{1e3a}', 0x1e3b), + ('\u{1e3c}', 0x1e3d), ('\u{1e3e}', 0x1e3f), ('\u{1e40}', 0x1e41), ('\u{1e42}', 0x1e43), + ('\u{1e44}', 0x1e45), ('\u{1e46}', 0x1e47), ('\u{1e48}', 0x1e49), ('\u{1e4a}', 0x1e4b), + ('\u{1e4c}', 0x1e4d), ('\u{1e4e}', 0x1e4f), ('\u{1e50}', 0x1e51), ('\u{1e52}', 0x1e53), + ('\u{1e54}', 0x1e55), ('\u{1e56}', 0x1e57), ('\u{1e58}', 0x1e59), ('\u{1e5a}', 0x1e5b), + ('\u{1e5c}', 0x1e5d), ('\u{1e5e}', 0x1e5f), ('\u{1e60}', 0x1e61), ('\u{1e62}', 0x1e63), + ('\u{1e64}', 0x1e65), ('\u{1e66}', 0x1e67), ('\u{1e68}', 0x1e69), ('\u{1e6a}', 0x1e6b), + ('\u{1e6c}', 0x1e6d), ('\u{1e6e}', 0x1e6f), ('\u{1e70}', 0x1e71), ('\u{1e72}', 0x1e73), + ('\u{1e74}', 0x1e75), ('\u{1e76}', 0x1e77), ('\u{1e78}', 0x1e79), ('\u{1e7a}', 0x1e7b), + ('\u{1e7c}', 0x1e7d), ('\u{1e7e}', 0x1e7f), ('\u{1e80}', 0x1e81), ('\u{1e82}', 0x1e83), + ('\u{1e84}', 0x1e85), ('\u{1e86}', 0x1e87), ('\u{1e88}', 0x1e89), ('\u{1e8a}', 0x1e8b), + ('\u{1e8c}', 0x1e8d), ('\u{1e8e}', 0x1e8f), ('\u{1e90}', 0x1e91), ('\u{1e92}', 0x1e93), + ('\u{1e94}', 0x1e95), ('\u{1e9e}', 0xdf), ('\u{1ea0}', 0x1ea1), ('\u{1ea2}', 0x1ea3), + ('\u{1ea4}', 0x1ea5), ('\u{1ea6}', 0x1ea7), ('\u{1ea8}', 0x1ea9), ('\u{1eaa}', 0x1eab), + ('\u{1eac}', 0x1ead), ('\u{1eae}', 0x1eaf), ('\u{1eb0}', 0x1eb1), ('\u{1eb2}', 0x1eb3), + ('\u{1eb4}', 0x1eb5), ('\u{1eb6}', 0x1eb7), ('\u{1eb8}', 0x1eb9), ('\u{1eba}', 0x1ebb), + ('\u{1ebc}', 0x1ebd), ('\u{1ebe}', 0x1ebf), ('\u{1ec0}', 0x1ec1), ('\u{1ec2}', 0x1ec3), + ('\u{1ec4}', 0x1ec5), ('\u{1ec6}', 0x1ec7), ('\u{1ec8}', 0x1ec9), ('\u{1eca}', 0x1ecb), + ('\u{1ecc}', 0x1ecd), ('\u{1ece}', 0x1ecf), ('\u{1ed0}', 0x1ed1), ('\u{1ed2}', 0x1ed3), + ('\u{1ed4}', 0x1ed5), ('\u{1ed6}', 0x1ed7), ('\u{1ed8}', 0x1ed9), ('\u{1eda}', 0x1edb), + ('\u{1edc}', 0x1edd), ('\u{1ede}', 0x1edf), ('\u{1ee0}', 0x1ee1), ('\u{1ee2}', 0x1ee3), + ('\u{1ee4}', 0x1ee5), ('\u{1ee6}', 0x1ee7), ('\u{1ee8}', 0x1ee9), ('\u{1eea}', 0x1eeb), + ('\u{1eec}', 0x1eed), ('\u{1eee}', 0x1eef), ('\u{1ef0}', 0x1ef1), ('\u{1ef2}', 0x1ef3), + ('\u{1ef4}', 0x1ef5), ('\u{1ef6}', 0x1ef7), ('\u{1ef8}', 0x1ef9), ('\u{1efa}', 0x1efb), + ('\u{1efc}', 0x1efd), ('\u{1efe}', 0x1eff), ('\u{1f08}', 0x1f00), ('\u{1f09}', 0x1f01), + ('\u{1f0a}', 0x1f02), ('\u{1f0b}', 0x1f03), ('\u{1f0c}', 0x1f04), ('\u{1f0d}', 0x1f05), + ('\u{1f0e}', 0x1f06), ('\u{1f0f}', 0x1f07), ('\u{1f18}', 0x1f10), ('\u{1f19}', 0x1f11), + ('\u{1f1a}', 0x1f12), ('\u{1f1b}', 0x1f13), ('\u{1f1c}', 0x1f14), ('\u{1f1d}', 0x1f15), + ('\u{1f28}', 0x1f20), ('\u{1f29}', 0x1f21), ('\u{1f2a}', 0x1f22), ('\u{1f2b}', 0x1f23), + ('\u{1f2c}', 0x1f24), ('\u{1f2d}', 0x1f25), ('\u{1f2e}', 0x1f26), ('\u{1f2f}', 0x1f27), + ('\u{1f38}', 0x1f30), ('\u{1f39}', 0x1f31), ('\u{1f3a}', 0x1f32), ('\u{1f3b}', 0x1f33), + ('\u{1f3c}', 0x1f34), ('\u{1f3d}', 0x1f35), ('\u{1f3e}', 0x1f36), ('\u{1f3f}', 0x1f37), + ('\u{1f48}', 0x1f40), ('\u{1f49}', 0x1f41), ('\u{1f4a}', 0x1f42), ('\u{1f4b}', 0x1f43), + ('\u{1f4c}', 0x1f44), ('\u{1f4d}', 0x1f45), ('\u{1f59}', 0x1f51), ('\u{1f5b}', 0x1f53), + ('\u{1f5d}', 0x1f55), ('\u{1f5f}', 0x1f57), ('\u{1f68}', 0x1f60), ('\u{1f69}', 0x1f61), + ('\u{1f6a}', 0x1f62), ('\u{1f6b}', 0x1f63), ('\u{1f6c}', 0x1f64), ('\u{1f6d}', 0x1f65), + ('\u{1f6e}', 0x1f66), ('\u{1f6f}', 0x1f67), ('\u{1f88}', 0x1f80), ('\u{1f89}', 0x1f81), + ('\u{1f8a}', 0x1f82), ('\u{1f8b}', 0x1f83), ('\u{1f8c}', 0x1f84), ('\u{1f8d}', 0x1f85), + ('\u{1f8e}', 0x1f86), ('\u{1f8f}', 0x1f87), ('\u{1f98}', 0x1f90), ('\u{1f99}', 0x1f91), + ('\u{1f9a}', 0x1f92), ('\u{1f9b}', 0x1f93), ('\u{1f9c}', 0x1f94), ('\u{1f9d}', 0x1f95), + ('\u{1f9e}', 0x1f96), ('\u{1f9f}', 0x1f97), ('\u{1fa8}', 0x1fa0), ('\u{1fa9}', 0x1fa1), + ('\u{1faa}', 0x1fa2), ('\u{1fab}', 0x1fa3), ('\u{1fac}', 0x1fa4), ('\u{1fad}', 0x1fa5), + ('\u{1fae}', 0x1fa6), ('\u{1faf}', 0x1fa7), ('\u{1fb8}', 0x1fb0), ('\u{1fb9}', 0x1fb1), + ('\u{1fba}', 0x1f70), ('\u{1fbb}', 0x1f71), ('\u{1fbc}', 0x1fb3), ('\u{1fc8}', 0x1f72), + ('\u{1fc9}', 0x1f73), ('\u{1fca}', 0x1f74), ('\u{1fcb}', 0x1f75), ('\u{1fcc}', 0x1fc3), + ('\u{1fd8}', 0x1fd0), ('\u{1fd9}', 0x1fd1), ('\u{1fda}', 0x1f76), ('\u{1fdb}', 0x1f77), + ('\u{1fe8}', 0x1fe0), ('\u{1fe9}', 0x1fe1), ('\u{1fea}', 0x1f7a), ('\u{1feb}', 0x1f7b), + ('\u{1fec}', 0x1fe5), ('\u{1ff8}', 0x1f78), ('\u{1ff9}', 0x1f79), ('\u{1ffa}', 0x1f7c), + ('\u{1ffb}', 0x1f7d), ('\u{1ffc}', 0x1ff3), ('\u{2126}', 0x3c9), ('\u{212a}', 0x6b), + ('\u{212b}', 0xe5), ('\u{2132}', 0x214e), ('\u{2160}', 0x2170), ('\u{2161}', 0x2171), + ('\u{2162}', 0x2172), ('\u{2163}', 0x2173), ('\u{2164}', 0x2174), ('\u{2165}', 0x2175), + ('\u{2166}', 0x2176), ('\u{2167}', 0x2177), ('\u{2168}', 0x2178), ('\u{2169}', 0x2179), + ('\u{216a}', 0x217a), ('\u{216b}', 0x217b), ('\u{216c}', 0x217c), ('\u{216d}', 0x217d), + ('\u{216e}', 0x217e), ('\u{216f}', 0x217f), ('\u{2183}', 0x2184), ('\u{24b6}', 0x24d0), + ('\u{24b7}', 0x24d1), ('\u{24b8}', 0x24d2), ('\u{24b9}', 0x24d3), ('\u{24ba}', 0x24d4), + ('\u{24bb}', 0x24d5), ('\u{24bc}', 0x24d6), ('\u{24bd}', 0x24d7), ('\u{24be}', 0x24d8), + ('\u{24bf}', 0x24d9), ('\u{24c0}', 0x24da), ('\u{24c1}', 0x24db), ('\u{24c2}', 0x24dc), + ('\u{24c3}', 0x24dd), ('\u{24c4}', 0x24de), ('\u{24c5}', 0x24df), ('\u{24c6}', 0x24e0), + ('\u{24c7}', 0x24e1), ('\u{24c8}', 0x24e2), ('\u{24c9}', 0x24e3), ('\u{24ca}', 0x24e4), + ('\u{24cb}', 0x24e5), ('\u{24cc}', 0x24e6), ('\u{24cd}', 0x24e7), ('\u{24ce}', 0x24e8), + ('\u{24cf}', 0x24e9), ('\u{2c00}', 0x2c30), ('\u{2c01}', 0x2c31), ('\u{2c02}', 0x2c32), + ('\u{2c03}', 0x2c33), ('\u{2c04}', 0x2c34), ('\u{2c05}', 0x2c35), ('\u{2c06}', 0x2c36), + ('\u{2c07}', 0x2c37), ('\u{2c08}', 0x2c38), ('\u{2c09}', 0x2c39), ('\u{2c0a}', 0x2c3a), + ('\u{2c0b}', 0x2c3b), ('\u{2c0c}', 0x2c3c), ('\u{2c0d}', 0x2c3d), ('\u{2c0e}', 0x2c3e), + ('\u{2c0f}', 0x2c3f), ('\u{2c10}', 0x2c40), ('\u{2c11}', 0x2c41), ('\u{2c12}', 0x2c42), + ('\u{2c13}', 0x2c43), ('\u{2c14}', 0x2c44), ('\u{2c15}', 0x2c45), ('\u{2c16}', 0x2c46), + ('\u{2c17}', 0x2c47), ('\u{2c18}', 0x2c48), ('\u{2c19}', 0x2c49), ('\u{2c1a}', 0x2c4a), + ('\u{2c1b}', 0x2c4b), ('\u{2c1c}', 0x2c4c), ('\u{2c1d}', 0x2c4d), ('\u{2c1e}', 0x2c4e), + ('\u{2c1f}', 0x2c4f), ('\u{2c20}', 0x2c50), ('\u{2c21}', 0x2c51), ('\u{2c22}', 0x2c52), + ('\u{2c23}', 0x2c53), ('\u{2c24}', 0x2c54), ('\u{2c25}', 0x2c55), ('\u{2c26}', 0x2c56), + ('\u{2c27}', 0x2c57), ('\u{2c28}', 0x2c58), ('\u{2c29}', 0x2c59), ('\u{2c2a}', 0x2c5a), + ('\u{2c2b}', 0x2c5b), ('\u{2c2c}', 0x2c5c), ('\u{2c2d}', 0x2c5d), ('\u{2c2e}', 0x2c5e), + ('\u{2c2f}', 0x2c5f), ('\u{2c60}', 0x2c61), ('\u{2c62}', 0x26b), ('\u{2c63}', 0x1d7d), + ('\u{2c64}', 0x27d), ('\u{2c67}', 0x2c68), ('\u{2c69}', 0x2c6a), ('\u{2c6b}', 0x2c6c), + ('\u{2c6d}', 0x251), ('\u{2c6e}', 0x271), ('\u{2c6f}', 0x250), ('\u{2c70}', 0x252), + ('\u{2c72}', 0x2c73), ('\u{2c75}', 0x2c76), ('\u{2c7e}', 0x23f), ('\u{2c7f}', 0x240), + ('\u{2c80}', 0x2c81), ('\u{2c82}', 0x2c83), ('\u{2c84}', 0x2c85), ('\u{2c86}', 0x2c87), + ('\u{2c88}', 0x2c89), ('\u{2c8a}', 0x2c8b), ('\u{2c8c}', 0x2c8d), ('\u{2c8e}', 0x2c8f), + ('\u{2c90}', 0x2c91), ('\u{2c92}', 0x2c93), ('\u{2c94}', 0x2c95), ('\u{2c96}', 0x2c97), + ('\u{2c98}', 0x2c99), ('\u{2c9a}', 0x2c9b), ('\u{2c9c}', 0x2c9d), ('\u{2c9e}', 0x2c9f), + ('\u{2ca0}', 0x2ca1), ('\u{2ca2}', 0x2ca3), ('\u{2ca4}', 0x2ca5), ('\u{2ca6}', 0x2ca7), + ('\u{2ca8}', 0x2ca9), ('\u{2caa}', 0x2cab), ('\u{2cac}', 0x2cad), ('\u{2cae}', 0x2caf), + ('\u{2cb0}', 0x2cb1), ('\u{2cb2}', 0x2cb3), ('\u{2cb4}', 0x2cb5), ('\u{2cb6}', 0x2cb7), + ('\u{2cb8}', 0x2cb9), ('\u{2cba}', 0x2cbb), ('\u{2cbc}', 0x2cbd), ('\u{2cbe}', 0x2cbf), + ('\u{2cc0}', 0x2cc1), ('\u{2cc2}', 0x2cc3), ('\u{2cc4}', 0x2cc5), ('\u{2cc6}', 0x2cc7), + ('\u{2cc8}', 0x2cc9), ('\u{2cca}', 0x2ccb), ('\u{2ccc}', 0x2ccd), ('\u{2cce}', 0x2ccf), + ('\u{2cd0}', 0x2cd1), ('\u{2cd2}', 0x2cd3), ('\u{2cd4}', 0x2cd5), ('\u{2cd6}', 0x2cd7), + ('\u{2cd8}', 0x2cd9), ('\u{2cda}', 0x2cdb), ('\u{2cdc}', 0x2cdd), ('\u{2cde}', 0x2cdf), + ('\u{2ce0}', 0x2ce1), ('\u{2ce2}', 0x2ce3), ('\u{2ceb}', 0x2cec), ('\u{2ced}', 0x2cee), + ('\u{2cf2}', 0x2cf3), ('\u{a640}', 0xa641), ('\u{a642}', 0xa643), ('\u{a644}', 0xa645), + ('\u{a646}', 0xa647), ('\u{a648}', 0xa649), ('\u{a64a}', 0xa64b), ('\u{a64c}', 0xa64d), + ('\u{a64e}', 0xa64f), ('\u{a650}', 0xa651), ('\u{a652}', 0xa653), ('\u{a654}', 0xa655), + ('\u{a656}', 0xa657), ('\u{a658}', 0xa659), ('\u{a65a}', 0xa65b), ('\u{a65c}', 0xa65d), + ('\u{a65e}', 0xa65f), ('\u{a660}', 0xa661), ('\u{a662}', 0xa663), ('\u{a664}', 0xa665), + ('\u{a666}', 0xa667), ('\u{a668}', 0xa669), ('\u{a66a}', 0xa66b), ('\u{a66c}', 0xa66d), + ('\u{a680}', 0xa681), ('\u{a682}', 0xa683), ('\u{a684}', 0xa685), ('\u{a686}', 0xa687), + ('\u{a688}', 0xa689), ('\u{a68a}', 0xa68b), ('\u{a68c}', 0xa68d), ('\u{a68e}', 0xa68f), + ('\u{a690}', 0xa691), ('\u{a692}', 0xa693), ('\u{a694}', 0xa695), ('\u{a696}', 0xa697), + ('\u{a698}', 0xa699), ('\u{a69a}', 0xa69b), ('\u{a722}', 0xa723), ('\u{a724}', 0xa725), + ('\u{a726}', 0xa727), ('\u{a728}', 0xa729), ('\u{a72a}', 0xa72b), ('\u{a72c}', 0xa72d), + ('\u{a72e}', 0xa72f), ('\u{a732}', 0xa733), ('\u{a734}', 0xa735), ('\u{a736}', 0xa737), + ('\u{a738}', 0xa739), ('\u{a73a}', 0xa73b), ('\u{a73c}', 0xa73d), ('\u{a73e}', 0xa73f), + ('\u{a740}', 0xa741), ('\u{a742}', 0xa743), ('\u{a744}', 0xa745), ('\u{a746}', 0xa747), + ('\u{a748}', 0xa749), ('\u{a74a}', 0xa74b), ('\u{a74c}', 0xa74d), ('\u{a74e}', 0xa74f), + ('\u{a750}', 0xa751), ('\u{a752}', 0xa753), ('\u{a754}', 0xa755), ('\u{a756}', 0xa757), + ('\u{a758}', 0xa759), ('\u{a75a}', 0xa75b), ('\u{a75c}', 0xa75d), ('\u{a75e}', 0xa75f), + ('\u{a760}', 0xa761), ('\u{a762}', 0xa763), ('\u{a764}', 0xa765), ('\u{a766}', 0xa767), + ('\u{a768}', 0xa769), ('\u{a76a}', 0xa76b), ('\u{a76c}', 0xa76d), ('\u{a76e}', 0xa76f), + ('\u{a779}', 0xa77a), ('\u{a77b}', 0xa77c), ('\u{a77d}', 0x1d79), ('\u{a77e}', 0xa77f), + ('\u{a780}', 0xa781), ('\u{a782}', 0xa783), ('\u{a784}', 0xa785), ('\u{a786}', 0xa787), + ('\u{a78b}', 0xa78c), ('\u{a78d}', 0x265), ('\u{a790}', 0xa791), ('\u{a792}', 0xa793), + ('\u{a796}', 0xa797), ('\u{a798}', 0xa799), ('\u{a79a}', 0xa79b), ('\u{a79c}', 0xa79d), + ('\u{a79e}', 0xa79f), ('\u{a7a0}', 0xa7a1), ('\u{a7a2}', 0xa7a3), ('\u{a7a4}', 0xa7a5), + ('\u{a7a6}', 0xa7a7), ('\u{a7a8}', 0xa7a9), ('\u{a7aa}', 0x266), ('\u{a7ab}', 0x25c), + ('\u{a7ac}', 0x261), ('\u{a7ad}', 0x26c), ('\u{a7ae}', 0x26a), ('\u{a7b0}', 0x29e), + ('\u{a7b1}', 0x287), ('\u{a7b2}', 0x29d), ('\u{a7b3}', 0xab53), ('\u{a7b4}', 0xa7b5), + ('\u{a7b6}', 0xa7b7), ('\u{a7b8}', 0xa7b9), ('\u{a7ba}', 0xa7bb), ('\u{a7bc}', 0xa7bd), + ('\u{a7be}', 0xa7bf), ('\u{a7c0}', 0xa7c1), ('\u{a7c2}', 0xa7c3), ('\u{a7c4}', 0xa794), + ('\u{a7c5}', 0x282), ('\u{a7c6}', 0x1d8e), ('\u{a7c7}', 0xa7c8), ('\u{a7c9}', 0xa7ca), + ('\u{a7cb}', 0x264), ('\u{a7cc}', 0xa7cd), ('\u{a7ce}', 0xa7cf), ('\u{a7d0}', 0xa7d1), + ('\u{a7d2}', 0xa7d3), ('\u{a7d4}', 0xa7d5), ('\u{a7d6}', 0xa7d7), ('\u{a7d8}', 0xa7d9), + ('\u{a7da}', 0xa7db), ('\u{a7dc}', 0x19b), ('\u{a7f5}', 0xa7f6), ('\u{ff21}', 0xff41), + ('\u{ff22}', 0xff42), ('\u{ff23}', 0xff43), ('\u{ff24}', 0xff44), ('\u{ff25}', 0xff45), + ('\u{ff26}', 0xff46), ('\u{ff27}', 0xff47), ('\u{ff28}', 0xff48), ('\u{ff29}', 0xff49), + ('\u{ff2a}', 0xff4a), ('\u{ff2b}', 0xff4b), ('\u{ff2c}', 0xff4c), ('\u{ff2d}', 0xff4d), + ('\u{ff2e}', 0xff4e), ('\u{ff2f}', 0xff4f), ('\u{ff30}', 0xff50), ('\u{ff31}', 0xff51), + ('\u{ff32}', 0xff52), ('\u{ff33}', 0xff53), ('\u{ff34}', 0xff54), ('\u{ff35}', 0xff55), + ('\u{ff36}', 0xff56), ('\u{ff37}', 0xff57), ('\u{ff38}', 0xff58), ('\u{ff39}', 0xff59), + ('\u{ff3a}', 0xff5a), ('\u{10400}', 0x10428), ('\u{10401}', 0x10429), + ('\u{10402}', 0x1042a), ('\u{10403}', 0x1042b), ('\u{10404}', 0x1042c), + ('\u{10405}', 0x1042d), ('\u{10406}', 0x1042e), ('\u{10407}', 0x1042f), + ('\u{10408}', 0x10430), ('\u{10409}', 0x10431), ('\u{1040a}', 0x10432), + ('\u{1040b}', 0x10433), ('\u{1040c}', 0x10434), ('\u{1040d}', 0x10435), + ('\u{1040e}', 0x10436), ('\u{1040f}', 0x10437), ('\u{10410}', 0x10438), + ('\u{10411}', 0x10439), ('\u{10412}', 0x1043a), ('\u{10413}', 0x1043b), + ('\u{10414}', 0x1043c), ('\u{10415}', 0x1043d), ('\u{10416}', 0x1043e), + ('\u{10417}', 0x1043f), ('\u{10418}', 0x10440), ('\u{10419}', 0x10441), + ('\u{1041a}', 0x10442), ('\u{1041b}', 0x10443), ('\u{1041c}', 0x10444), + ('\u{1041d}', 0x10445), ('\u{1041e}', 0x10446), ('\u{1041f}', 0x10447), + ('\u{10420}', 0x10448), ('\u{10421}', 0x10449), ('\u{10422}', 0x1044a), + ('\u{10423}', 0x1044b), ('\u{10424}', 0x1044c), ('\u{10425}', 0x1044d), + ('\u{10426}', 0x1044e), ('\u{10427}', 0x1044f), ('\u{104b0}', 0x104d8), + ('\u{104b1}', 0x104d9), ('\u{104b2}', 0x104da), ('\u{104b3}', 0x104db), + ('\u{104b4}', 0x104dc), ('\u{104b5}', 0x104dd), ('\u{104b6}', 0x104de), + ('\u{104b7}', 0x104df), ('\u{104b8}', 0x104e0), ('\u{104b9}', 0x104e1), + ('\u{104ba}', 0x104e2), ('\u{104bb}', 0x104e3), ('\u{104bc}', 0x104e4), + ('\u{104bd}', 0x104e5), ('\u{104be}', 0x104e6), ('\u{104bf}', 0x104e7), + ('\u{104c0}', 0x104e8), ('\u{104c1}', 0x104e9), ('\u{104c2}', 0x104ea), + ('\u{104c3}', 0x104eb), ('\u{104c4}', 0x104ec), ('\u{104c5}', 0x104ed), + ('\u{104c6}', 0x104ee), ('\u{104c7}', 0x104ef), ('\u{104c8}', 0x104f0), + ('\u{104c9}', 0x104f1), ('\u{104ca}', 0x104f2), ('\u{104cb}', 0x104f3), + ('\u{104cc}', 0x104f4), ('\u{104cd}', 0x104f5), ('\u{104ce}', 0x104f6), + ('\u{104cf}', 0x104f7), ('\u{104d0}', 0x104f8), ('\u{104d1}', 0x104f9), + ('\u{104d2}', 0x104fa), ('\u{104d3}', 0x104fb), ('\u{10570}', 0x10597), + ('\u{10571}', 0x10598), ('\u{10572}', 0x10599), ('\u{10573}', 0x1059a), + ('\u{10574}', 0x1059b), ('\u{10575}', 0x1059c), ('\u{10576}', 0x1059d), + ('\u{10577}', 0x1059e), ('\u{10578}', 0x1059f), ('\u{10579}', 0x105a0), + ('\u{1057a}', 0x105a1), ('\u{1057c}', 0x105a3), ('\u{1057d}', 0x105a4), + ('\u{1057e}', 0x105a5), ('\u{1057f}', 0x105a6), ('\u{10580}', 0x105a7), + ('\u{10581}', 0x105a8), ('\u{10582}', 0x105a9), ('\u{10583}', 0x105aa), + ('\u{10584}', 0x105ab), ('\u{10585}', 0x105ac), ('\u{10586}', 0x105ad), + ('\u{10587}', 0x105ae), ('\u{10588}', 0x105af), ('\u{10589}', 0x105b0), + ('\u{1058a}', 0x105b1), ('\u{1058c}', 0x105b3), ('\u{1058d}', 0x105b4), + ('\u{1058e}', 0x105b5), ('\u{1058f}', 0x105b6), ('\u{10590}', 0x105b7), + ('\u{10591}', 0x105b8), ('\u{10592}', 0x105b9), ('\u{10594}', 0x105bb), + ('\u{10595}', 0x105bc), ('\u{10c80}', 0x10cc0), ('\u{10c81}', 0x10cc1), + ('\u{10c82}', 0x10cc2), ('\u{10c83}', 0x10cc3), ('\u{10c84}', 0x10cc4), + ('\u{10c85}', 0x10cc5), ('\u{10c86}', 0x10cc6), ('\u{10c87}', 0x10cc7), + ('\u{10c88}', 0x10cc8), ('\u{10c89}', 0x10cc9), ('\u{10c8a}', 0x10cca), + ('\u{10c8b}', 0x10ccb), ('\u{10c8c}', 0x10ccc), ('\u{10c8d}', 0x10ccd), + ('\u{10c8e}', 0x10cce), ('\u{10c8f}', 0x10ccf), ('\u{10c90}', 0x10cd0), + ('\u{10c91}', 0x10cd1), ('\u{10c92}', 0x10cd2), ('\u{10c93}', 0x10cd3), + ('\u{10c94}', 0x10cd4), ('\u{10c95}', 0x10cd5), ('\u{10c96}', 0x10cd6), + ('\u{10c97}', 0x10cd7), ('\u{10c98}', 0x10cd8), ('\u{10c99}', 0x10cd9), + ('\u{10c9a}', 0x10cda), ('\u{10c9b}', 0x10cdb), ('\u{10c9c}', 0x10cdc), + ('\u{10c9d}', 0x10cdd), ('\u{10c9e}', 0x10cde), ('\u{10c9f}', 0x10cdf), + ('\u{10ca0}', 0x10ce0), ('\u{10ca1}', 0x10ce1), ('\u{10ca2}', 0x10ce2), + ('\u{10ca3}', 0x10ce3), ('\u{10ca4}', 0x10ce4), ('\u{10ca5}', 0x10ce5), + ('\u{10ca6}', 0x10ce6), ('\u{10ca7}', 0x10ce7), ('\u{10ca8}', 0x10ce8), + ('\u{10ca9}', 0x10ce9), ('\u{10caa}', 0x10cea), ('\u{10cab}', 0x10ceb), + ('\u{10cac}', 0x10cec), ('\u{10cad}', 0x10ced), ('\u{10cae}', 0x10cee), + ('\u{10caf}', 0x10cef), ('\u{10cb0}', 0x10cf0), ('\u{10cb1}', 0x10cf1), + ('\u{10cb2}', 0x10cf2), ('\u{10d50}', 0x10d70), ('\u{10d51}', 0x10d71), + ('\u{10d52}', 0x10d72), ('\u{10d53}', 0x10d73), ('\u{10d54}', 0x10d74), + ('\u{10d55}', 0x10d75), ('\u{10d56}', 0x10d76), ('\u{10d57}', 0x10d77), + ('\u{10d58}', 0x10d78), ('\u{10d59}', 0x10d79), ('\u{10d5a}', 0x10d7a), + ('\u{10d5b}', 0x10d7b), ('\u{10d5c}', 0x10d7c), ('\u{10d5d}', 0x10d7d), + ('\u{10d5e}', 0x10d7e), ('\u{10d5f}', 0x10d7f), ('\u{10d60}', 0x10d80), + ('\u{10d61}', 0x10d81), ('\u{10d62}', 0x10d82), ('\u{10d63}', 0x10d83), + ('\u{10d64}', 0x10d84), ('\u{10d65}', 0x10d85), ('\u{118a0}', 0x118c0), + ('\u{118a1}', 0x118c1), ('\u{118a2}', 0x118c2), ('\u{118a3}', 0x118c3), + ('\u{118a4}', 0x118c4), ('\u{118a5}', 0x118c5), ('\u{118a6}', 0x118c6), + ('\u{118a7}', 0x118c7), ('\u{118a8}', 0x118c8), ('\u{118a9}', 0x118c9), + ('\u{118aa}', 0x118ca), ('\u{118ab}', 0x118cb), ('\u{118ac}', 0x118cc), + ('\u{118ad}', 0x118cd), ('\u{118ae}', 0x118ce), ('\u{118af}', 0x118cf), + ('\u{118b0}', 0x118d0), ('\u{118b1}', 0x118d1), ('\u{118b2}', 0x118d2), + ('\u{118b3}', 0x118d3), ('\u{118b4}', 0x118d4), ('\u{118b5}', 0x118d5), + ('\u{118b6}', 0x118d6), ('\u{118b7}', 0x118d7), ('\u{118b8}', 0x118d8), + ('\u{118b9}', 0x118d9), ('\u{118ba}', 0x118da), ('\u{118bb}', 0x118db), + ('\u{118bc}', 0x118dc), ('\u{118bd}', 0x118dd), ('\u{118be}', 0x118de), + ('\u{118bf}', 0x118df), ('\u{16e40}', 0x16e60), ('\u{16e41}', 0x16e61), + ('\u{16e42}', 0x16e62), ('\u{16e43}', 0x16e63), ('\u{16e44}', 0x16e64), + ('\u{16e45}', 0x16e65), ('\u{16e46}', 0x16e66), ('\u{16e47}', 0x16e67), + ('\u{16e48}', 0x16e68), ('\u{16e49}', 0x16e69), ('\u{16e4a}', 0x16e6a), + ('\u{16e4b}', 0x16e6b), ('\u{16e4c}', 0x16e6c), ('\u{16e4d}', 0x16e6d), + ('\u{16e4e}', 0x16e6e), ('\u{16e4f}', 0x16e6f), ('\u{16e50}', 0x16e70), + ('\u{16e51}', 0x16e71), ('\u{16e52}', 0x16e72), ('\u{16e53}', 0x16e73), + ('\u{16e54}', 0x16e74), ('\u{16e55}', 0x16e75), ('\u{16e56}', 0x16e76), + ('\u{16e57}', 0x16e77), ('\u{16e58}', 0x16e78), ('\u{16e59}', 0x16e79), + ('\u{16e5a}', 0x16e7a), ('\u{16e5b}', 0x16e7b), ('\u{16e5c}', 0x16e7c), + ('\u{16e5d}', 0x16e7d), ('\u{16e5e}', 0x16e7e), ('\u{16e5f}', 0x16e7f), + ('\u{16ea0}', 0x16ebb), ('\u{16ea1}', 0x16ebc), ('\u{16ea2}', 0x16ebd), + ('\u{16ea3}', 0x16ebe), ('\u{16ea4}', 0x16ebf), ('\u{16ea5}', 0x16ec0), + ('\u{16ea6}', 0x16ec1), ('\u{16ea7}', 0x16ec2), ('\u{16ea8}', 0x16ec3), + ('\u{16ea9}', 0x16ec4), ('\u{16eaa}', 0x16ec5), ('\u{16eab}', 0x16ec6), + ('\u{16eac}', 0x16ec7), ('\u{16ead}', 0x16ec8), ('\u{16eae}', 0x16ec9), + ('\u{16eaf}', 0x16eca), ('\u{16eb0}', 0x16ecb), ('\u{16eb1}', 0x16ecc), + ('\u{16eb2}', 0x16ecd), ('\u{16eb3}', 0x16ece), ('\u{16eb4}', 0x16ecf), + ('\u{16eb5}', 0x16ed0), ('\u{16eb6}', 0x16ed1), ('\u{16eb7}', 0x16ed2), + ('\u{16eb8}', 0x16ed3), ('\u{1e900}', 0x1e922), ('\u{1e901}', 0x1e923), + ('\u{1e902}', 0x1e924), ('\u{1e903}', 0x1e925), ('\u{1e904}', 0x1e926), + ('\u{1e905}', 0x1e927), ('\u{1e906}', 0x1e928), ('\u{1e907}', 0x1e929), + ('\u{1e908}', 0x1e92a), ('\u{1e909}', 0x1e92b), ('\u{1e90a}', 0x1e92c), + ('\u{1e90b}', 0x1e92d), ('\u{1e90c}', 0x1e92e), ('\u{1e90d}', 0x1e92f), + ('\u{1e90e}', 0x1e930), ('\u{1e90f}', 0x1e931), ('\u{1e910}', 0x1e932), + ('\u{1e911}', 0x1e933), ('\u{1e912}', 0x1e934), ('\u{1e913}', 0x1e935), + ('\u{1e914}', 0x1e936), ('\u{1e915}', 0x1e937), ('\u{1e916}', 0x1e938), + ('\u{1e917}', 0x1e939), ('\u{1e918}', 0x1e93a), ('\u{1e919}', 0x1e93b), + ('\u{1e91a}', 0x1e93c), ('\u{1e91b}', 0x1e93d), ('\u{1e91c}', 0x1e93e), + ('\u{1e91d}', 0x1e93f), ('\u{1e91e}', 0x1e940), ('\u{1e91f}', 0x1e941), + ('\u{1e920}', 0x1e942), ('\u{1e921}', 0x1e943), + ]; + + #[rustfmt::skip] + static LOWERCASE_TABLE_MULTI: &[[char; 3]; 1] = &[ + ['\u{69}', '\u{307}', '\u{0}'], + ]; + #[inline] pub fn to_lower(c: char) -> [char; 3] { const { @@ -781,367 +1187,483 @@ pub mod conversions { ) } } + #[rustfmt::skip] - 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), - ('\u{cf}', 239), ('\u{d0}', 240), ('\u{d1}', 241), ('\u{d2}', 242), ('\u{d3}', 243), - ('\u{d4}', 244), ('\u{d5}', 245), ('\u{d6}', 246), ('\u{d8}', 248), ('\u{d9}', 249), - ('\u{da}', 250), ('\u{db}', 251), ('\u{dc}', 252), ('\u{dd}', 253), ('\u{de}', 254), - ('\u{100}', 257), ('\u{102}', 259), ('\u{104}', 261), ('\u{106}', 263), ('\u{108}', 265), - ('\u{10a}', 267), ('\u{10c}', 269), ('\u{10e}', 271), ('\u{110}', 273), ('\u{112}', 275), - ('\u{114}', 277), ('\u{116}', 279), ('\u{118}', 281), ('\u{11a}', 283), ('\u{11c}', 285), - ('\u{11e}', 287), ('\u{120}', 289), ('\u{122}', 291), ('\u{124}', 293), ('\u{126}', 295), - ('\u{128}', 297), ('\u{12a}', 299), ('\u{12c}', 301), ('\u{12e}', 303), - ('\u{130}', 4194304), ('\u{132}', 307), ('\u{134}', 309), ('\u{136}', 311), - ('\u{139}', 314), ('\u{13b}', 316), ('\u{13d}', 318), ('\u{13f}', 320), ('\u{141}', 322), - ('\u{143}', 324), ('\u{145}', 326), ('\u{147}', 328), ('\u{14a}', 331), ('\u{14c}', 333), - ('\u{14e}', 335), ('\u{150}', 337), ('\u{152}', 339), ('\u{154}', 341), ('\u{156}', 343), - ('\u{158}', 345), ('\u{15a}', 347), ('\u{15c}', 349), ('\u{15e}', 351), ('\u{160}', 353), - ('\u{162}', 355), ('\u{164}', 357), ('\u{166}', 359), ('\u{168}', 361), ('\u{16a}', 363), - ('\u{16c}', 365), ('\u{16e}', 367), ('\u{170}', 369), ('\u{172}', 371), ('\u{174}', 373), - ('\u{176}', 375), ('\u{178}', 255), ('\u{179}', 378), ('\u{17b}', 380), ('\u{17d}', 382), - ('\u{181}', 595), ('\u{182}', 387), ('\u{184}', 389), ('\u{186}', 596), ('\u{187}', 392), - ('\u{189}', 598), ('\u{18a}', 599), ('\u{18b}', 396), ('\u{18e}', 477), ('\u{18f}', 601), - ('\u{190}', 603), ('\u{191}', 402), ('\u{193}', 608), ('\u{194}', 611), ('\u{196}', 617), - ('\u{197}', 616), ('\u{198}', 409), ('\u{19c}', 623), ('\u{19d}', 626), ('\u{19f}', 629), - ('\u{1a0}', 417), ('\u{1a2}', 419), ('\u{1a4}', 421), ('\u{1a6}', 640), ('\u{1a7}', 424), - ('\u{1a9}', 643), ('\u{1ac}', 429), ('\u{1ae}', 648), ('\u{1af}', 432), ('\u{1b1}', 650), - ('\u{1b2}', 651), ('\u{1b3}', 436), ('\u{1b5}', 438), ('\u{1b7}', 658), ('\u{1b8}', 441), - ('\u{1bc}', 445), ('\u{1c4}', 454), ('\u{1c5}', 454), ('\u{1c7}', 457), ('\u{1c8}', 457), - ('\u{1ca}', 460), ('\u{1cb}', 460), ('\u{1cd}', 462), ('\u{1cf}', 464), ('\u{1d1}', 466), - ('\u{1d3}', 468), ('\u{1d5}', 470), ('\u{1d7}', 472), ('\u{1d9}', 474), ('\u{1db}', 476), - ('\u{1de}', 479), ('\u{1e0}', 481), ('\u{1e2}', 483), ('\u{1e4}', 485), ('\u{1e6}', 487), - ('\u{1e8}', 489), ('\u{1ea}', 491), ('\u{1ec}', 493), ('\u{1ee}', 495), ('\u{1f1}', 499), - ('\u{1f2}', 499), ('\u{1f4}', 501), ('\u{1f6}', 405), ('\u{1f7}', 447), ('\u{1f8}', 505), - ('\u{1fa}', 507), ('\u{1fc}', 509), ('\u{1fe}', 511), ('\u{200}', 513), ('\u{202}', 515), - ('\u{204}', 517), ('\u{206}', 519), ('\u{208}', 521), ('\u{20a}', 523), ('\u{20c}', 525), - ('\u{20e}', 527), ('\u{210}', 529), ('\u{212}', 531), ('\u{214}', 533), ('\u{216}', 535), - ('\u{218}', 537), ('\u{21a}', 539), ('\u{21c}', 541), ('\u{21e}', 543), ('\u{220}', 414), - ('\u{222}', 547), ('\u{224}', 549), ('\u{226}', 551), ('\u{228}', 553), ('\u{22a}', 555), - ('\u{22c}', 557), ('\u{22e}', 559), ('\u{230}', 561), ('\u{232}', 563), ('\u{23a}', 11365), - ('\u{23b}', 572), ('\u{23d}', 410), ('\u{23e}', 11366), ('\u{241}', 578), ('\u{243}', 384), - ('\u{244}', 649), ('\u{245}', 652), ('\u{246}', 583), ('\u{248}', 585), ('\u{24a}', 587), - ('\u{24c}', 589), ('\u{24e}', 591), ('\u{370}', 881), ('\u{372}', 883), ('\u{376}', 887), - ('\u{37f}', 1011), ('\u{386}', 940), ('\u{388}', 941), ('\u{389}', 942), ('\u{38a}', 943), - ('\u{38c}', 972), ('\u{38e}', 973), ('\u{38f}', 974), ('\u{391}', 945), ('\u{392}', 946), - ('\u{393}', 947), ('\u{394}', 948), ('\u{395}', 949), ('\u{396}', 950), ('\u{397}', 951), - ('\u{398}', 952), ('\u{399}', 953), ('\u{39a}', 954), ('\u{39b}', 955), ('\u{39c}', 956), - ('\u{39d}', 957), ('\u{39e}', 958), ('\u{39f}', 959), ('\u{3a0}', 960), ('\u{3a1}', 961), - ('\u{3a3}', 963), ('\u{3a4}', 964), ('\u{3a5}', 965), ('\u{3a6}', 966), ('\u{3a7}', 967), - ('\u{3a8}', 968), ('\u{3a9}', 969), ('\u{3aa}', 970), ('\u{3ab}', 971), ('\u{3cf}', 983), - ('\u{3d8}', 985), ('\u{3da}', 987), ('\u{3dc}', 989), ('\u{3de}', 991), ('\u{3e0}', 993), - ('\u{3e2}', 995), ('\u{3e4}', 997), ('\u{3e6}', 999), ('\u{3e8}', 1001), ('\u{3ea}', 1003), - ('\u{3ec}', 1005), ('\u{3ee}', 1007), ('\u{3f4}', 952), ('\u{3f7}', 1016), - ('\u{3f9}', 1010), ('\u{3fa}', 1019), ('\u{3fd}', 891), ('\u{3fe}', 892), ('\u{3ff}', 893), - ('\u{400}', 1104), ('\u{401}', 1105), ('\u{402}', 1106), ('\u{403}', 1107), - ('\u{404}', 1108), ('\u{405}', 1109), ('\u{406}', 1110), ('\u{407}', 1111), - ('\u{408}', 1112), ('\u{409}', 1113), ('\u{40a}', 1114), ('\u{40b}', 1115), - ('\u{40c}', 1116), ('\u{40d}', 1117), ('\u{40e}', 1118), ('\u{40f}', 1119), - ('\u{410}', 1072), ('\u{411}', 1073), ('\u{412}', 1074), ('\u{413}', 1075), - ('\u{414}', 1076), ('\u{415}', 1077), ('\u{416}', 1078), ('\u{417}', 1079), - ('\u{418}', 1080), ('\u{419}', 1081), ('\u{41a}', 1082), ('\u{41b}', 1083), - ('\u{41c}', 1084), ('\u{41d}', 1085), ('\u{41e}', 1086), ('\u{41f}', 1087), - ('\u{420}', 1088), ('\u{421}', 1089), ('\u{422}', 1090), ('\u{423}', 1091), - ('\u{424}', 1092), ('\u{425}', 1093), ('\u{426}', 1094), ('\u{427}', 1095), - ('\u{428}', 1096), ('\u{429}', 1097), ('\u{42a}', 1098), ('\u{42b}', 1099), - ('\u{42c}', 1100), ('\u{42d}', 1101), ('\u{42e}', 1102), ('\u{42f}', 1103), - ('\u{460}', 1121), ('\u{462}', 1123), ('\u{464}', 1125), ('\u{466}', 1127), - ('\u{468}', 1129), ('\u{46a}', 1131), ('\u{46c}', 1133), ('\u{46e}', 1135), - ('\u{470}', 1137), ('\u{472}', 1139), ('\u{474}', 1141), ('\u{476}', 1143), - ('\u{478}', 1145), ('\u{47a}', 1147), ('\u{47c}', 1149), ('\u{47e}', 1151), - ('\u{480}', 1153), ('\u{48a}', 1163), ('\u{48c}', 1165), ('\u{48e}', 1167), - ('\u{490}', 1169), ('\u{492}', 1171), ('\u{494}', 1173), ('\u{496}', 1175), - ('\u{498}', 1177), ('\u{49a}', 1179), ('\u{49c}', 1181), ('\u{49e}', 1183), - ('\u{4a0}', 1185), ('\u{4a2}', 1187), ('\u{4a4}', 1189), ('\u{4a6}', 1191), - ('\u{4a8}', 1193), ('\u{4aa}', 1195), ('\u{4ac}', 1197), ('\u{4ae}', 1199), - ('\u{4b0}', 1201), ('\u{4b2}', 1203), ('\u{4b4}', 1205), ('\u{4b6}', 1207), - ('\u{4b8}', 1209), ('\u{4ba}', 1211), ('\u{4bc}', 1213), ('\u{4be}', 1215), - ('\u{4c0}', 1231), ('\u{4c1}', 1218), ('\u{4c3}', 1220), ('\u{4c5}', 1222), - ('\u{4c7}', 1224), ('\u{4c9}', 1226), ('\u{4cb}', 1228), ('\u{4cd}', 1230), - ('\u{4d0}', 1233), ('\u{4d2}', 1235), ('\u{4d4}', 1237), ('\u{4d6}', 1239), - ('\u{4d8}', 1241), ('\u{4da}', 1243), ('\u{4dc}', 1245), ('\u{4de}', 1247), - ('\u{4e0}', 1249), ('\u{4e2}', 1251), ('\u{4e4}', 1253), ('\u{4e6}', 1255), - ('\u{4e8}', 1257), ('\u{4ea}', 1259), ('\u{4ec}', 1261), ('\u{4ee}', 1263), - ('\u{4f0}', 1265), ('\u{4f2}', 1267), ('\u{4f4}', 1269), ('\u{4f6}', 1271), - ('\u{4f8}', 1273), ('\u{4fa}', 1275), ('\u{4fc}', 1277), ('\u{4fe}', 1279), - ('\u{500}', 1281), ('\u{502}', 1283), ('\u{504}', 1285), ('\u{506}', 1287), - ('\u{508}', 1289), ('\u{50a}', 1291), ('\u{50c}', 1293), ('\u{50e}', 1295), - ('\u{510}', 1297), ('\u{512}', 1299), ('\u{514}', 1301), ('\u{516}', 1303), - ('\u{518}', 1305), ('\u{51a}', 1307), ('\u{51c}', 1309), ('\u{51e}', 1311), - ('\u{520}', 1313), ('\u{522}', 1315), ('\u{524}', 1317), ('\u{526}', 1319), - ('\u{528}', 1321), ('\u{52a}', 1323), ('\u{52c}', 1325), ('\u{52e}', 1327), - ('\u{531}', 1377), ('\u{532}', 1378), ('\u{533}', 1379), ('\u{534}', 1380), - ('\u{535}', 1381), ('\u{536}', 1382), ('\u{537}', 1383), ('\u{538}', 1384), - ('\u{539}', 1385), ('\u{53a}', 1386), ('\u{53b}', 1387), ('\u{53c}', 1388), - ('\u{53d}', 1389), ('\u{53e}', 1390), ('\u{53f}', 1391), ('\u{540}', 1392), - ('\u{541}', 1393), ('\u{542}', 1394), ('\u{543}', 1395), ('\u{544}', 1396), - ('\u{545}', 1397), ('\u{546}', 1398), ('\u{547}', 1399), ('\u{548}', 1400), - ('\u{549}', 1401), ('\u{54a}', 1402), ('\u{54b}', 1403), ('\u{54c}', 1404), - ('\u{54d}', 1405), ('\u{54e}', 1406), ('\u{54f}', 1407), ('\u{550}', 1408), - ('\u{551}', 1409), ('\u{552}', 1410), ('\u{553}', 1411), ('\u{554}', 1412), - ('\u{555}', 1413), ('\u{556}', 1414), ('\u{10a0}', 11520), ('\u{10a1}', 11521), - ('\u{10a2}', 11522), ('\u{10a3}', 11523), ('\u{10a4}', 11524), ('\u{10a5}', 11525), - ('\u{10a6}', 11526), ('\u{10a7}', 11527), ('\u{10a8}', 11528), ('\u{10a9}', 11529), - ('\u{10aa}', 11530), ('\u{10ab}', 11531), ('\u{10ac}', 11532), ('\u{10ad}', 11533), - ('\u{10ae}', 11534), ('\u{10af}', 11535), ('\u{10b0}', 11536), ('\u{10b1}', 11537), - ('\u{10b2}', 11538), ('\u{10b3}', 11539), ('\u{10b4}', 11540), ('\u{10b5}', 11541), - ('\u{10b6}', 11542), ('\u{10b7}', 11543), ('\u{10b8}', 11544), ('\u{10b9}', 11545), - ('\u{10ba}', 11546), ('\u{10bb}', 11547), ('\u{10bc}', 11548), ('\u{10bd}', 11549), - ('\u{10be}', 11550), ('\u{10bf}', 11551), ('\u{10c0}', 11552), ('\u{10c1}', 11553), - ('\u{10c2}', 11554), ('\u{10c3}', 11555), ('\u{10c4}', 11556), ('\u{10c5}', 11557), - ('\u{10c7}', 11559), ('\u{10cd}', 11565), ('\u{13a0}', 43888), ('\u{13a1}', 43889), - ('\u{13a2}', 43890), ('\u{13a3}', 43891), ('\u{13a4}', 43892), ('\u{13a5}', 43893), - ('\u{13a6}', 43894), ('\u{13a7}', 43895), ('\u{13a8}', 43896), ('\u{13a9}', 43897), - ('\u{13aa}', 43898), ('\u{13ab}', 43899), ('\u{13ac}', 43900), ('\u{13ad}', 43901), - ('\u{13ae}', 43902), ('\u{13af}', 43903), ('\u{13b0}', 43904), ('\u{13b1}', 43905), - ('\u{13b2}', 43906), ('\u{13b3}', 43907), ('\u{13b4}', 43908), ('\u{13b5}', 43909), - ('\u{13b6}', 43910), ('\u{13b7}', 43911), ('\u{13b8}', 43912), ('\u{13b9}', 43913), - ('\u{13ba}', 43914), ('\u{13bb}', 43915), ('\u{13bc}', 43916), ('\u{13bd}', 43917), - ('\u{13be}', 43918), ('\u{13bf}', 43919), ('\u{13c0}', 43920), ('\u{13c1}', 43921), - ('\u{13c2}', 43922), ('\u{13c3}', 43923), ('\u{13c4}', 43924), ('\u{13c5}', 43925), - ('\u{13c6}', 43926), ('\u{13c7}', 43927), ('\u{13c8}', 43928), ('\u{13c9}', 43929), - ('\u{13ca}', 43930), ('\u{13cb}', 43931), ('\u{13cc}', 43932), ('\u{13cd}', 43933), - ('\u{13ce}', 43934), ('\u{13cf}', 43935), ('\u{13d0}', 43936), ('\u{13d1}', 43937), - ('\u{13d2}', 43938), ('\u{13d3}', 43939), ('\u{13d4}', 43940), ('\u{13d5}', 43941), - ('\u{13d6}', 43942), ('\u{13d7}', 43943), ('\u{13d8}', 43944), ('\u{13d9}', 43945), - ('\u{13da}', 43946), ('\u{13db}', 43947), ('\u{13dc}', 43948), ('\u{13dd}', 43949), - ('\u{13de}', 43950), ('\u{13df}', 43951), ('\u{13e0}', 43952), ('\u{13e1}', 43953), - ('\u{13e2}', 43954), ('\u{13e3}', 43955), ('\u{13e4}', 43956), ('\u{13e5}', 43957), - ('\u{13e6}', 43958), ('\u{13e7}', 43959), ('\u{13e8}', 43960), ('\u{13e9}', 43961), - ('\u{13ea}', 43962), ('\u{13eb}', 43963), ('\u{13ec}', 43964), ('\u{13ed}', 43965), - ('\u{13ee}', 43966), ('\u{13ef}', 43967), ('\u{13f0}', 5112), ('\u{13f1}', 5113), - ('\u{13f2}', 5114), ('\u{13f3}', 5115), ('\u{13f4}', 5116), ('\u{13f5}', 5117), - ('\u{1c89}', 7306), ('\u{1c90}', 4304), ('\u{1c91}', 4305), ('\u{1c92}', 4306), - ('\u{1c93}', 4307), ('\u{1c94}', 4308), ('\u{1c95}', 4309), ('\u{1c96}', 4310), - ('\u{1c97}', 4311), ('\u{1c98}', 4312), ('\u{1c99}', 4313), ('\u{1c9a}', 4314), - ('\u{1c9b}', 4315), ('\u{1c9c}', 4316), ('\u{1c9d}', 4317), ('\u{1c9e}', 4318), - ('\u{1c9f}', 4319), ('\u{1ca0}', 4320), ('\u{1ca1}', 4321), ('\u{1ca2}', 4322), - ('\u{1ca3}', 4323), ('\u{1ca4}', 4324), ('\u{1ca5}', 4325), ('\u{1ca6}', 4326), - ('\u{1ca7}', 4327), ('\u{1ca8}', 4328), ('\u{1ca9}', 4329), ('\u{1caa}', 4330), - ('\u{1cab}', 4331), ('\u{1cac}', 4332), ('\u{1cad}', 4333), ('\u{1cae}', 4334), - ('\u{1caf}', 4335), ('\u{1cb0}', 4336), ('\u{1cb1}', 4337), ('\u{1cb2}', 4338), - ('\u{1cb3}', 4339), ('\u{1cb4}', 4340), ('\u{1cb5}', 4341), ('\u{1cb6}', 4342), - ('\u{1cb7}', 4343), ('\u{1cb8}', 4344), ('\u{1cb9}', 4345), ('\u{1cba}', 4346), - ('\u{1cbd}', 4349), ('\u{1cbe}', 4350), ('\u{1cbf}', 4351), ('\u{1e00}', 7681), - ('\u{1e02}', 7683), ('\u{1e04}', 7685), ('\u{1e06}', 7687), ('\u{1e08}', 7689), - ('\u{1e0a}', 7691), ('\u{1e0c}', 7693), ('\u{1e0e}', 7695), ('\u{1e10}', 7697), - ('\u{1e12}', 7699), ('\u{1e14}', 7701), ('\u{1e16}', 7703), ('\u{1e18}', 7705), - ('\u{1e1a}', 7707), ('\u{1e1c}', 7709), ('\u{1e1e}', 7711), ('\u{1e20}', 7713), - ('\u{1e22}', 7715), ('\u{1e24}', 7717), ('\u{1e26}', 7719), ('\u{1e28}', 7721), - ('\u{1e2a}', 7723), ('\u{1e2c}', 7725), ('\u{1e2e}', 7727), ('\u{1e30}', 7729), - ('\u{1e32}', 7731), ('\u{1e34}', 7733), ('\u{1e36}', 7735), ('\u{1e38}', 7737), - ('\u{1e3a}', 7739), ('\u{1e3c}', 7741), ('\u{1e3e}', 7743), ('\u{1e40}', 7745), - ('\u{1e42}', 7747), ('\u{1e44}', 7749), ('\u{1e46}', 7751), ('\u{1e48}', 7753), - ('\u{1e4a}', 7755), ('\u{1e4c}', 7757), ('\u{1e4e}', 7759), ('\u{1e50}', 7761), - ('\u{1e52}', 7763), ('\u{1e54}', 7765), ('\u{1e56}', 7767), ('\u{1e58}', 7769), - ('\u{1e5a}', 7771), ('\u{1e5c}', 7773), ('\u{1e5e}', 7775), ('\u{1e60}', 7777), - ('\u{1e62}', 7779), ('\u{1e64}', 7781), ('\u{1e66}', 7783), ('\u{1e68}', 7785), - ('\u{1e6a}', 7787), ('\u{1e6c}', 7789), ('\u{1e6e}', 7791), ('\u{1e70}', 7793), - ('\u{1e72}', 7795), ('\u{1e74}', 7797), ('\u{1e76}', 7799), ('\u{1e78}', 7801), - ('\u{1e7a}', 7803), ('\u{1e7c}', 7805), ('\u{1e7e}', 7807), ('\u{1e80}', 7809), - ('\u{1e82}', 7811), ('\u{1e84}', 7813), ('\u{1e86}', 7815), ('\u{1e88}', 7817), - ('\u{1e8a}', 7819), ('\u{1e8c}', 7821), ('\u{1e8e}', 7823), ('\u{1e90}', 7825), - ('\u{1e92}', 7827), ('\u{1e94}', 7829), ('\u{1e9e}', 223), ('\u{1ea0}', 7841), - ('\u{1ea2}', 7843), ('\u{1ea4}', 7845), ('\u{1ea6}', 7847), ('\u{1ea8}', 7849), - ('\u{1eaa}', 7851), ('\u{1eac}', 7853), ('\u{1eae}', 7855), ('\u{1eb0}', 7857), - ('\u{1eb2}', 7859), ('\u{1eb4}', 7861), ('\u{1eb6}', 7863), ('\u{1eb8}', 7865), - ('\u{1eba}', 7867), ('\u{1ebc}', 7869), ('\u{1ebe}', 7871), ('\u{1ec0}', 7873), - ('\u{1ec2}', 7875), ('\u{1ec4}', 7877), ('\u{1ec6}', 7879), ('\u{1ec8}', 7881), - ('\u{1eca}', 7883), ('\u{1ecc}', 7885), ('\u{1ece}', 7887), ('\u{1ed0}', 7889), - ('\u{1ed2}', 7891), ('\u{1ed4}', 7893), ('\u{1ed6}', 7895), ('\u{1ed8}', 7897), - ('\u{1eda}', 7899), ('\u{1edc}', 7901), ('\u{1ede}', 7903), ('\u{1ee0}', 7905), - ('\u{1ee2}', 7907), ('\u{1ee4}', 7909), ('\u{1ee6}', 7911), ('\u{1ee8}', 7913), - ('\u{1eea}', 7915), ('\u{1eec}', 7917), ('\u{1eee}', 7919), ('\u{1ef0}', 7921), - ('\u{1ef2}', 7923), ('\u{1ef4}', 7925), ('\u{1ef6}', 7927), ('\u{1ef8}', 7929), - ('\u{1efa}', 7931), ('\u{1efc}', 7933), ('\u{1efe}', 7935), ('\u{1f08}', 7936), - ('\u{1f09}', 7937), ('\u{1f0a}', 7938), ('\u{1f0b}', 7939), ('\u{1f0c}', 7940), - ('\u{1f0d}', 7941), ('\u{1f0e}', 7942), ('\u{1f0f}', 7943), ('\u{1f18}', 7952), - ('\u{1f19}', 7953), ('\u{1f1a}', 7954), ('\u{1f1b}', 7955), ('\u{1f1c}', 7956), - ('\u{1f1d}', 7957), ('\u{1f28}', 7968), ('\u{1f29}', 7969), ('\u{1f2a}', 7970), - ('\u{1f2b}', 7971), ('\u{1f2c}', 7972), ('\u{1f2d}', 7973), ('\u{1f2e}', 7974), - ('\u{1f2f}', 7975), ('\u{1f38}', 7984), ('\u{1f39}', 7985), ('\u{1f3a}', 7986), - ('\u{1f3b}', 7987), ('\u{1f3c}', 7988), ('\u{1f3d}', 7989), ('\u{1f3e}', 7990), - ('\u{1f3f}', 7991), ('\u{1f48}', 8000), ('\u{1f49}', 8001), ('\u{1f4a}', 8002), - ('\u{1f4b}', 8003), ('\u{1f4c}', 8004), ('\u{1f4d}', 8005), ('\u{1f59}', 8017), - ('\u{1f5b}', 8019), ('\u{1f5d}', 8021), ('\u{1f5f}', 8023), ('\u{1f68}', 8032), - ('\u{1f69}', 8033), ('\u{1f6a}', 8034), ('\u{1f6b}', 8035), ('\u{1f6c}', 8036), - ('\u{1f6d}', 8037), ('\u{1f6e}', 8038), ('\u{1f6f}', 8039), ('\u{1f88}', 8064), - ('\u{1f89}', 8065), ('\u{1f8a}', 8066), ('\u{1f8b}', 8067), ('\u{1f8c}', 8068), - ('\u{1f8d}', 8069), ('\u{1f8e}', 8070), ('\u{1f8f}', 8071), ('\u{1f98}', 8080), - ('\u{1f99}', 8081), ('\u{1f9a}', 8082), ('\u{1f9b}', 8083), ('\u{1f9c}', 8084), - ('\u{1f9d}', 8085), ('\u{1f9e}', 8086), ('\u{1f9f}', 8087), ('\u{1fa8}', 8096), - ('\u{1fa9}', 8097), ('\u{1faa}', 8098), ('\u{1fab}', 8099), ('\u{1fac}', 8100), - ('\u{1fad}', 8101), ('\u{1fae}', 8102), ('\u{1faf}', 8103), ('\u{1fb8}', 8112), - ('\u{1fb9}', 8113), ('\u{1fba}', 8048), ('\u{1fbb}', 8049), ('\u{1fbc}', 8115), - ('\u{1fc8}', 8050), ('\u{1fc9}', 8051), ('\u{1fca}', 8052), ('\u{1fcb}', 8053), - ('\u{1fcc}', 8131), ('\u{1fd8}', 8144), ('\u{1fd9}', 8145), ('\u{1fda}', 8054), - ('\u{1fdb}', 8055), ('\u{1fe8}', 8160), ('\u{1fe9}', 8161), ('\u{1fea}', 8058), - ('\u{1feb}', 8059), ('\u{1fec}', 8165), ('\u{1ff8}', 8056), ('\u{1ff9}', 8057), - ('\u{1ffa}', 8060), ('\u{1ffb}', 8061), ('\u{1ffc}', 8179), ('\u{2126}', 969), - ('\u{212a}', 107), ('\u{212b}', 229), ('\u{2132}', 8526), ('\u{2160}', 8560), - ('\u{2161}', 8561), ('\u{2162}', 8562), ('\u{2163}', 8563), ('\u{2164}', 8564), - ('\u{2165}', 8565), ('\u{2166}', 8566), ('\u{2167}', 8567), ('\u{2168}', 8568), - ('\u{2169}', 8569), ('\u{216a}', 8570), ('\u{216b}', 8571), ('\u{216c}', 8572), - ('\u{216d}', 8573), ('\u{216e}', 8574), ('\u{216f}', 8575), ('\u{2183}', 8580), - ('\u{24b6}', 9424), ('\u{24b7}', 9425), ('\u{24b8}', 9426), ('\u{24b9}', 9427), - ('\u{24ba}', 9428), ('\u{24bb}', 9429), ('\u{24bc}', 9430), ('\u{24bd}', 9431), - ('\u{24be}', 9432), ('\u{24bf}', 9433), ('\u{24c0}', 9434), ('\u{24c1}', 9435), - ('\u{24c2}', 9436), ('\u{24c3}', 9437), ('\u{24c4}', 9438), ('\u{24c5}', 9439), - ('\u{24c6}', 9440), ('\u{24c7}', 9441), ('\u{24c8}', 9442), ('\u{24c9}', 9443), - ('\u{24ca}', 9444), ('\u{24cb}', 9445), ('\u{24cc}', 9446), ('\u{24cd}', 9447), - ('\u{24ce}', 9448), ('\u{24cf}', 9449), ('\u{2c00}', 11312), ('\u{2c01}', 11313), - ('\u{2c02}', 11314), ('\u{2c03}', 11315), ('\u{2c04}', 11316), ('\u{2c05}', 11317), - ('\u{2c06}', 11318), ('\u{2c07}', 11319), ('\u{2c08}', 11320), ('\u{2c09}', 11321), - ('\u{2c0a}', 11322), ('\u{2c0b}', 11323), ('\u{2c0c}', 11324), ('\u{2c0d}', 11325), - ('\u{2c0e}', 11326), ('\u{2c0f}', 11327), ('\u{2c10}', 11328), ('\u{2c11}', 11329), - ('\u{2c12}', 11330), ('\u{2c13}', 11331), ('\u{2c14}', 11332), ('\u{2c15}', 11333), - ('\u{2c16}', 11334), ('\u{2c17}', 11335), ('\u{2c18}', 11336), ('\u{2c19}', 11337), - ('\u{2c1a}', 11338), ('\u{2c1b}', 11339), ('\u{2c1c}', 11340), ('\u{2c1d}', 11341), - ('\u{2c1e}', 11342), ('\u{2c1f}', 11343), ('\u{2c20}', 11344), ('\u{2c21}', 11345), - ('\u{2c22}', 11346), ('\u{2c23}', 11347), ('\u{2c24}', 11348), ('\u{2c25}', 11349), - ('\u{2c26}', 11350), ('\u{2c27}', 11351), ('\u{2c28}', 11352), ('\u{2c29}', 11353), - ('\u{2c2a}', 11354), ('\u{2c2b}', 11355), ('\u{2c2c}', 11356), ('\u{2c2d}', 11357), - ('\u{2c2e}', 11358), ('\u{2c2f}', 11359), ('\u{2c60}', 11361), ('\u{2c62}', 619), - ('\u{2c63}', 7549), ('\u{2c64}', 637), ('\u{2c67}', 11368), ('\u{2c69}', 11370), - ('\u{2c6b}', 11372), ('\u{2c6d}', 593), ('\u{2c6e}', 625), ('\u{2c6f}', 592), - ('\u{2c70}', 594), ('\u{2c72}', 11379), ('\u{2c75}', 11382), ('\u{2c7e}', 575), - ('\u{2c7f}', 576), ('\u{2c80}', 11393), ('\u{2c82}', 11395), ('\u{2c84}', 11397), - ('\u{2c86}', 11399), ('\u{2c88}', 11401), ('\u{2c8a}', 11403), ('\u{2c8c}', 11405), - ('\u{2c8e}', 11407), ('\u{2c90}', 11409), ('\u{2c92}', 11411), ('\u{2c94}', 11413), - ('\u{2c96}', 11415), ('\u{2c98}', 11417), ('\u{2c9a}', 11419), ('\u{2c9c}', 11421), - ('\u{2c9e}', 11423), ('\u{2ca0}', 11425), ('\u{2ca2}', 11427), ('\u{2ca4}', 11429), - ('\u{2ca6}', 11431), ('\u{2ca8}', 11433), ('\u{2caa}', 11435), ('\u{2cac}', 11437), - ('\u{2cae}', 11439), ('\u{2cb0}', 11441), ('\u{2cb2}', 11443), ('\u{2cb4}', 11445), - ('\u{2cb6}', 11447), ('\u{2cb8}', 11449), ('\u{2cba}', 11451), ('\u{2cbc}', 11453), - ('\u{2cbe}', 11455), ('\u{2cc0}', 11457), ('\u{2cc2}', 11459), ('\u{2cc4}', 11461), - ('\u{2cc6}', 11463), ('\u{2cc8}', 11465), ('\u{2cca}', 11467), ('\u{2ccc}', 11469), - ('\u{2cce}', 11471), ('\u{2cd0}', 11473), ('\u{2cd2}', 11475), ('\u{2cd4}', 11477), - ('\u{2cd6}', 11479), ('\u{2cd8}', 11481), ('\u{2cda}', 11483), ('\u{2cdc}', 11485), - ('\u{2cde}', 11487), ('\u{2ce0}', 11489), ('\u{2ce2}', 11491), ('\u{2ceb}', 11500), - ('\u{2ced}', 11502), ('\u{2cf2}', 11507), ('\u{a640}', 42561), ('\u{a642}', 42563), - ('\u{a644}', 42565), ('\u{a646}', 42567), ('\u{a648}', 42569), ('\u{a64a}', 42571), - ('\u{a64c}', 42573), ('\u{a64e}', 42575), ('\u{a650}', 42577), ('\u{a652}', 42579), - ('\u{a654}', 42581), ('\u{a656}', 42583), ('\u{a658}', 42585), ('\u{a65a}', 42587), - ('\u{a65c}', 42589), ('\u{a65e}', 42591), ('\u{a660}', 42593), ('\u{a662}', 42595), - ('\u{a664}', 42597), ('\u{a666}', 42599), ('\u{a668}', 42601), ('\u{a66a}', 42603), - ('\u{a66c}', 42605), ('\u{a680}', 42625), ('\u{a682}', 42627), ('\u{a684}', 42629), - ('\u{a686}', 42631), ('\u{a688}', 42633), ('\u{a68a}', 42635), ('\u{a68c}', 42637), - ('\u{a68e}', 42639), ('\u{a690}', 42641), ('\u{a692}', 42643), ('\u{a694}', 42645), - ('\u{a696}', 42647), ('\u{a698}', 42649), ('\u{a69a}', 42651), ('\u{a722}', 42787), - ('\u{a724}', 42789), ('\u{a726}', 42791), ('\u{a728}', 42793), ('\u{a72a}', 42795), - ('\u{a72c}', 42797), ('\u{a72e}', 42799), ('\u{a732}', 42803), ('\u{a734}', 42805), - ('\u{a736}', 42807), ('\u{a738}', 42809), ('\u{a73a}', 42811), ('\u{a73c}', 42813), - ('\u{a73e}', 42815), ('\u{a740}', 42817), ('\u{a742}', 42819), ('\u{a744}', 42821), - ('\u{a746}', 42823), ('\u{a748}', 42825), ('\u{a74a}', 42827), ('\u{a74c}', 42829), - ('\u{a74e}', 42831), ('\u{a750}', 42833), ('\u{a752}', 42835), ('\u{a754}', 42837), - ('\u{a756}', 42839), ('\u{a758}', 42841), ('\u{a75a}', 42843), ('\u{a75c}', 42845), - ('\u{a75e}', 42847), ('\u{a760}', 42849), ('\u{a762}', 42851), ('\u{a764}', 42853), - ('\u{a766}', 42855), ('\u{a768}', 42857), ('\u{a76a}', 42859), ('\u{a76c}', 42861), - ('\u{a76e}', 42863), ('\u{a779}', 42874), ('\u{a77b}', 42876), ('\u{a77d}', 7545), - ('\u{a77e}', 42879), ('\u{a780}', 42881), ('\u{a782}', 42883), ('\u{a784}', 42885), - ('\u{a786}', 42887), ('\u{a78b}', 42892), ('\u{a78d}', 613), ('\u{a790}', 42897), - ('\u{a792}', 42899), ('\u{a796}', 42903), ('\u{a798}', 42905), ('\u{a79a}', 42907), - ('\u{a79c}', 42909), ('\u{a79e}', 42911), ('\u{a7a0}', 42913), ('\u{a7a2}', 42915), - ('\u{a7a4}', 42917), ('\u{a7a6}', 42919), ('\u{a7a8}', 42921), ('\u{a7aa}', 614), - ('\u{a7ab}', 604), ('\u{a7ac}', 609), ('\u{a7ad}', 620), ('\u{a7ae}', 618), - ('\u{a7b0}', 670), ('\u{a7b1}', 647), ('\u{a7b2}', 669), ('\u{a7b3}', 43859), - ('\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{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), - ('\u{1e90d}', 125231), ('\u{1e90e}', 125232), ('\u{1e90f}', 125233), ('\u{1e910}', 125234), - ('\u{1e911}', 125235), ('\u{1e912}', 125236), ('\u{1e913}', 125237), ('\u{1e914}', 125238), - ('\u{1e915}', 125239), ('\u{1e916}', 125240), ('\u{1e917}', 125241), ('\u{1e918}', 125242), - ('\u{1e919}', 125243), ('\u{1e91a}', 125244), ('\u{1e91b}', 125245), ('\u{1e91c}', 125246), - ('\u{1e91d}', 125247), ('\u{1e91e}', 125248), ('\u{1e91f}', 125249), ('\u{1e920}', 125250), - ('\u{1e921}', 125251), + static UPPERCASE_TABLE: &[(char, u32); 1554] = &[ + ('\u{b5}', 0x39c), ('\u{df}', 0x400000), ('\u{e0}', 0xc0), ('\u{e1}', 0xc1), + ('\u{e2}', 0xc2), ('\u{e3}', 0xc3), ('\u{e4}', 0xc4), ('\u{e5}', 0xc5), ('\u{e6}', 0xc6), + ('\u{e7}', 0xc7), ('\u{e8}', 0xc8), ('\u{e9}', 0xc9), ('\u{ea}', 0xca), ('\u{eb}', 0xcb), + ('\u{ec}', 0xcc), ('\u{ed}', 0xcd), ('\u{ee}', 0xce), ('\u{ef}', 0xcf), ('\u{f0}', 0xd0), + ('\u{f1}', 0xd1), ('\u{f2}', 0xd2), ('\u{f3}', 0xd3), ('\u{f4}', 0xd4), ('\u{f5}', 0xd5), + ('\u{f6}', 0xd6), ('\u{f8}', 0xd8), ('\u{f9}', 0xd9), ('\u{fa}', 0xda), ('\u{fb}', 0xdb), + ('\u{fc}', 0xdc), ('\u{fd}', 0xdd), ('\u{fe}', 0xde), ('\u{ff}', 0x178), ('\u{101}', 0x100), + ('\u{103}', 0x102), ('\u{105}', 0x104), ('\u{107}', 0x106), ('\u{109}', 0x108), + ('\u{10b}', 0x10a), ('\u{10d}', 0x10c), ('\u{10f}', 0x10e), ('\u{111}', 0x110), + ('\u{113}', 0x112), ('\u{115}', 0x114), ('\u{117}', 0x116), ('\u{119}', 0x118), + ('\u{11b}', 0x11a), ('\u{11d}', 0x11c), ('\u{11f}', 0x11e), ('\u{121}', 0x120), + ('\u{123}', 0x122), ('\u{125}', 0x124), ('\u{127}', 0x126), ('\u{129}', 0x128), + ('\u{12b}', 0x12a), ('\u{12d}', 0x12c), ('\u{12f}', 0x12e), ('\u{131}', 0x49), + ('\u{133}', 0x132), ('\u{135}', 0x134), ('\u{137}', 0x136), ('\u{13a}', 0x139), + ('\u{13c}', 0x13b), ('\u{13e}', 0x13d), ('\u{140}', 0x13f), ('\u{142}', 0x141), + ('\u{144}', 0x143), ('\u{146}', 0x145), ('\u{148}', 0x147), ('\u{149}', 0x400001), + ('\u{14b}', 0x14a), ('\u{14d}', 0x14c), ('\u{14f}', 0x14e), ('\u{151}', 0x150), + ('\u{153}', 0x152), ('\u{155}', 0x154), ('\u{157}', 0x156), ('\u{159}', 0x158), + ('\u{15b}', 0x15a), ('\u{15d}', 0x15c), ('\u{15f}', 0x15e), ('\u{161}', 0x160), + ('\u{163}', 0x162), ('\u{165}', 0x164), ('\u{167}', 0x166), ('\u{169}', 0x168), + ('\u{16b}', 0x16a), ('\u{16d}', 0x16c), ('\u{16f}', 0x16e), ('\u{171}', 0x170), + ('\u{173}', 0x172), ('\u{175}', 0x174), ('\u{177}', 0x176), ('\u{17a}', 0x179), + ('\u{17c}', 0x17b), ('\u{17e}', 0x17d), ('\u{17f}', 0x53), ('\u{180}', 0x243), + ('\u{183}', 0x182), ('\u{185}', 0x184), ('\u{188}', 0x187), ('\u{18c}', 0x18b), + ('\u{192}', 0x191), ('\u{195}', 0x1f6), ('\u{199}', 0x198), ('\u{19a}', 0x23d), + ('\u{19b}', 0xa7dc), ('\u{19e}', 0x220), ('\u{1a1}', 0x1a0), ('\u{1a3}', 0x1a2), + ('\u{1a5}', 0x1a4), ('\u{1a8}', 0x1a7), ('\u{1ad}', 0x1ac), ('\u{1b0}', 0x1af), + ('\u{1b4}', 0x1b3), ('\u{1b6}', 0x1b5), ('\u{1b9}', 0x1b8), ('\u{1bd}', 0x1bc), + ('\u{1bf}', 0x1f7), ('\u{1c5}', 0x1c4), ('\u{1c6}', 0x1c4), ('\u{1c8}', 0x1c7), + ('\u{1c9}', 0x1c7), ('\u{1cb}', 0x1ca), ('\u{1cc}', 0x1ca), ('\u{1ce}', 0x1cd), + ('\u{1d0}', 0x1cf), ('\u{1d2}', 0x1d1), ('\u{1d4}', 0x1d3), ('\u{1d6}', 0x1d5), + ('\u{1d8}', 0x1d7), ('\u{1da}', 0x1d9), ('\u{1dc}', 0x1db), ('\u{1dd}', 0x18e), + ('\u{1df}', 0x1de), ('\u{1e1}', 0x1e0), ('\u{1e3}', 0x1e2), ('\u{1e5}', 0x1e4), + ('\u{1e7}', 0x1e6), ('\u{1e9}', 0x1e8), ('\u{1eb}', 0x1ea), ('\u{1ed}', 0x1ec), + ('\u{1ef}', 0x1ee), ('\u{1f0}', 0x400002), ('\u{1f2}', 0x1f1), ('\u{1f3}', 0x1f1), + ('\u{1f5}', 0x1f4), ('\u{1f9}', 0x1f8), ('\u{1fb}', 0x1fa), ('\u{1fd}', 0x1fc), + ('\u{1ff}', 0x1fe), ('\u{201}', 0x200), ('\u{203}', 0x202), ('\u{205}', 0x204), + ('\u{207}', 0x206), ('\u{209}', 0x208), ('\u{20b}', 0x20a), ('\u{20d}', 0x20c), + ('\u{20f}', 0x20e), ('\u{211}', 0x210), ('\u{213}', 0x212), ('\u{215}', 0x214), + ('\u{217}', 0x216), ('\u{219}', 0x218), ('\u{21b}', 0x21a), ('\u{21d}', 0x21c), + ('\u{21f}', 0x21e), ('\u{223}', 0x222), ('\u{225}', 0x224), ('\u{227}', 0x226), + ('\u{229}', 0x228), ('\u{22b}', 0x22a), ('\u{22d}', 0x22c), ('\u{22f}', 0x22e), + ('\u{231}', 0x230), ('\u{233}', 0x232), ('\u{23c}', 0x23b), ('\u{23f}', 0x2c7e), + ('\u{240}', 0x2c7f), ('\u{242}', 0x241), ('\u{247}', 0x246), ('\u{249}', 0x248), + ('\u{24b}', 0x24a), ('\u{24d}', 0x24c), ('\u{24f}', 0x24e), ('\u{250}', 0x2c6f), + ('\u{251}', 0x2c6d), ('\u{252}', 0x2c70), ('\u{253}', 0x181), ('\u{254}', 0x186), + ('\u{256}', 0x189), ('\u{257}', 0x18a), ('\u{259}', 0x18f), ('\u{25b}', 0x190), + ('\u{25c}', 0xa7ab), ('\u{260}', 0x193), ('\u{261}', 0xa7ac), ('\u{263}', 0x194), + ('\u{264}', 0xa7cb), ('\u{265}', 0xa78d), ('\u{266}', 0xa7aa), ('\u{268}', 0x197), + ('\u{269}', 0x196), ('\u{26a}', 0xa7ae), ('\u{26b}', 0x2c62), ('\u{26c}', 0xa7ad), + ('\u{26f}', 0x19c), ('\u{271}', 0x2c6e), ('\u{272}', 0x19d), ('\u{275}', 0x19f), + ('\u{27d}', 0x2c64), ('\u{280}', 0x1a6), ('\u{282}', 0xa7c5), ('\u{283}', 0x1a9), + ('\u{287}', 0xa7b1), ('\u{288}', 0x1ae), ('\u{289}', 0x244), ('\u{28a}', 0x1b1), + ('\u{28b}', 0x1b2), ('\u{28c}', 0x245), ('\u{292}', 0x1b7), ('\u{29d}', 0xa7b2), + ('\u{29e}', 0xa7b0), ('\u{345}', 0x399), ('\u{371}', 0x370), ('\u{373}', 0x372), + ('\u{377}', 0x376), ('\u{37b}', 0x3fd), ('\u{37c}', 0x3fe), ('\u{37d}', 0x3ff), + ('\u{390}', 0x400003), ('\u{3ac}', 0x386), ('\u{3ad}', 0x388), ('\u{3ae}', 0x389), + ('\u{3af}', 0x38a), ('\u{3b0}', 0x400004), ('\u{3b1}', 0x391), ('\u{3b2}', 0x392), + ('\u{3b3}', 0x393), ('\u{3b4}', 0x394), ('\u{3b5}', 0x395), ('\u{3b6}', 0x396), + ('\u{3b7}', 0x397), ('\u{3b8}', 0x398), ('\u{3b9}', 0x399), ('\u{3ba}', 0x39a), + ('\u{3bb}', 0x39b), ('\u{3bc}', 0x39c), ('\u{3bd}', 0x39d), ('\u{3be}', 0x39e), + ('\u{3bf}', 0x39f), ('\u{3c0}', 0x3a0), ('\u{3c1}', 0x3a1), ('\u{3c2}', 0x3a3), + ('\u{3c3}', 0x3a3), ('\u{3c4}', 0x3a4), ('\u{3c5}', 0x3a5), ('\u{3c6}', 0x3a6), + ('\u{3c7}', 0x3a7), ('\u{3c8}', 0x3a8), ('\u{3c9}', 0x3a9), ('\u{3ca}', 0x3aa), + ('\u{3cb}', 0x3ab), ('\u{3cc}', 0x38c), ('\u{3cd}', 0x38e), ('\u{3ce}', 0x38f), + ('\u{3d0}', 0x392), ('\u{3d1}', 0x398), ('\u{3d5}', 0x3a6), ('\u{3d6}', 0x3a0), + ('\u{3d7}', 0x3cf), ('\u{3d9}', 0x3d8), ('\u{3db}', 0x3da), ('\u{3dd}', 0x3dc), + ('\u{3df}', 0x3de), ('\u{3e1}', 0x3e0), ('\u{3e3}', 0x3e2), ('\u{3e5}', 0x3e4), + ('\u{3e7}', 0x3e6), ('\u{3e9}', 0x3e8), ('\u{3eb}', 0x3ea), ('\u{3ed}', 0x3ec), + ('\u{3ef}', 0x3ee), ('\u{3f0}', 0x39a), ('\u{3f1}', 0x3a1), ('\u{3f2}', 0x3f9), + ('\u{3f3}', 0x37f), ('\u{3f5}', 0x395), ('\u{3f8}', 0x3f7), ('\u{3fb}', 0x3fa), + ('\u{430}', 0x410), ('\u{431}', 0x411), ('\u{432}', 0x412), ('\u{433}', 0x413), + ('\u{434}', 0x414), ('\u{435}', 0x415), ('\u{436}', 0x416), ('\u{437}', 0x417), + ('\u{438}', 0x418), ('\u{439}', 0x419), ('\u{43a}', 0x41a), ('\u{43b}', 0x41b), + ('\u{43c}', 0x41c), ('\u{43d}', 0x41d), ('\u{43e}', 0x41e), ('\u{43f}', 0x41f), + ('\u{440}', 0x420), ('\u{441}', 0x421), ('\u{442}', 0x422), ('\u{443}', 0x423), + ('\u{444}', 0x424), ('\u{445}', 0x425), ('\u{446}', 0x426), ('\u{447}', 0x427), + ('\u{448}', 0x428), ('\u{449}', 0x429), ('\u{44a}', 0x42a), ('\u{44b}', 0x42b), + ('\u{44c}', 0x42c), ('\u{44d}', 0x42d), ('\u{44e}', 0x42e), ('\u{44f}', 0x42f), + ('\u{450}', 0x400), ('\u{451}', 0x401), ('\u{452}', 0x402), ('\u{453}', 0x403), + ('\u{454}', 0x404), ('\u{455}', 0x405), ('\u{456}', 0x406), ('\u{457}', 0x407), + ('\u{458}', 0x408), ('\u{459}', 0x409), ('\u{45a}', 0x40a), ('\u{45b}', 0x40b), + ('\u{45c}', 0x40c), ('\u{45d}', 0x40d), ('\u{45e}', 0x40e), ('\u{45f}', 0x40f), + ('\u{461}', 0x460), ('\u{463}', 0x462), ('\u{465}', 0x464), ('\u{467}', 0x466), + ('\u{469}', 0x468), ('\u{46b}', 0x46a), ('\u{46d}', 0x46c), ('\u{46f}', 0x46e), + ('\u{471}', 0x470), ('\u{473}', 0x472), ('\u{475}', 0x474), ('\u{477}', 0x476), + ('\u{479}', 0x478), ('\u{47b}', 0x47a), ('\u{47d}', 0x47c), ('\u{47f}', 0x47e), + ('\u{481}', 0x480), ('\u{48b}', 0x48a), ('\u{48d}', 0x48c), ('\u{48f}', 0x48e), + ('\u{491}', 0x490), ('\u{493}', 0x492), ('\u{495}', 0x494), ('\u{497}', 0x496), + ('\u{499}', 0x498), ('\u{49b}', 0x49a), ('\u{49d}', 0x49c), ('\u{49f}', 0x49e), + ('\u{4a1}', 0x4a0), ('\u{4a3}', 0x4a2), ('\u{4a5}', 0x4a4), ('\u{4a7}', 0x4a6), + ('\u{4a9}', 0x4a8), ('\u{4ab}', 0x4aa), ('\u{4ad}', 0x4ac), ('\u{4af}', 0x4ae), + ('\u{4b1}', 0x4b0), ('\u{4b3}', 0x4b2), ('\u{4b5}', 0x4b4), ('\u{4b7}', 0x4b6), + ('\u{4b9}', 0x4b8), ('\u{4bb}', 0x4ba), ('\u{4bd}', 0x4bc), ('\u{4bf}', 0x4be), + ('\u{4c2}', 0x4c1), ('\u{4c4}', 0x4c3), ('\u{4c6}', 0x4c5), ('\u{4c8}', 0x4c7), + ('\u{4ca}', 0x4c9), ('\u{4cc}', 0x4cb), ('\u{4ce}', 0x4cd), ('\u{4cf}', 0x4c0), + ('\u{4d1}', 0x4d0), ('\u{4d3}', 0x4d2), ('\u{4d5}', 0x4d4), ('\u{4d7}', 0x4d6), + ('\u{4d9}', 0x4d8), ('\u{4db}', 0x4da), ('\u{4dd}', 0x4dc), ('\u{4df}', 0x4de), + ('\u{4e1}', 0x4e0), ('\u{4e3}', 0x4e2), ('\u{4e5}', 0x4e4), ('\u{4e7}', 0x4e6), + ('\u{4e9}', 0x4e8), ('\u{4eb}', 0x4ea), ('\u{4ed}', 0x4ec), ('\u{4ef}', 0x4ee), + ('\u{4f1}', 0x4f0), ('\u{4f3}', 0x4f2), ('\u{4f5}', 0x4f4), ('\u{4f7}', 0x4f6), + ('\u{4f9}', 0x4f8), ('\u{4fb}', 0x4fa), ('\u{4fd}', 0x4fc), ('\u{4ff}', 0x4fe), + ('\u{501}', 0x500), ('\u{503}', 0x502), ('\u{505}', 0x504), ('\u{507}', 0x506), + ('\u{509}', 0x508), ('\u{50b}', 0x50a), ('\u{50d}', 0x50c), ('\u{50f}', 0x50e), + ('\u{511}', 0x510), ('\u{513}', 0x512), ('\u{515}', 0x514), ('\u{517}', 0x516), + ('\u{519}', 0x518), ('\u{51b}', 0x51a), ('\u{51d}', 0x51c), ('\u{51f}', 0x51e), + ('\u{521}', 0x520), ('\u{523}', 0x522), ('\u{525}', 0x524), ('\u{527}', 0x526), + ('\u{529}', 0x528), ('\u{52b}', 0x52a), ('\u{52d}', 0x52c), ('\u{52f}', 0x52e), + ('\u{561}', 0x531), ('\u{562}', 0x532), ('\u{563}', 0x533), ('\u{564}', 0x534), + ('\u{565}', 0x535), ('\u{566}', 0x536), ('\u{567}', 0x537), ('\u{568}', 0x538), + ('\u{569}', 0x539), ('\u{56a}', 0x53a), ('\u{56b}', 0x53b), ('\u{56c}', 0x53c), + ('\u{56d}', 0x53d), ('\u{56e}', 0x53e), ('\u{56f}', 0x53f), ('\u{570}', 0x540), + ('\u{571}', 0x541), ('\u{572}', 0x542), ('\u{573}', 0x543), ('\u{574}', 0x544), + ('\u{575}', 0x545), ('\u{576}', 0x546), ('\u{577}', 0x547), ('\u{578}', 0x548), + ('\u{579}', 0x549), ('\u{57a}', 0x54a), ('\u{57b}', 0x54b), ('\u{57c}', 0x54c), + ('\u{57d}', 0x54d), ('\u{57e}', 0x54e), ('\u{57f}', 0x54f), ('\u{580}', 0x550), + ('\u{581}', 0x551), ('\u{582}', 0x552), ('\u{583}', 0x553), ('\u{584}', 0x554), + ('\u{585}', 0x555), ('\u{586}', 0x556), ('\u{587}', 0x400005), ('\u{10d0}', 0x1c90), + ('\u{10d1}', 0x1c91), ('\u{10d2}', 0x1c92), ('\u{10d3}', 0x1c93), ('\u{10d4}', 0x1c94), + ('\u{10d5}', 0x1c95), ('\u{10d6}', 0x1c96), ('\u{10d7}', 0x1c97), ('\u{10d8}', 0x1c98), + ('\u{10d9}', 0x1c99), ('\u{10da}', 0x1c9a), ('\u{10db}', 0x1c9b), ('\u{10dc}', 0x1c9c), + ('\u{10dd}', 0x1c9d), ('\u{10de}', 0x1c9e), ('\u{10df}', 0x1c9f), ('\u{10e0}', 0x1ca0), + ('\u{10e1}', 0x1ca1), ('\u{10e2}', 0x1ca2), ('\u{10e3}', 0x1ca3), ('\u{10e4}', 0x1ca4), + ('\u{10e5}', 0x1ca5), ('\u{10e6}', 0x1ca6), ('\u{10e7}', 0x1ca7), ('\u{10e8}', 0x1ca8), + ('\u{10e9}', 0x1ca9), ('\u{10ea}', 0x1caa), ('\u{10eb}', 0x1cab), ('\u{10ec}', 0x1cac), + ('\u{10ed}', 0x1cad), ('\u{10ee}', 0x1cae), ('\u{10ef}', 0x1caf), ('\u{10f0}', 0x1cb0), + ('\u{10f1}', 0x1cb1), ('\u{10f2}', 0x1cb2), ('\u{10f3}', 0x1cb3), ('\u{10f4}', 0x1cb4), + ('\u{10f5}', 0x1cb5), ('\u{10f6}', 0x1cb6), ('\u{10f7}', 0x1cb7), ('\u{10f8}', 0x1cb8), + ('\u{10f9}', 0x1cb9), ('\u{10fa}', 0x1cba), ('\u{10fd}', 0x1cbd), ('\u{10fe}', 0x1cbe), + ('\u{10ff}', 0x1cbf), ('\u{13f8}', 0x13f0), ('\u{13f9}', 0x13f1), ('\u{13fa}', 0x13f2), + ('\u{13fb}', 0x13f3), ('\u{13fc}', 0x13f4), ('\u{13fd}', 0x13f5), ('\u{1c80}', 0x412), + ('\u{1c81}', 0x414), ('\u{1c82}', 0x41e), ('\u{1c83}', 0x421), ('\u{1c84}', 0x422), + ('\u{1c85}', 0x422), ('\u{1c86}', 0x42a), ('\u{1c87}', 0x462), ('\u{1c88}', 0xa64a), + ('\u{1c8a}', 0x1c89), ('\u{1d79}', 0xa77d), ('\u{1d7d}', 0x2c63), ('\u{1d8e}', 0xa7c6), + ('\u{1e01}', 0x1e00), ('\u{1e03}', 0x1e02), ('\u{1e05}', 0x1e04), ('\u{1e07}', 0x1e06), + ('\u{1e09}', 0x1e08), ('\u{1e0b}', 0x1e0a), ('\u{1e0d}', 0x1e0c), ('\u{1e0f}', 0x1e0e), + ('\u{1e11}', 0x1e10), ('\u{1e13}', 0x1e12), ('\u{1e15}', 0x1e14), ('\u{1e17}', 0x1e16), + ('\u{1e19}', 0x1e18), ('\u{1e1b}', 0x1e1a), ('\u{1e1d}', 0x1e1c), ('\u{1e1f}', 0x1e1e), + ('\u{1e21}', 0x1e20), ('\u{1e23}', 0x1e22), ('\u{1e25}', 0x1e24), ('\u{1e27}', 0x1e26), + ('\u{1e29}', 0x1e28), ('\u{1e2b}', 0x1e2a), ('\u{1e2d}', 0x1e2c), ('\u{1e2f}', 0x1e2e), + ('\u{1e31}', 0x1e30), ('\u{1e33}', 0x1e32), ('\u{1e35}', 0x1e34), ('\u{1e37}', 0x1e36), + ('\u{1e39}', 0x1e38), ('\u{1e3b}', 0x1e3a), ('\u{1e3d}', 0x1e3c), ('\u{1e3f}', 0x1e3e), + ('\u{1e41}', 0x1e40), ('\u{1e43}', 0x1e42), ('\u{1e45}', 0x1e44), ('\u{1e47}', 0x1e46), + ('\u{1e49}', 0x1e48), ('\u{1e4b}', 0x1e4a), ('\u{1e4d}', 0x1e4c), ('\u{1e4f}', 0x1e4e), + ('\u{1e51}', 0x1e50), ('\u{1e53}', 0x1e52), ('\u{1e55}', 0x1e54), ('\u{1e57}', 0x1e56), + ('\u{1e59}', 0x1e58), ('\u{1e5b}', 0x1e5a), ('\u{1e5d}', 0x1e5c), ('\u{1e5f}', 0x1e5e), + ('\u{1e61}', 0x1e60), ('\u{1e63}', 0x1e62), ('\u{1e65}', 0x1e64), ('\u{1e67}', 0x1e66), + ('\u{1e69}', 0x1e68), ('\u{1e6b}', 0x1e6a), ('\u{1e6d}', 0x1e6c), ('\u{1e6f}', 0x1e6e), + ('\u{1e71}', 0x1e70), ('\u{1e73}', 0x1e72), ('\u{1e75}', 0x1e74), ('\u{1e77}', 0x1e76), + ('\u{1e79}', 0x1e78), ('\u{1e7b}', 0x1e7a), ('\u{1e7d}', 0x1e7c), ('\u{1e7f}', 0x1e7e), + ('\u{1e81}', 0x1e80), ('\u{1e83}', 0x1e82), ('\u{1e85}', 0x1e84), ('\u{1e87}', 0x1e86), + ('\u{1e89}', 0x1e88), ('\u{1e8b}', 0x1e8a), ('\u{1e8d}', 0x1e8c), ('\u{1e8f}', 0x1e8e), + ('\u{1e91}', 0x1e90), ('\u{1e93}', 0x1e92), ('\u{1e95}', 0x1e94), ('\u{1e96}', 0x400006), + ('\u{1e97}', 0x400007), ('\u{1e98}', 0x400008), ('\u{1e99}', 0x400009), + ('\u{1e9a}', 0x40000a), ('\u{1e9b}', 0x1e60), ('\u{1ea1}', 0x1ea0), ('\u{1ea3}', 0x1ea2), + ('\u{1ea5}', 0x1ea4), ('\u{1ea7}', 0x1ea6), ('\u{1ea9}', 0x1ea8), ('\u{1eab}', 0x1eaa), + ('\u{1ead}', 0x1eac), ('\u{1eaf}', 0x1eae), ('\u{1eb1}', 0x1eb0), ('\u{1eb3}', 0x1eb2), + ('\u{1eb5}', 0x1eb4), ('\u{1eb7}', 0x1eb6), ('\u{1eb9}', 0x1eb8), ('\u{1ebb}', 0x1eba), + ('\u{1ebd}', 0x1ebc), ('\u{1ebf}', 0x1ebe), ('\u{1ec1}', 0x1ec0), ('\u{1ec3}', 0x1ec2), + ('\u{1ec5}', 0x1ec4), ('\u{1ec7}', 0x1ec6), ('\u{1ec9}', 0x1ec8), ('\u{1ecb}', 0x1eca), + ('\u{1ecd}', 0x1ecc), ('\u{1ecf}', 0x1ece), ('\u{1ed1}', 0x1ed0), ('\u{1ed3}', 0x1ed2), + ('\u{1ed5}', 0x1ed4), ('\u{1ed7}', 0x1ed6), ('\u{1ed9}', 0x1ed8), ('\u{1edb}', 0x1eda), + ('\u{1edd}', 0x1edc), ('\u{1edf}', 0x1ede), ('\u{1ee1}', 0x1ee0), ('\u{1ee3}', 0x1ee2), + ('\u{1ee5}', 0x1ee4), ('\u{1ee7}', 0x1ee6), ('\u{1ee9}', 0x1ee8), ('\u{1eeb}', 0x1eea), + ('\u{1eed}', 0x1eec), ('\u{1eef}', 0x1eee), ('\u{1ef1}', 0x1ef0), ('\u{1ef3}', 0x1ef2), + ('\u{1ef5}', 0x1ef4), ('\u{1ef7}', 0x1ef6), ('\u{1ef9}', 0x1ef8), ('\u{1efb}', 0x1efa), + ('\u{1efd}', 0x1efc), ('\u{1eff}', 0x1efe), ('\u{1f00}', 0x1f08), ('\u{1f01}', 0x1f09), + ('\u{1f02}', 0x1f0a), ('\u{1f03}', 0x1f0b), ('\u{1f04}', 0x1f0c), ('\u{1f05}', 0x1f0d), + ('\u{1f06}', 0x1f0e), ('\u{1f07}', 0x1f0f), ('\u{1f10}', 0x1f18), ('\u{1f11}', 0x1f19), + ('\u{1f12}', 0x1f1a), ('\u{1f13}', 0x1f1b), ('\u{1f14}', 0x1f1c), ('\u{1f15}', 0x1f1d), + ('\u{1f20}', 0x1f28), ('\u{1f21}', 0x1f29), ('\u{1f22}', 0x1f2a), ('\u{1f23}', 0x1f2b), + ('\u{1f24}', 0x1f2c), ('\u{1f25}', 0x1f2d), ('\u{1f26}', 0x1f2e), ('\u{1f27}', 0x1f2f), + ('\u{1f30}', 0x1f38), ('\u{1f31}', 0x1f39), ('\u{1f32}', 0x1f3a), ('\u{1f33}', 0x1f3b), + ('\u{1f34}', 0x1f3c), ('\u{1f35}', 0x1f3d), ('\u{1f36}', 0x1f3e), ('\u{1f37}', 0x1f3f), + ('\u{1f40}', 0x1f48), ('\u{1f41}', 0x1f49), ('\u{1f42}', 0x1f4a), ('\u{1f43}', 0x1f4b), + ('\u{1f44}', 0x1f4c), ('\u{1f45}', 0x1f4d), ('\u{1f50}', 0x40000b), ('\u{1f51}', 0x1f59), + ('\u{1f52}', 0x40000c), ('\u{1f53}', 0x1f5b), ('\u{1f54}', 0x40000d), ('\u{1f55}', 0x1f5d), + ('\u{1f56}', 0x40000e), ('\u{1f57}', 0x1f5f), ('\u{1f60}', 0x1f68), ('\u{1f61}', 0x1f69), + ('\u{1f62}', 0x1f6a), ('\u{1f63}', 0x1f6b), ('\u{1f64}', 0x1f6c), ('\u{1f65}', 0x1f6d), + ('\u{1f66}', 0x1f6e), ('\u{1f67}', 0x1f6f), ('\u{1f70}', 0x1fba), ('\u{1f71}', 0x1fbb), + ('\u{1f72}', 0x1fc8), ('\u{1f73}', 0x1fc9), ('\u{1f74}', 0x1fca), ('\u{1f75}', 0x1fcb), + ('\u{1f76}', 0x1fda), ('\u{1f77}', 0x1fdb), ('\u{1f78}', 0x1ff8), ('\u{1f79}', 0x1ff9), + ('\u{1f7a}', 0x1fea), ('\u{1f7b}', 0x1feb), ('\u{1f7c}', 0x1ffa), ('\u{1f7d}', 0x1ffb), + ('\u{1f80}', 0x40000f), ('\u{1f81}', 0x400010), ('\u{1f82}', 0x400011), + ('\u{1f83}', 0x400012), ('\u{1f84}', 0x400013), ('\u{1f85}', 0x400014), + ('\u{1f86}', 0x400015), ('\u{1f87}', 0x400016), ('\u{1f88}', 0x400017), + ('\u{1f89}', 0x400018), ('\u{1f8a}', 0x400019), ('\u{1f8b}', 0x40001a), + ('\u{1f8c}', 0x40001b), ('\u{1f8d}', 0x40001c), ('\u{1f8e}', 0x40001d), + ('\u{1f8f}', 0x40001e), ('\u{1f90}', 0x40001f), ('\u{1f91}', 0x400020), + ('\u{1f92}', 0x400021), ('\u{1f93}', 0x400022), ('\u{1f94}', 0x400023), + ('\u{1f95}', 0x400024), ('\u{1f96}', 0x400025), ('\u{1f97}', 0x400026), + ('\u{1f98}', 0x400027), ('\u{1f99}', 0x400028), ('\u{1f9a}', 0x400029), + ('\u{1f9b}', 0x40002a), ('\u{1f9c}', 0x40002b), ('\u{1f9d}', 0x40002c), + ('\u{1f9e}', 0x40002d), ('\u{1f9f}', 0x40002e), ('\u{1fa0}', 0x40002f), + ('\u{1fa1}', 0x400030), ('\u{1fa2}', 0x400031), ('\u{1fa3}', 0x400032), + ('\u{1fa4}', 0x400033), ('\u{1fa5}', 0x400034), ('\u{1fa6}', 0x400035), + ('\u{1fa7}', 0x400036), ('\u{1fa8}', 0x400037), ('\u{1fa9}', 0x400038), + ('\u{1faa}', 0x400039), ('\u{1fab}', 0x40003a), ('\u{1fac}', 0x40003b), + ('\u{1fad}', 0x40003c), ('\u{1fae}', 0x40003d), ('\u{1faf}', 0x40003e), + ('\u{1fb0}', 0x1fb8), ('\u{1fb1}', 0x1fb9), ('\u{1fb2}', 0x40003f), ('\u{1fb3}', 0x400040), + ('\u{1fb4}', 0x400041), ('\u{1fb6}', 0x400042), ('\u{1fb7}', 0x400043), + ('\u{1fbc}', 0x400044), ('\u{1fbe}', 0x399), ('\u{1fc2}', 0x400045), ('\u{1fc3}', 0x400046), + ('\u{1fc4}', 0x400047), ('\u{1fc6}', 0x400048), ('\u{1fc7}', 0x400049), + ('\u{1fcc}', 0x40004a), ('\u{1fd0}', 0x1fd8), ('\u{1fd1}', 0x1fd9), ('\u{1fd2}', 0x40004b), + ('\u{1fd3}', 0x40004c), ('\u{1fd6}', 0x40004d), ('\u{1fd7}', 0x40004e), + ('\u{1fe0}', 0x1fe8), ('\u{1fe1}', 0x1fe9), ('\u{1fe2}', 0x40004f), ('\u{1fe3}', 0x400050), + ('\u{1fe4}', 0x400051), ('\u{1fe5}', 0x1fec), ('\u{1fe6}', 0x400052), + ('\u{1fe7}', 0x400053), ('\u{1ff2}', 0x400054), ('\u{1ff3}', 0x400055), + ('\u{1ff4}', 0x400056), ('\u{1ff6}', 0x400057), ('\u{1ff7}', 0x400058), + ('\u{1ffc}', 0x400059), ('\u{214e}', 0x2132), ('\u{2170}', 0x2160), ('\u{2171}', 0x2161), + ('\u{2172}', 0x2162), ('\u{2173}', 0x2163), ('\u{2174}', 0x2164), ('\u{2175}', 0x2165), + ('\u{2176}', 0x2166), ('\u{2177}', 0x2167), ('\u{2178}', 0x2168), ('\u{2179}', 0x2169), + ('\u{217a}', 0x216a), ('\u{217b}', 0x216b), ('\u{217c}', 0x216c), ('\u{217d}', 0x216d), + ('\u{217e}', 0x216e), ('\u{217f}', 0x216f), ('\u{2184}', 0x2183), ('\u{24d0}', 0x24b6), + ('\u{24d1}', 0x24b7), ('\u{24d2}', 0x24b8), ('\u{24d3}', 0x24b9), ('\u{24d4}', 0x24ba), + ('\u{24d5}', 0x24bb), ('\u{24d6}', 0x24bc), ('\u{24d7}', 0x24bd), ('\u{24d8}', 0x24be), + ('\u{24d9}', 0x24bf), ('\u{24da}', 0x24c0), ('\u{24db}', 0x24c1), ('\u{24dc}', 0x24c2), + ('\u{24dd}', 0x24c3), ('\u{24de}', 0x24c4), ('\u{24df}', 0x24c5), ('\u{24e0}', 0x24c6), + ('\u{24e1}', 0x24c7), ('\u{24e2}', 0x24c8), ('\u{24e3}', 0x24c9), ('\u{24e4}', 0x24ca), + ('\u{24e5}', 0x24cb), ('\u{24e6}', 0x24cc), ('\u{24e7}', 0x24cd), ('\u{24e8}', 0x24ce), + ('\u{24e9}', 0x24cf), ('\u{2c30}', 0x2c00), ('\u{2c31}', 0x2c01), ('\u{2c32}', 0x2c02), + ('\u{2c33}', 0x2c03), ('\u{2c34}', 0x2c04), ('\u{2c35}', 0x2c05), ('\u{2c36}', 0x2c06), + ('\u{2c37}', 0x2c07), ('\u{2c38}', 0x2c08), ('\u{2c39}', 0x2c09), ('\u{2c3a}', 0x2c0a), + ('\u{2c3b}', 0x2c0b), ('\u{2c3c}', 0x2c0c), ('\u{2c3d}', 0x2c0d), ('\u{2c3e}', 0x2c0e), + ('\u{2c3f}', 0x2c0f), ('\u{2c40}', 0x2c10), ('\u{2c41}', 0x2c11), ('\u{2c42}', 0x2c12), + ('\u{2c43}', 0x2c13), ('\u{2c44}', 0x2c14), ('\u{2c45}', 0x2c15), ('\u{2c46}', 0x2c16), + ('\u{2c47}', 0x2c17), ('\u{2c48}', 0x2c18), ('\u{2c49}', 0x2c19), ('\u{2c4a}', 0x2c1a), + ('\u{2c4b}', 0x2c1b), ('\u{2c4c}', 0x2c1c), ('\u{2c4d}', 0x2c1d), ('\u{2c4e}', 0x2c1e), + ('\u{2c4f}', 0x2c1f), ('\u{2c50}', 0x2c20), ('\u{2c51}', 0x2c21), ('\u{2c52}', 0x2c22), + ('\u{2c53}', 0x2c23), ('\u{2c54}', 0x2c24), ('\u{2c55}', 0x2c25), ('\u{2c56}', 0x2c26), + ('\u{2c57}', 0x2c27), ('\u{2c58}', 0x2c28), ('\u{2c59}', 0x2c29), ('\u{2c5a}', 0x2c2a), + ('\u{2c5b}', 0x2c2b), ('\u{2c5c}', 0x2c2c), ('\u{2c5d}', 0x2c2d), ('\u{2c5e}', 0x2c2e), + ('\u{2c5f}', 0x2c2f), ('\u{2c61}', 0x2c60), ('\u{2c65}', 0x23a), ('\u{2c66}', 0x23e), + ('\u{2c68}', 0x2c67), ('\u{2c6a}', 0x2c69), ('\u{2c6c}', 0x2c6b), ('\u{2c73}', 0x2c72), + ('\u{2c76}', 0x2c75), ('\u{2c81}', 0x2c80), ('\u{2c83}', 0x2c82), ('\u{2c85}', 0x2c84), + ('\u{2c87}', 0x2c86), ('\u{2c89}', 0x2c88), ('\u{2c8b}', 0x2c8a), ('\u{2c8d}', 0x2c8c), + ('\u{2c8f}', 0x2c8e), ('\u{2c91}', 0x2c90), ('\u{2c93}', 0x2c92), ('\u{2c95}', 0x2c94), + ('\u{2c97}', 0x2c96), ('\u{2c99}', 0x2c98), ('\u{2c9b}', 0x2c9a), ('\u{2c9d}', 0x2c9c), + ('\u{2c9f}', 0x2c9e), ('\u{2ca1}', 0x2ca0), ('\u{2ca3}', 0x2ca2), ('\u{2ca5}', 0x2ca4), + ('\u{2ca7}', 0x2ca6), ('\u{2ca9}', 0x2ca8), ('\u{2cab}', 0x2caa), ('\u{2cad}', 0x2cac), + ('\u{2caf}', 0x2cae), ('\u{2cb1}', 0x2cb0), ('\u{2cb3}', 0x2cb2), ('\u{2cb5}', 0x2cb4), + ('\u{2cb7}', 0x2cb6), ('\u{2cb9}', 0x2cb8), ('\u{2cbb}', 0x2cba), ('\u{2cbd}', 0x2cbc), + ('\u{2cbf}', 0x2cbe), ('\u{2cc1}', 0x2cc0), ('\u{2cc3}', 0x2cc2), ('\u{2cc5}', 0x2cc4), + ('\u{2cc7}', 0x2cc6), ('\u{2cc9}', 0x2cc8), ('\u{2ccb}', 0x2cca), ('\u{2ccd}', 0x2ccc), + ('\u{2ccf}', 0x2cce), ('\u{2cd1}', 0x2cd0), ('\u{2cd3}', 0x2cd2), ('\u{2cd5}', 0x2cd4), + ('\u{2cd7}', 0x2cd6), ('\u{2cd9}', 0x2cd8), ('\u{2cdb}', 0x2cda), ('\u{2cdd}', 0x2cdc), + ('\u{2cdf}', 0x2cde), ('\u{2ce1}', 0x2ce0), ('\u{2ce3}', 0x2ce2), ('\u{2cec}', 0x2ceb), + ('\u{2cee}', 0x2ced), ('\u{2cf3}', 0x2cf2), ('\u{2d00}', 0x10a0), ('\u{2d01}', 0x10a1), + ('\u{2d02}', 0x10a2), ('\u{2d03}', 0x10a3), ('\u{2d04}', 0x10a4), ('\u{2d05}', 0x10a5), + ('\u{2d06}', 0x10a6), ('\u{2d07}', 0x10a7), ('\u{2d08}', 0x10a8), ('\u{2d09}', 0x10a9), + ('\u{2d0a}', 0x10aa), ('\u{2d0b}', 0x10ab), ('\u{2d0c}', 0x10ac), ('\u{2d0d}', 0x10ad), + ('\u{2d0e}', 0x10ae), ('\u{2d0f}', 0x10af), ('\u{2d10}', 0x10b0), ('\u{2d11}', 0x10b1), + ('\u{2d12}', 0x10b2), ('\u{2d13}', 0x10b3), ('\u{2d14}', 0x10b4), ('\u{2d15}', 0x10b5), + ('\u{2d16}', 0x10b6), ('\u{2d17}', 0x10b7), ('\u{2d18}', 0x10b8), ('\u{2d19}', 0x10b9), + ('\u{2d1a}', 0x10ba), ('\u{2d1b}', 0x10bb), ('\u{2d1c}', 0x10bc), ('\u{2d1d}', 0x10bd), + ('\u{2d1e}', 0x10be), ('\u{2d1f}', 0x10bf), ('\u{2d20}', 0x10c0), ('\u{2d21}', 0x10c1), + ('\u{2d22}', 0x10c2), ('\u{2d23}', 0x10c3), ('\u{2d24}', 0x10c4), ('\u{2d25}', 0x10c5), + ('\u{2d27}', 0x10c7), ('\u{2d2d}', 0x10cd), ('\u{a641}', 0xa640), ('\u{a643}', 0xa642), + ('\u{a645}', 0xa644), ('\u{a647}', 0xa646), ('\u{a649}', 0xa648), ('\u{a64b}', 0xa64a), + ('\u{a64d}', 0xa64c), ('\u{a64f}', 0xa64e), ('\u{a651}', 0xa650), ('\u{a653}', 0xa652), + ('\u{a655}', 0xa654), ('\u{a657}', 0xa656), ('\u{a659}', 0xa658), ('\u{a65b}', 0xa65a), + ('\u{a65d}', 0xa65c), ('\u{a65f}', 0xa65e), ('\u{a661}', 0xa660), ('\u{a663}', 0xa662), + ('\u{a665}', 0xa664), ('\u{a667}', 0xa666), ('\u{a669}', 0xa668), ('\u{a66b}', 0xa66a), + ('\u{a66d}', 0xa66c), ('\u{a681}', 0xa680), ('\u{a683}', 0xa682), ('\u{a685}', 0xa684), + ('\u{a687}', 0xa686), ('\u{a689}', 0xa688), ('\u{a68b}', 0xa68a), ('\u{a68d}', 0xa68c), + ('\u{a68f}', 0xa68e), ('\u{a691}', 0xa690), ('\u{a693}', 0xa692), ('\u{a695}', 0xa694), + ('\u{a697}', 0xa696), ('\u{a699}', 0xa698), ('\u{a69b}', 0xa69a), ('\u{a723}', 0xa722), + ('\u{a725}', 0xa724), ('\u{a727}', 0xa726), ('\u{a729}', 0xa728), ('\u{a72b}', 0xa72a), + ('\u{a72d}', 0xa72c), ('\u{a72f}', 0xa72e), ('\u{a733}', 0xa732), ('\u{a735}', 0xa734), + ('\u{a737}', 0xa736), ('\u{a739}', 0xa738), ('\u{a73b}', 0xa73a), ('\u{a73d}', 0xa73c), + ('\u{a73f}', 0xa73e), ('\u{a741}', 0xa740), ('\u{a743}', 0xa742), ('\u{a745}', 0xa744), + ('\u{a747}', 0xa746), ('\u{a749}', 0xa748), ('\u{a74b}', 0xa74a), ('\u{a74d}', 0xa74c), + ('\u{a74f}', 0xa74e), ('\u{a751}', 0xa750), ('\u{a753}', 0xa752), ('\u{a755}', 0xa754), + ('\u{a757}', 0xa756), ('\u{a759}', 0xa758), ('\u{a75b}', 0xa75a), ('\u{a75d}', 0xa75c), + ('\u{a75f}', 0xa75e), ('\u{a761}', 0xa760), ('\u{a763}', 0xa762), ('\u{a765}', 0xa764), + ('\u{a767}', 0xa766), ('\u{a769}', 0xa768), ('\u{a76b}', 0xa76a), ('\u{a76d}', 0xa76c), + ('\u{a76f}', 0xa76e), ('\u{a77a}', 0xa779), ('\u{a77c}', 0xa77b), ('\u{a77f}', 0xa77e), + ('\u{a781}', 0xa780), ('\u{a783}', 0xa782), ('\u{a785}', 0xa784), ('\u{a787}', 0xa786), + ('\u{a78c}', 0xa78b), ('\u{a791}', 0xa790), ('\u{a793}', 0xa792), ('\u{a794}', 0xa7c4), + ('\u{a797}', 0xa796), ('\u{a799}', 0xa798), ('\u{a79b}', 0xa79a), ('\u{a79d}', 0xa79c), + ('\u{a79f}', 0xa79e), ('\u{a7a1}', 0xa7a0), ('\u{a7a3}', 0xa7a2), ('\u{a7a5}', 0xa7a4), + ('\u{a7a7}', 0xa7a6), ('\u{a7a9}', 0xa7a8), ('\u{a7b5}', 0xa7b4), ('\u{a7b7}', 0xa7b6), + ('\u{a7b9}', 0xa7b8), ('\u{a7bb}', 0xa7ba), ('\u{a7bd}', 0xa7bc), ('\u{a7bf}', 0xa7be), + ('\u{a7c1}', 0xa7c0), ('\u{a7c3}', 0xa7c2), ('\u{a7c8}', 0xa7c7), ('\u{a7ca}', 0xa7c9), + ('\u{a7cd}', 0xa7cc), ('\u{a7cf}', 0xa7ce), ('\u{a7d1}', 0xa7d0), ('\u{a7d3}', 0xa7d2), + ('\u{a7d5}', 0xa7d4), ('\u{a7d7}', 0xa7d6), ('\u{a7d9}', 0xa7d8), ('\u{a7db}', 0xa7da), + ('\u{a7f6}', 0xa7f5), ('\u{ab53}', 0xa7b3), ('\u{ab70}', 0x13a0), ('\u{ab71}', 0x13a1), + ('\u{ab72}', 0x13a2), ('\u{ab73}', 0x13a3), ('\u{ab74}', 0x13a4), ('\u{ab75}', 0x13a5), + ('\u{ab76}', 0x13a6), ('\u{ab77}', 0x13a7), ('\u{ab78}', 0x13a8), ('\u{ab79}', 0x13a9), + ('\u{ab7a}', 0x13aa), ('\u{ab7b}', 0x13ab), ('\u{ab7c}', 0x13ac), ('\u{ab7d}', 0x13ad), + ('\u{ab7e}', 0x13ae), ('\u{ab7f}', 0x13af), ('\u{ab80}', 0x13b0), ('\u{ab81}', 0x13b1), + ('\u{ab82}', 0x13b2), ('\u{ab83}', 0x13b3), ('\u{ab84}', 0x13b4), ('\u{ab85}', 0x13b5), + ('\u{ab86}', 0x13b6), ('\u{ab87}', 0x13b7), ('\u{ab88}', 0x13b8), ('\u{ab89}', 0x13b9), + ('\u{ab8a}', 0x13ba), ('\u{ab8b}', 0x13bb), ('\u{ab8c}', 0x13bc), ('\u{ab8d}', 0x13bd), + ('\u{ab8e}', 0x13be), ('\u{ab8f}', 0x13bf), ('\u{ab90}', 0x13c0), ('\u{ab91}', 0x13c1), + ('\u{ab92}', 0x13c2), ('\u{ab93}', 0x13c3), ('\u{ab94}', 0x13c4), ('\u{ab95}', 0x13c5), + ('\u{ab96}', 0x13c6), ('\u{ab97}', 0x13c7), ('\u{ab98}', 0x13c8), ('\u{ab99}', 0x13c9), + ('\u{ab9a}', 0x13ca), ('\u{ab9b}', 0x13cb), ('\u{ab9c}', 0x13cc), ('\u{ab9d}', 0x13cd), + ('\u{ab9e}', 0x13ce), ('\u{ab9f}', 0x13cf), ('\u{aba0}', 0x13d0), ('\u{aba1}', 0x13d1), + ('\u{aba2}', 0x13d2), ('\u{aba3}', 0x13d3), ('\u{aba4}', 0x13d4), ('\u{aba5}', 0x13d5), + ('\u{aba6}', 0x13d6), ('\u{aba7}', 0x13d7), ('\u{aba8}', 0x13d8), ('\u{aba9}', 0x13d9), + ('\u{abaa}', 0x13da), ('\u{abab}', 0x13db), ('\u{abac}', 0x13dc), ('\u{abad}', 0x13dd), + ('\u{abae}', 0x13de), ('\u{abaf}', 0x13df), ('\u{abb0}', 0x13e0), ('\u{abb1}', 0x13e1), + ('\u{abb2}', 0x13e2), ('\u{abb3}', 0x13e3), ('\u{abb4}', 0x13e4), ('\u{abb5}', 0x13e5), + ('\u{abb6}', 0x13e6), ('\u{abb7}', 0x13e7), ('\u{abb8}', 0x13e8), ('\u{abb9}', 0x13e9), + ('\u{abba}', 0x13ea), ('\u{abbb}', 0x13eb), ('\u{abbc}', 0x13ec), ('\u{abbd}', 0x13ed), + ('\u{abbe}', 0x13ee), ('\u{abbf}', 0x13ef), ('\u{fb00}', 0x40005a), ('\u{fb01}', 0x40005b), + ('\u{fb02}', 0x40005c), ('\u{fb03}', 0x40005d), ('\u{fb04}', 0x40005e), + ('\u{fb05}', 0x40005f), ('\u{fb06}', 0x400060), ('\u{fb13}', 0x400061), + ('\u{fb14}', 0x400062), ('\u{fb15}', 0x400063), ('\u{fb16}', 0x400064), + ('\u{fb17}', 0x400065), ('\u{ff41}', 0xff21), ('\u{ff42}', 0xff22), ('\u{ff43}', 0xff23), + ('\u{ff44}', 0xff24), ('\u{ff45}', 0xff25), ('\u{ff46}', 0xff26), ('\u{ff47}', 0xff27), + ('\u{ff48}', 0xff28), ('\u{ff49}', 0xff29), ('\u{ff4a}', 0xff2a), ('\u{ff4b}', 0xff2b), + ('\u{ff4c}', 0xff2c), ('\u{ff4d}', 0xff2d), ('\u{ff4e}', 0xff2e), ('\u{ff4f}', 0xff2f), + ('\u{ff50}', 0xff30), ('\u{ff51}', 0xff31), ('\u{ff52}', 0xff32), ('\u{ff53}', 0xff33), + ('\u{ff54}', 0xff34), ('\u{ff55}', 0xff35), ('\u{ff56}', 0xff36), ('\u{ff57}', 0xff37), + ('\u{ff58}', 0xff38), ('\u{ff59}', 0xff39), ('\u{ff5a}', 0xff3a), ('\u{10428}', 0x10400), + ('\u{10429}', 0x10401), ('\u{1042a}', 0x10402), ('\u{1042b}', 0x10403), + ('\u{1042c}', 0x10404), ('\u{1042d}', 0x10405), ('\u{1042e}', 0x10406), + ('\u{1042f}', 0x10407), ('\u{10430}', 0x10408), ('\u{10431}', 0x10409), + ('\u{10432}', 0x1040a), ('\u{10433}', 0x1040b), ('\u{10434}', 0x1040c), + ('\u{10435}', 0x1040d), ('\u{10436}', 0x1040e), ('\u{10437}', 0x1040f), + ('\u{10438}', 0x10410), ('\u{10439}', 0x10411), ('\u{1043a}', 0x10412), + ('\u{1043b}', 0x10413), ('\u{1043c}', 0x10414), ('\u{1043d}', 0x10415), + ('\u{1043e}', 0x10416), ('\u{1043f}', 0x10417), ('\u{10440}', 0x10418), + ('\u{10441}', 0x10419), ('\u{10442}', 0x1041a), ('\u{10443}', 0x1041b), + ('\u{10444}', 0x1041c), ('\u{10445}', 0x1041d), ('\u{10446}', 0x1041e), + ('\u{10447}', 0x1041f), ('\u{10448}', 0x10420), ('\u{10449}', 0x10421), + ('\u{1044a}', 0x10422), ('\u{1044b}', 0x10423), ('\u{1044c}', 0x10424), + ('\u{1044d}', 0x10425), ('\u{1044e}', 0x10426), ('\u{1044f}', 0x10427), + ('\u{104d8}', 0x104b0), ('\u{104d9}', 0x104b1), ('\u{104da}', 0x104b2), + ('\u{104db}', 0x104b3), ('\u{104dc}', 0x104b4), ('\u{104dd}', 0x104b5), + ('\u{104de}', 0x104b6), ('\u{104df}', 0x104b7), ('\u{104e0}', 0x104b8), + ('\u{104e1}', 0x104b9), ('\u{104e2}', 0x104ba), ('\u{104e3}', 0x104bb), + ('\u{104e4}', 0x104bc), ('\u{104e5}', 0x104bd), ('\u{104e6}', 0x104be), + ('\u{104e7}', 0x104bf), ('\u{104e8}', 0x104c0), ('\u{104e9}', 0x104c1), + ('\u{104ea}', 0x104c2), ('\u{104eb}', 0x104c3), ('\u{104ec}', 0x104c4), + ('\u{104ed}', 0x104c5), ('\u{104ee}', 0x104c6), ('\u{104ef}', 0x104c7), + ('\u{104f0}', 0x104c8), ('\u{104f1}', 0x104c9), ('\u{104f2}', 0x104ca), + ('\u{104f3}', 0x104cb), ('\u{104f4}', 0x104cc), ('\u{104f5}', 0x104cd), + ('\u{104f6}', 0x104ce), ('\u{104f7}', 0x104cf), ('\u{104f8}', 0x104d0), + ('\u{104f9}', 0x104d1), ('\u{104fa}', 0x104d2), ('\u{104fb}', 0x104d3), + ('\u{10597}', 0x10570), ('\u{10598}', 0x10571), ('\u{10599}', 0x10572), + ('\u{1059a}', 0x10573), ('\u{1059b}', 0x10574), ('\u{1059c}', 0x10575), + ('\u{1059d}', 0x10576), ('\u{1059e}', 0x10577), ('\u{1059f}', 0x10578), + ('\u{105a0}', 0x10579), ('\u{105a1}', 0x1057a), ('\u{105a3}', 0x1057c), + ('\u{105a4}', 0x1057d), ('\u{105a5}', 0x1057e), ('\u{105a6}', 0x1057f), + ('\u{105a7}', 0x10580), ('\u{105a8}', 0x10581), ('\u{105a9}', 0x10582), + ('\u{105aa}', 0x10583), ('\u{105ab}', 0x10584), ('\u{105ac}', 0x10585), + ('\u{105ad}', 0x10586), ('\u{105ae}', 0x10587), ('\u{105af}', 0x10588), + ('\u{105b0}', 0x10589), ('\u{105b1}', 0x1058a), ('\u{105b3}', 0x1058c), + ('\u{105b4}', 0x1058d), ('\u{105b5}', 0x1058e), ('\u{105b6}', 0x1058f), + ('\u{105b7}', 0x10590), ('\u{105b8}', 0x10591), ('\u{105b9}', 0x10592), + ('\u{105bb}', 0x10594), ('\u{105bc}', 0x10595), ('\u{10cc0}', 0x10c80), + ('\u{10cc1}', 0x10c81), ('\u{10cc2}', 0x10c82), ('\u{10cc3}', 0x10c83), + ('\u{10cc4}', 0x10c84), ('\u{10cc5}', 0x10c85), ('\u{10cc6}', 0x10c86), + ('\u{10cc7}', 0x10c87), ('\u{10cc8}', 0x10c88), ('\u{10cc9}', 0x10c89), + ('\u{10cca}', 0x10c8a), ('\u{10ccb}', 0x10c8b), ('\u{10ccc}', 0x10c8c), + ('\u{10ccd}', 0x10c8d), ('\u{10cce}', 0x10c8e), ('\u{10ccf}', 0x10c8f), + ('\u{10cd0}', 0x10c90), ('\u{10cd1}', 0x10c91), ('\u{10cd2}', 0x10c92), + ('\u{10cd3}', 0x10c93), ('\u{10cd4}', 0x10c94), ('\u{10cd5}', 0x10c95), + ('\u{10cd6}', 0x10c96), ('\u{10cd7}', 0x10c97), ('\u{10cd8}', 0x10c98), + ('\u{10cd9}', 0x10c99), ('\u{10cda}', 0x10c9a), ('\u{10cdb}', 0x10c9b), + ('\u{10cdc}', 0x10c9c), ('\u{10cdd}', 0x10c9d), ('\u{10cde}', 0x10c9e), + ('\u{10cdf}', 0x10c9f), ('\u{10ce0}', 0x10ca0), ('\u{10ce1}', 0x10ca1), + ('\u{10ce2}', 0x10ca2), ('\u{10ce3}', 0x10ca3), ('\u{10ce4}', 0x10ca4), + ('\u{10ce5}', 0x10ca5), ('\u{10ce6}', 0x10ca6), ('\u{10ce7}', 0x10ca7), + ('\u{10ce8}', 0x10ca8), ('\u{10ce9}', 0x10ca9), ('\u{10cea}', 0x10caa), + ('\u{10ceb}', 0x10cab), ('\u{10cec}', 0x10cac), ('\u{10ced}', 0x10cad), + ('\u{10cee}', 0x10cae), ('\u{10cef}', 0x10caf), ('\u{10cf0}', 0x10cb0), + ('\u{10cf1}', 0x10cb1), ('\u{10cf2}', 0x10cb2), ('\u{10d70}', 0x10d50), + ('\u{10d71}', 0x10d51), ('\u{10d72}', 0x10d52), ('\u{10d73}', 0x10d53), + ('\u{10d74}', 0x10d54), ('\u{10d75}', 0x10d55), ('\u{10d76}', 0x10d56), + ('\u{10d77}', 0x10d57), ('\u{10d78}', 0x10d58), ('\u{10d79}', 0x10d59), + ('\u{10d7a}', 0x10d5a), ('\u{10d7b}', 0x10d5b), ('\u{10d7c}', 0x10d5c), + ('\u{10d7d}', 0x10d5d), ('\u{10d7e}', 0x10d5e), ('\u{10d7f}', 0x10d5f), + ('\u{10d80}', 0x10d60), ('\u{10d81}', 0x10d61), ('\u{10d82}', 0x10d62), + ('\u{10d83}', 0x10d63), ('\u{10d84}', 0x10d64), ('\u{10d85}', 0x10d65), + ('\u{118c0}', 0x118a0), ('\u{118c1}', 0x118a1), ('\u{118c2}', 0x118a2), + ('\u{118c3}', 0x118a3), ('\u{118c4}', 0x118a4), ('\u{118c5}', 0x118a5), + ('\u{118c6}', 0x118a6), ('\u{118c7}', 0x118a7), ('\u{118c8}', 0x118a8), + ('\u{118c9}', 0x118a9), ('\u{118ca}', 0x118aa), ('\u{118cb}', 0x118ab), + ('\u{118cc}', 0x118ac), ('\u{118cd}', 0x118ad), ('\u{118ce}', 0x118ae), + ('\u{118cf}', 0x118af), ('\u{118d0}', 0x118b0), ('\u{118d1}', 0x118b1), + ('\u{118d2}', 0x118b2), ('\u{118d3}', 0x118b3), ('\u{118d4}', 0x118b4), + ('\u{118d5}', 0x118b5), ('\u{118d6}', 0x118b6), ('\u{118d7}', 0x118b7), + ('\u{118d8}', 0x118b8), ('\u{118d9}', 0x118b9), ('\u{118da}', 0x118ba), + ('\u{118db}', 0x118bb), ('\u{118dc}', 0x118bc), ('\u{118dd}', 0x118bd), + ('\u{118de}', 0x118be), ('\u{118df}', 0x118bf), ('\u{16e60}', 0x16e40), + ('\u{16e61}', 0x16e41), ('\u{16e62}', 0x16e42), ('\u{16e63}', 0x16e43), + ('\u{16e64}', 0x16e44), ('\u{16e65}', 0x16e45), ('\u{16e66}', 0x16e46), + ('\u{16e67}', 0x16e47), ('\u{16e68}', 0x16e48), ('\u{16e69}', 0x16e49), + ('\u{16e6a}', 0x16e4a), ('\u{16e6b}', 0x16e4b), ('\u{16e6c}', 0x16e4c), + ('\u{16e6d}', 0x16e4d), ('\u{16e6e}', 0x16e4e), ('\u{16e6f}', 0x16e4f), + ('\u{16e70}', 0x16e50), ('\u{16e71}', 0x16e51), ('\u{16e72}', 0x16e52), + ('\u{16e73}', 0x16e53), ('\u{16e74}', 0x16e54), ('\u{16e75}', 0x16e55), + ('\u{16e76}', 0x16e56), ('\u{16e77}', 0x16e57), ('\u{16e78}', 0x16e58), + ('\u{16e79}', 0x16e59), ('\u{16e7a}', 0x16e5a), ('\u{16e7b}', 0x16e5b), + ('\u{16e7c}', 0x16e5c), ('\u{16e7d}', 0x16e5d), ('\u{16e7e}', 0x16e5e), + ('\u{16e7f}', 0x16e5f), ('\u{16ebb}', 0x16ea0), ('\u{16ebc}', 0x16ea1), + ('\u{16ebd}', 0x16ea2), ('\u{16ebe}', 0x16ea3), ('\u{16ebf}', 0x16ea4), + ('\u{16ec0}', 0x16ea5), ('\u{16ec1}', 0x16ea6), ('\u{16ec2}', 0x16ea7), + ('\u{16ec3}', 0x16ea8), ('\u{16ec4}', 0x16ea9), ('\u{16ec5}', 0x16eaa), + ('\u{16ec6}', 0x16eab), ('\u{16ec7}', 0x16eac), ('\u{16ec8}', 0x16ead), + ('\u{16ec9}', 0x16eae), ('\u{16eca}', 0x16eaf), ('\u{16ecb}', 0x16eb0), + ('\u{16ecc}', 0x16eb1), ('\u{16ecd}', 0x16eb2), ('\u{16ece}', 0x16eb3), + ('\u{16ecf}', 0x16eb4), ('\u{16ed0}', 0x16eb5), ('\u{16ed1}', 0x16eb6), + ('\u{16ed2}', 0x16eb7), ('\u{16ed3}', 0x16eb8), ('\u{1e922}', 0x1e900), + ('\u{1e923}', 0x1e901), ('\u{1e924}', 0x1e902), ('\u{1e925}', 0x1e903), + ('\u{1e926}', 0x1e904), ('\u{1e927}', 0x1e905), ('\u{1e928}', 0x1e906), + ('\u{1e929}', 0x1e907), ('\u{1e92a}', 0x1e908), ('\u{1e92b}', 0x1e909), + ('\u{1e92c}', 0x1e90a), ('\u{1e92d}', 0x1e90b), ('\u{1e92e}', 0x1e90c), + ('\u{1e92f}', 0x1e90d), ('\u{1e930}', 0x1e90e), ('\u{1e931}', 0x1e90f), + ('\u{1e932}', 0x1e910), ('\u{1e933}', 0x1e911), ('\u{1e934}', 0x1e912), + ('\u{1e935}', 0x1e913), ('\u{1e936}', 0x1e914), ('\u{1e937}', 0x1e915), + ('\u{1e938}', 0x1e916), ('\u{1e939}', 0x1e917), ('\u{1e93a}', 0x1e918), + ('\u{1e93b}', 0x1e919), ('\u{1e93c}', 0x1e91a), ('\u{1e93d}', 0x1e91b), + ('\u{1e93e}', 0x1e91c), ('\u{1e93f}', 0x1e91d), ('\u{1e940}', 0x1e91e), + ('\u{1e941}', 0x1e91f), ('\u{1e942}', 0x1e920), ('\u{1e943}', 0x1e921), ]; #[rustfmt::skip] - static LOWERCASE_TABLE_MULTI: &[[char; 3]; 1] = &[ - ['i', '\u{307}', '\u{0}'], + static UPPERCASE_TABLE_MULTI: &[[char; 3]; 102] = &[ + ['\u{53}', '\u{53}', '\u{0}'], ['\u{2bc}', '\u{4e}', '\u{0}'], + ['\u{4a}', '\u{30c}', '\u{0}'], ['\u{399}', '\u{308}', '\u{301}'], + ['\u{3a5}', '\u{308}', '\u{301}'], ['\u{535}', '\u{552}', '\u{0}'], + ['\u{48}', '\u{331}', '\u{0}'], ['\u{54}', '\u{308}', '\u{0}'], + ['\u{57}', '\u{30a}', '\u{0}'], ['\u{59}', '\u{30a}', '\u{0}'], + ['\u{41}', '\u{2be}', '\u{0}'], ['\u{3a5}', '\u{313}', '\u{0}'], + ['\u{3a5}', '\u{313}', '\u{300}'], ['\u{3a5}', '\u{313}', '\u{301}'], + ['\u{3a5}', '\u{313}', '\u{342}'], ['\u{1f08}', '\u{399}', '\u{0}'], + ['\u{1f09}', '\u{399}', '\u{0}'], ['\u{1f0a}', '\u{399}', '\u{0}'], + ['\u{1f0b}', '\u{399}', '\u{0}'], ['\u{1f0c}', '\u{399}', '\u{0}'], + ['\u{1f0d}', '\u{399}', '\u{0}'], ['\u{1f0e}', '\u{399}', '\u{0}'], + ['\u{1f0f}', '\u{399}', '\u{0}'], ['\u{1f08}', '\u{399}', '\u{0}'], + ['\u{1f09}', '\u{399}', '\u{0}'], ['\u{1f0a}', '\u{399}', '\u{0}'], + ['\u{1f0b}', '\u{399}', '\u{0}'], ['\u{1f0c}', '\u{399}', '\u{0}'], + ['\u{1f0d}', '\u{399}', '\u{0}'], ['\u{1f0e}', '\u{399}', '\u{0}'], + ['\u{1f0f}', '\u{399}', '\u{0}'], ['\u{1f28}', '\u{399}', '\u{0}'], + ['\u{1f29}', '\u{399}', '\u{0}'], ['\u{1f2a}', '\u{399}', '\u{0}'], + ['\u{1f2b}', '\u{399}', '\u{0}'], ['\u{1f2c}', '\u{399}', '\u{0}'], + ['\u{1f2d}', '\u{399}', '\u{0}'], ['\u{1f2e}', '\u{399}', '\u{0}'], + ['\u{1f2f}', '\u{399}', '\u{0}'], ['\u{1f28}', '\u{399}', '\u{0}'], + ['\u{1f29}', '\u{399}', '\u{0}'], ['\u{1f2a}', '\u{399}', '\u{0}'], + ['\u{1f2b}', '\u{399}', '\u{0}'], ['\u{1f2c}', '\u{399}', '\u{0}'], + ['\u{1f2d}', '\u{399}', '\u{0}'], ['\u{1f2e}', '\u{399}', '\u{0}'], + ['\u{1f2f}', '\u{399}', '\u{0}'], ['\u{1f68}', '\u{399}', '\u{0}'], + ['\u{1f69}', '\u{399}', '\u{0}'], ['\u{1f6a}', '\u{399}', '\u{0}'], + ['\u{1f6b}', '\u{399}', '\u{0}'], ['\u{1f6c}', '\u{399}', '\u{0}'], + ['\u{1f6d}', '\u{399}', '\u{0}'], ['\u{1f6e}', '\u{399}', '\u{0}'], + ['\u{1f6f}', '\u{399}', '\u{0}'], ['\u{1f68}', '\u{399}', '\u{0}'], + ['\u{1f69}', '\u{399}', '\u{0}'], ['\u{1f6a}', '\u{399}', '\u{0}'], + ['\u{1f6b}', '\u{399}', '\u{0}'], ['\u{1f6c}', '\u{399}', '\u{0}'], + ['\u{1f6d}', '\u{399}', '\u{0}'], ['\u{1f6e}', '\u{399}', '\u{0}'], + ['\u{1f6f}', '\u{399}', '\u{0}'], ['\u{1fba}', '\u{399}', '\u{0}'], + ['\u{391}', '\u{399}', '\u{0}'], ['\u{386}', '\u{399}', '\u{0}'], + ['\u{391}', '\u{342}', '\u{0}'], ['\u{391}', '\u{342}', '\u{399}'], + ['\u{391}', '\u{399}', '\u{0}'], ['\u{1fca}', '\u{399}', '\u{0}'], + ['\u{397}', '\u{399}', '\u{0}'], ['\u{389}', '\u{399}', '\u{0}'], + ['\u{397}', '\u{342}', '\u{0}'], ['\u{397}', '\u{342}', '\u{399}'], + ['\u{397}', '\u{399}', '\u{0}'], ['\u{399}', '\u{308}', '\u{300}'], + ['\u{399}', '\u{308}', '\u{301}'], ['\u{399}', '\u{342}', '\u{0}'], + ['\u{399}', '\u{308}', '\u{342}'], ['\u{3a5}', '\u{308}', '\u{300}'], + ['\u{3a5}', '\u{308}', '\u{301}'], ['\u{3a1}', '\u{313}', '\u{0}'], + ['\u{3a5}', '\u{342}', '\u{0}'], ['\u{3a5}', '\u{308}', '\u{342}'], + ['\u{1ffa}', '\u{399}', '\u{0}'], ['\u{3a9}', '\u{399}', '\u{0}'], + ['\u{38f}', '\u{399}', '\u{0}'], ['\u{3a9}', '\u{342}', '\u{0}'], + ['\u{3a9}', '\u{342}', '\u{399}'], ['\u{3a9}', '\u{399}', '\u{0}'], + ['\u{46}', '\u{46}', '\u{0}'], ['\u{46}', '\u{49}', '\u{0}'], ['\u{46}', '\u{4c}', '\u{0}'], + ['\u{46}', '\u{46}', '\u{49}'], ['\u{46}', '\u{46}', '\u{4c}'], + ['\u{53}', '\u{54}', '\u{0}'], ['\u{53}', '\u{54}', '\u{0}'], + ['\u{544}', '\u{546}', '\u{0}'], ['\u{544}', '\u{535}', '\u{0}'], + ['\u{544}', '\u{53b}', '\u{0}'], ['\u{54e}', '\u{546}', '\u{0}'], + ['\u{544}', '\u{53d}', '\u{0}'], ]; #[inline] @@ -1170,436 +1692,4 @@ pub mod conversions { ) } } - #[rustfmt::skip] - 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), - ('\u{ed}', 205), ('\u{ee}', 206), ('\u{ef}', 207), ('\u{f0}', 208), ('\u{f1}', 209), - ('\u{f2}', 210), ('\u{f3}', 211), ('\u{f4}', 212), ('\u{f5}', 213), ('\u{f6}', 214), - ('\u{f8}', 216), ('\u{f9}', 217), ('\u{fa}', 218), ('\u{fb}', 219), ('\u{fc}', 220), - ('\u{fd}', 221), ('\u{fe}', 222), ('\u{ff}', 376), ('\u{101}', 256), ('\u{103}', 258), - ('\u{105}', 260), ('\u{107}', 262), ('\u{109}', 264), ('\u{10b}', 266), ('\u{10d}', 268), - ('\u{10f}', 270), ('\u{111}', 272), ('\u{113}', 274), ('\u{115}', 276), ('\u{117}', 278), - ('\u{119}', 280), ('\u{11b}', 282), ('\u{11d}', 284), ('\u{11f}', 286), ('\u{121}', 288), - ('\u{123}', 290), ('\u{125}', 292), ('\u{127}', 294), ('\u{129}', 296), ('\u{12b}', 298), - ('\u{12d}', 300), ('\u{12f}', 302), ('\u{131}', 73), ('\u{133}', 306), ('\u{135}', 308), - ('\u{137}', 310), ('\u{13a}', 313), ('\u{13c}', 315), ('\u{13e}', 317), ('\u{140}', 319), - ('\u{142}', 321), ('\u{144}', 323), ('\u{146}', 325), ('\u{148}', 327), - ('\u{149}', 4194305), ('\u{14b}', 330), ('\u{14d}', 332), ('\u{14f}', 334), - ('\u{151}', 336), ('\u{153}', 338), ('\u{155}', 340), ('\u{157}', 342), ('\u{159}', 344), - ('\u{15b}', 346), ('\u{15d}', 348), ('\u{15f}', 350), ('\u{161}', 352), ('\u{163}', 354), - ('\u{165}', 356), ('\u{167}', 358), ('\u{169}', 360), ('\u{16b}', 362), ('\u{16d}', 364), - ('\u{16f}', 366), ('\u{171}', 368), ('\u{173}', 370), ('\u{175}', 372), ('\u{177}', 374), - ('\u{17a}', 377), ('\u{17c}', 379), ('\u{17e}', 381), ('\u{17f}', 83), ('\u{180}', 579), - ('\u{183}', 386), ('\u{185}', 388), ('\u{188}', 391), ('\u{18c}', 395), ('\u{192}', 401), - ('\u{195}', 502), ('\u{199}', 408), ('\u{19a}', 573), ('\u{19b}', 42972), ('\u{19e}', 544), - ('\u{1a1}', 416), ('\u{1a3}', 418), ('\u{1a5}', 420), ('\u{1a8}', 423), ('\u{1ad}', 428), - ('\u{1b0}', 431), ('\u{1b4}', 435), ('\u{1b6}', 437), ('\u{1b9}', 440), ('\u{1bd}', 444), - ('\u{1bf}', 503), ('\u{1c5}', 452), ('\u{1c6}', 452), ('\u{1c8}', 455), ('\u{1c9}', 455), - ('\u{1cb}', 458), ('\u{1cc}', 458), ('\u{1ce}', 461), ('\u{1d0}', 463), ('\u{1d2}', 465), - ('\u{1d4}', 467), ('\u{1d6}', 469), ('\u{1d8}', 471), ('\u{1da}', 473), ('\u{1dc}', 475), - ('\u{1dd}', 398), ('\u{1df}', 478), ('\u{1e1}', 480), ('\u{1e3}', 482), ('\u{1e5}', 484), - ('\u{1e7}', 486), ('\u{1e9}', 488), ('\u{1eb}', 490), ('\u{1ed}', 492), ('\u{1ef}', 494), - ('\u{1f0}', 4194306), ('\u{1f2}', 497), ('\u{1f3}', 497), ('\u{1f5}', 500), - ('\u{1f9}', 504), ('\u{1fb}', 506), ('\u{1fd}', 508), ('\u{1ff}', 510), ('\u{201}', 512), - ('\u{203}', 514), ('\u{205}', 516), ('\u{207}', 518), ('\u{209}', 520), ('\u{20b}', 522), - ('\u{20d}', 524), ('\u{20f}', 526), ('\u{211}', 528), ('\u{213}', 530), ('\u{215}', 532), - ('\u{217}', 534), ('\u{219}', 536), ('\u{21b}', 538), ('\u{21d}', 540), ('\u{21f}', 542), - ('\u{223}', 546), ('\u{225}', 548), ('\u{227}', 550), ('\u{229}', 552), ('\u{22b}', 554), - ('\u{22d}', 556), ('\u{22f}', 558), ('\u{231}', 560), ('\u{233}', 562), ('\u{23c}', 571), - ('\u{23f}', 11390), ('\u{240}', 11391), ('\u{242}', 577), ('\u{247}', 582), - ('\u{249}', 584), ('\u{24b}', 586), ('\u{24d}', 588), ('\u{24f}', 590), ('\u{250}', 11375), - ('\u{251}', 11373), ('\u{252}', 11376), ('\u{253}', 385), ('\u{254}', 390), - ('\u{256}', 393), ('\u{257}', 394), ('\u{259}', 399), ('\u{25b}', 400), ('\u{25c}', 42923), - ('\u{260}', 403), ('\u{261}', 42924), ('\u{263}', 404), ('\u{264}', 42955), - ('\u{265}', 42893), ('\u{266}', 42922), ('\u{268}', 407), ('\u{269}', 406), - ('\u{26a}', 42926), ('\u{26b}', 11362), ('\u{26c}', 42925), ('\u{26f}', 412), - ('\u{271}', 11374), ('\u{272}', 413), ('\u{275}', 415), ('\u{27d}', 11364), - ('\u{280}', 422), ('\u{282}', 42949), ('\u{283}', 425), ('\u{287}', 42929), - ('\u{288}', 430), ('\u{289}', 580), ('\u{28a}', 433), ('\u{28b}', 434), ('\u{28c}', 581), - ('\u{292}', 439), ('\u{29d}', 42930), ('\u{29e}', 42928), ('\u{345}', 921), - ('\u{371}', 880), ('\u{373}', 882), ('\u{377}', 886), ('\u{37b}', 1021), ('\u{37c}', 1022), - ('\u{37d}', 1023), ('\u{390}', 4194307), ('\u{3ac}', 902), ('\u{3ad}', 904), - ('\u{3ae}', 905), ('\u{3af}', 906), ('\u{3b0}', 4194308), ('\u{3b1}', 913), - ('\u{3b2}', 914), ('\u{3b3}', 915), ('\u{3b4}', 916), ('\u{3b5}', 917), ('\u{3b6}', 918), - ('\u{3b7}', 919), ('\u{3b8}', 920), ('\u{3b9}', 921), ('\u{3ba}', 922), ('\u{3bb}', 923), - ('\u{3bc}', 924), ('\u{3bd}', 925), ('\u{3be}', 926), ('\u{3bf}', 927), ('\u{3c0}', 928), - ('\u{3c1}', 929), ('\u{3c2}', 931), ('\u{3c3}', 931), ('\u{3c4}', 932), ('\u{3c5}', 933), - ('\u{3c6}', 934), ('\u{3c7}', 935), ('\u{3c8}', 936), ('\u{3c9}', 937), ('\u{3ca}', 938), - ('\u{3cb}', 939), ('\u{3cc}', 908), ('\u{3cd}', 910), ('\u{3ce}', 911), ('\u{3d0}', 914), - ('\u{3d1}', 920), ('\u{3d5}', 934), ('\u{3d6}', 928), ('\u{3d7}', 975), ('\u{3d9}', 984), - ('\u{3db}', 986), ('\u{3dd}', 988), ('\u{3df}', 990), ('\u{3e1}', 992), ('\u{3e3}', 994), - ('\u{3e5}', 996), ('\u{3e7}', 998), ('\u{3e9}', 1000), ('\u{3eb}', 1002), ('\u{3ed}', 1004), - ('\u{3ef}', 1006), ('\u{3f0}', 922), ('\u{3f1}', 929), ('\u{3f2}', 1017), ('\u{3f3}', 895), - ('\u{3f5}', 917), ('\u{3f8}', 1015), ('\u{3fb}', 1018), ('\u{430}', 1040), - ('\u{431}', 1041), ('\u{432}', 1042), ('\u{433}', 1043), ('\u{434}', 1044), - ('\u{435}', 1045), ('\u{436}', 1046), ('\u{437}', 1047), ('\u{438}', 1048), - ('\u{439}', 1049), ('\u{43a}', 1050), ('\u{43b}', 1051), ('\u{43c}', 1052), - ('\u{43d}', 1053), ('\u{43e}', 1054), ('\u{43f}', 1055), ('\u{440}', 1056), - ('\u{441}', 1057), ('\u{442}', 1058), ('\u{443}', 1059), ('\u{444}', 1060), - ('\u{445}', 1061), ('\u{446}', 1062), ('\u{447}', 1063), ('\u{448}', 1064), - ('\u{449}', 1065), ('\u{44a}', 1066), ('\u{44b}', 1067), ('\u{44c}', 1068), - ('\u{44d}', 1069), ('\u{44e}', 1070), ('\u{44f}', 1071), ('\u{450}', 1024), - ('\u{451}', 1025), ('\u{452}', 1026), ('\u{453}', 1027), ('\u{454}', 1028), - ('\u{455}', 1029), ('\u{456}', 1030), ('\u{457}', 1031), ('\u{458}', 1032), - ('\u{459}', 1033), ('\u{45a}', 1034), ('\u{45b}', 1035), ('\u{45c}', 1036), - ('\u{45d}', 1037), ('\u{45e}', 1038), ('\u{45f}', 1039), ('\u{461}', 1120), - ('\u{463}', 1122), ('\u{465}', 1124), ('\u{467}', 1126), ('\u{469}', 1128), - ('\u{46b}', 1130), ('\u{46d}', 1132), ('\u{46f}', 1134), ('\u{471}', 1136), - ('\u{473}', 1138), ('\u{475}', 1140), ('\u{477}', 1142), ('\u{479}', 1144), - ('\u{47b}', 1146), ('\u{47d}', 1148), ('\u{47f}', 1150), ('\u{481}', 1152), - ('\u{48b}', 1162), ('\u{48d}', 1164), ('\u{48f}', 1166), ('\u{491}', 1168), - ('\u{493}', 1170), ('\u{495}', 1172), ('\u{497}', 1174), ('\u{499}', 1176), - ('\u{49b}', 1178), ('\u{49d}', 1180), ('\u{49f}', 1182), ('\u{4a1}', 1184), - ('\u{4a3}', 1186), ('\u{4a5}', 1188), ('\u{4a7}', 1190), ('\u{4a9}', 1192), - ('\u{4ab}', 1194), ('\u{4ad}', 1196), ('\u{4af}', 1198), ('\u{4b1}', 1200), - ('\u{4b3}', 1202), ('\u{4b5}', 1204), ('\u{4b7}', 1206), ('\u{4b9}', 1208), - ('\u{4bb}', 1210), ('\u{4bd}', 1212), ('\u{4bf}', 1214), ('\u{4c2}', 1217), - ('\u{4c4}', 1219), ('\u{4c6}', 1221), ('\u{4c8}', 1223), ('\u{4ca}', 1225), - ('\u{4cc}', 1227), ('\u{4ce}', 1229), ('\u{4cf}', 1216), ('\u{4d1}', 1232), - ('\u{4d3}', 1234), ('\u{4d5}', 1236), ('\u{4d7}', 1238), ('\u{4d9}', 1240), - ('\u{4db}', 1242), ('\u{4dd}', 1244), ('\u{4df}', 1246), ('\u{4e1}', 1248), - ('\u{4e3}', 1250), ('\u{4e5}', 1252), ('\u{4e7}', 1254), ('\u{4e9}', 1256), - ('\u{4eb}', 1258), ('\u{4ed}', 1260), ('\u{4ef}', 1262), ('\u{4f1}', 1264), - ('\u{4f3}', 1266), ('\u{4f5}', 1268), ('\u{4f7}', 1270), ('\u{4f9}', 1272), - ('\u{4fb}', 1274), ('\u{4fd}', 1276), ('\u{4ff}', 1278), ('\u{501}', 1280), - ('\u{503}', 1282), ('\u{505}', 1284), ('\u{507}', 1286), ('\u{509}', 1288), - ('\u{50b}', 1290), ('\u{50d}', 1292), ('\u{50f}', 1294), ('\u{511}', 1296), - ('\u{513}', 1298), ('\u{515}', 1300), ('\u{517}', 1302), ('\u{519}', 1304), - ('\u{51b}', 1306), ('\u{51d}', 1308), ('\u{51f}', 1310), ('\u{521}', 1312), - ('\u{523}', 1314), ('\u{525}', 1316), ('\u{527}', 1318), ('\u{529}', 1320), - ('\u{52b}', 1322), ('\u{52d}', 1324), ('\u{52f}', 1326), ('\u{561}', 1329), - ('\u{562}', 1330), ('\u{563}', 1331), ('\u{564}', 1332), ('\u{565}', 1333), - ('\u{566}', 1334), ('\u{567}', 1335), ('\u{568}', 1336), ('\u{569}', 1337), - ('\u{56a}', 1338), ('\u{56b}', 1339), ('\u{56c}', 1340), ('\u{56d}', 1341), - ('\u{56e}', 1342), ('\u{56f}', 1343), ('\u{570}', 1344), ('\u{571}', 1345), - ('\u{572}', 1346), ('\u{573}', 1347), ('\u{574}', 1348), ('\u{575}', 1349), - ('\u{576}', 1350), ('\u{577}', 1351), ('\u{578}', 1352), ('\u{579}', 1353), - ('\u{57a}', 1354), ('\u{57b}', 1355), ('\u{57c}', 1356), ('\u{57d}', 1357), - ('\u{57e}', 1358), ('\u{57f}', 1359), ('\u{580}', 1360), ('\u{581}', 1361), - ('\u{582}', 1362), ('\u{583}', 1363), ('\u{584}', 1364), ('\u{585}', 1365), - ('\u{586}', 1366), ('\u{587}', 4194309), ('\u{10d0}', 7312), ('\u{10d1}', 7313), - ('\u{10d2}', 7314), ('\u{10d3}', 7315), ('\u{10d4}', 7316), ('\u{10d5}', 7317), - ('\u{10d6}', 7318), ('\u{10d7}', 7319), ('\u{10d8}', 7320), ('\u{10d9}', 7321), - ('\u{10da}', 7322), ('\u{10db}', 7323), ('\u{10dc}', 7324), ('\u{10dd}', 7325), - ('\u{10de}', 7326), ('\u{10df}', 7327), ('\u{10e0}', 7328), ('\u{10e1}', 7329), - ('\u{10e2}', 7330), ('\u{10e3}', 7331), ('\u{10e4}', 7332), ('\u{10e5}', 7333), - ('\u{10e6}', 7334), ('\u{10e7}', 7335), ('\u{10e8}', 7336), ('\u{10e9}', 7337), - ('\u{10ea}', 7338), ('\u{10eb}', 7339), ('\u{10ec}', 7340), ('\u{10ed}', 7341), - ('\u{10ee}', 7342), ('\u{10ef}', 7343), ('\u{10f0}', 7344), ('\u{10f1}', 7345), - ('\u{10f2}', 7346), ('\u{10f3}', 7347), ('\u{10f4}', 7348), ('\u{10f5}', 7349), - ('\u{10f6}', 7350), ('\u{10f7}', 7351), ('\u{10f8}', 7352), ('\u{10f9}', 7353), - ('\u{10fa}', 7354), ('\u{10fd}', 7357), ('\u{10fe}', 7358), ('\u{10ff}', 7359), - ('\u{13f8}', 5104), ('\u{13f9}', 5105), ('\u{13fa}', 5106), ('\u{13fb}', 5107), - ('\u{13fc}', 5108), ('\u{13fd}', 5109), ('\u{1c80}', 1042), ('\u{1c81}', 1044), - ('\u{1c82}', 1054), ('\u{1c83}', 1057), ('\u{1c84}', 1058), ('\u{1c85}', 1058), - ('\u{1c86}', 1066), ('\u{1c87}', 1122), ('\u{1c88}', 42570), ('\u{1c8a}', 7305), - ('\u{1d79}', 42877), ('\u{1d7d}', 11363), ('\u{1d8e}', 42950), ('\u{1e01}', 7680), - ('\u{1e03}', 7682), ('\u{1e05}', 7684), ('\u{1e07}', 7686), ('\u{1e09}', 7688), - ('\u{1e0b}', 7690), ('\u{1e0d}', 7692), ('\u{1e0f}', 7694), ('\u{1e11}', 7696), - ('\u{1e13}', 7698), ('\u{1e15}', 7700), ('\u{1e17}', 7702), ('\u{1e19}', 7704), - ('\u{1e1b}', 7706), ('\u{1e1d}', 7708), ('\u{1e1f}', 7710), ('\u{1e21}', 7712), - ('\u{1e23}', 7714), ('\u{1e25}', 7716), ('\u{1e27}', 7718), ('\u{1e29}', 7720), - ('\u{1e2b}', 7722), ('\u{1e2d}', 7724), ('\u{1e2f}', 7726), ('\u{1e31}', 7728), - ('\u{1e33}', 7730), ('\u{1e35}', 7732), ('\u{1e37}', 7734), ('\u{1e39}', 7736), - ('\u{1e3b}', 7738), ('\u{1e3d}', 7740), ('\u{1e3f}', 7742), ('\u{1e41}', 7744), - ('\u{1e43}', 7746), ('\u{1e45}', 7748), ('\u{1e47}', 7750), ('\u{1e49}', 7752), - ('\u{1e4b}', 7754), ('\u{1e4d}', 7756), ('\u{1e4f}', 7758), ('\u{1e51}', 7760), - ('\u{1e53}', 7762), ('\u{1e55}', 7764), ('\u{1e57}', 7766), ('\u{1e59}', 7768), - ('\u{1e5b}', 7770), ('\u{1e5d}', 7772), ('\u{1e5f}', 7774), ('\u{1e61}', 7776), - ('\u{1e63}', 7778), ('\u{1e65}', 7780), ('\u{1e67}', 7782), ('\u{1e69}', 7784), - ('\u{1e6b}', 7786), ('\u{1e6d}', 7788), ('\u{1e6f}', 7790), ('\u{1e71}', 7792), - ('\u{1e73}', 7794), ('\u{1e75}', 7796), ('\u{1e77}', 7798), ('\u{1e79}', 7800), - ('\u{1e7b}', 7802), ('\u{1e7d}', 7804), ('\u{1e7f}', 7806), ('\u{1e81}', 7808), - ('\u{1e83}', 7810), ('\u{1e85}', 7812), ('\u{1e87}', 7814), ('\u{1e89}', 7816), - ('\u{1e8b}', 7818), ('\u{1e8d}', 7820), ('\u{1e8f}', 7822), ('\u{1e91}', 7824), - ('\u{1e93}', 7826), ('\u{1e95}', 7828), ('\u{1e96}', 4194310), ('\u{1e97}', 4194311), - ('\u{1e98}', 4194312), ('\u{1e99}', 4194313), ('\u{1e9a}', 4194314), ('\u{1e9b}', 7776), - ('\u{1ea1}', 7840), ('\u{1ea3}', 7842), ('\u{1ea5}', 7844), ('\u{1ea7}', 7846), - ('\u{1ea9}', 7848), ('\u{1eab}', 7850), ('\u{1ead}', 7852), ('\u{1eaf}', 7854), - ('\u{1eb1}', 7856), ('\u{1eb3}', 7858), ('\u{1eb5}', 7860), ('\u{1eb7}', 7862), - ('\u{1eb9}', 7864), ('\u{1ebb}', 7866), ('\u{1ebd}', 7868), ('\u{1ebf}', 7870), - ('\u{1ec1}', 7872), ('\u{1ec3}', 7874), ('\u{1ec5}', 7876), ('\u{1ec7}', 7878), - ('\u{1ec9}', 7880), ('\u{1ecb}', 7882), ('\u{1ecd}', 7884), ('\u{1ecf}', 7886), - ('\u{1ed1}', 7888), ('\u{1ed3}', 7890), ('\u{1ed5}', 7892), ('\u{1ed7}', 7894), - ('\u{1ed9}', 7896), ('\u{1edb}', 7898), ('\u{1edd}', 7900), ('\u{1edf}', 7902), - ('\u{1ee1}', 7904), ('\u{1ee3}', 7906), ('\u{1ee5}', 7908), ('\u{1ee7}', 7910), - ('\u{1ee9}', 7912), ('\u{1eeb}', 7914), ('\u{1eed}', 7916), ('\u{1eef}', 7918), - ('\u{1ef1}', 7920), ('\u{1ef3}', 7922), ('\u{1ef5}', 7924), ('\u{1ef7}', 7926), - ('\u{1ef9}', 7928), ('\u{1efb}', 7930), ('\u{1efd}', 7932), ('\u{1eff}', 7934), - ('\u{1f00}', 7944), ('\u{1f01}', 7945), ('\u{1f02}', 7946), ('\u{1f03}', 7947), - ('\u{1f04}', 7948), ('\u{1f05}', 7949), ('\u{1f06}', 7950), ('\u{1f07}', 7951), - ('\u{1f10}', 7960), ('\u{1f11}', 7961), ('\u{1f12}', 7962), ('\u{1f13}', 7963), - ('\u{1f14}', 7964), ('\u{1f15}', 7965), ('\u{1f20}', 7976), ('\u{1f21}', 7977), - ('\u{1f22}', 7978), ('\u{1f23}', 7979), ('\u{1f24}', 7980), ('\u{1f25}', 7981), - ('\u{1f26}', 7982), ('\u{1f27}', 7983), ('\u{1f30}', 7992), ('\u{1f31}', 7993), - ('\u{1f32}', 7994), ('\u{1f33}', 7995), ('\u{1f34}', 7996), ('\u{1f35}', 7997), - ('\u{1f36}', 7998), ('\u{1f37}', 7999), ('\u{1f40}', 8008), ('\u{1f41}', 8009), - ('\u{1f42}', 8010), ('\u{1f43}', 8011), ('\u{1f44}', 8012), ('\u{1f45}', 8013), - ('\u{1f50}', 4194315), ('\u{1f51}', 8025), ('\u{1f52}', 4194316), ('\u{1f53}', 8027), - ('\u{1f54}', 4194317), ('\u{1f55}', 8029), ('\u{1f56}', 4194318), ('\u{1f57}', 8031), - ('\u{1f60}', 8040), ('\u{1f61}', 8041), ('\u{1f62}', 8042), ('\u{1f63}', 8043), - ('\u{1f64}', 8044), ('\u{1f65}', 8045), ('\u{1f66}', 8046), ('\u{1f67}', 8047), - ('\u{1f70}', 8122), ('\u{1f71}', 8123), ('\u{1f72}', 8136), ('\u{1f73}', 8137), - ('\u{1f74}', 8138), ('\u{1f75}', 8139), ('\u{1f76}', 8154), ('\u{1f77}', 8155), - ('\u{1f78}', 8184), ('\u{1f79}', 8185), ('\u{1f7a}', 8170), ('\u{1f7b}', 8171), - ('\u{1f7c}', 8186), ('\u{1f7d}', 8187), ('\u{1f80}', 4194319), ('\u{1f81}', 4194320), - ('\u{1f82}', 4194321), ('\u{1f83}', 4194322), ('\u{1f84}', 4194323), ('\u{1f85}', 4194324), - ('\u{1f86}', 4194325), ('\u{1f87}', 4194326), ('\u{1f88}', 4194327), ('\u{1f89}', 4194328), - ('\u{1f8a}', 4194329), ('\u{1f8b}', 4194330), ('\u{1f8c}', 4194331), ('\u{1f8d}', 4194332), - ('\u{1f8e}', 4194333), ('\u{1f8f}', 4194334), ('\u{1f90}', 4194335), ('\u{1f91}', 4194336), - ('\u{1f92}', 4194337), ('\u{1f93}', 4194338), ('\u{1f94}', 4194339), ('\u{1f95}', 4194340), - ('\u{1f96}', 4194341), ('\u{1f97}', 4194342), ('\u{1f98}', 4194343), ('\u{1f99}', 4194344), - ('\u{1f9a}', 4194345), ('\u{1f9b}', 4194346), ('\u{1f9c}', 4194347), ('\u{1f9d}', 4194348), - ('\u{1f9e}', 4194349), ('\u{1f9f}', 4194350), ('\u{1fa0}', 4194351), ('\u{1fa1}', 4194352), - ('\u{1fa2}', 4194353), ('\u{1fa3}', 4194354), ('\u{1fa4}', 4194355), ('\u{1fa5}', 4194356), - ('\u{1fa6}', 4194357), ('\u{1fa7}', 4194358), ('\u{1fa8}', 4194359), ('\u{1fa9}', 4194360), - ('\u{1faa}', 4194361), ('\u{1fab}', 4194362), ('\u{1fac}', 4194363), ('\u{1fad}', 4194364), - ('\u{1fae}', 4194365), ('\u{1faf}', 4194366), ('\u{1fb0}', 8120), ('\u{1fb1}', 8121), - ('\u{1fb2}', 4194367), ('\u{1fb3}', 4194368), ('\u{1fb4}', 4194369), ('\u{1fb6}', 4194370), - ('\u{1fb7}', 4194371), ('\u{1fbc}', 4194372), ('\u{1fbe}', 921), ('\u{1fc2}', 4194373), - ('\u{1fc3}', 4194374), ('\u{1fc4}', 4194375), ('\u{1fc6}', 4194376), ('\u{1fc7}', 4194377), - ('\u{1fcc}', 4194378), ('\u{1fd0}', 8152), ('\u{1fd1}', 8153), ('\u{1fd2}', 4194379), - ('\u{1fd3}', 4194380), ('\u{1fd6}', 4194381), ('\u{1fd7}', 4194382), ('\u{1fe0}', 8168), - ('\u{1fe1}', 8169), ('\u{1fe2}', 4194383), ('\u{1fe3}', 4194384), ('\u{1fe4}', 4194385), - ('\u{1fe5}', 8172), ('\u{1fe6}', 4194386), ('\u{1fe7}', 4194387), ('\u{1ff2}', 4194388), - ('\u{1ff3}', 4194389), ('\u{1ff4}', 4194390), ('\u{1ff6}', 4194391), ('\u{1ff7}', 4194392), - ('\u{1ffc}', 4194393), ('\u{214e}', 8498), ('\u{2170}', 8544), ('\u{2171}', 8545), - ('\u{2172}', 8546), ('\u{2173}', 8547), ('\u{2174}', 8548), ('\u{2175}', 8549), - ('\u{2176}', 8550), ('\u{2177}', 8551), ('\u{2178}', 8552), ('\u{2179}', 8553), - ('\u{217a}', 8554), ('\u{217b}', 8555), ('\u{217c}', 8556), ('\u{217d}', 8557), - ('\u{217e}', 8558), ('\u{217f}', 8559), ('\u{2184}', 8579), ('\u{24d0}', 9398), - ('\u{24d1}', 9399), ('\u{24d2}', 9400), ('\u{24d3}', 9401), ('\u{24d4}', 9402), - ('\u{24d5}', 9403), ('\u{24d6}', 9404), ('\u{24d7}', 9405), ('\u{24d8}', 9406), - ('\u{24d9}', 9407), ('\u{24da}', 9408), ('\u{24db}', 9409), ('\u{24dc}', 9410), - ('\u{24dd}', 9411), ('\u{24de}', 9412), ('\u{24df}', 9413), ('\u{24e0}', 9414), - ('\u{24e1}', 9415), ('\u{24e2}', 9416), ('\u{24e3}', 9417), ('\u{24e4}', 9418), - ('\u{24e5}', 9419), ('\u{24e6}', 9420), ('\u{24e7}', 9421), ('\u{24e8}', 9422), - ('\u{24e9}', 9423), ('\u{2c30}', 11264), ('\u{2c31}', 11265), ('\u{2c32}', 11266), - ('\u{2c33}', 11267), ('\u{2c34}', 11268), ('\u{2c35}', 11269), ('\u{2c36}', 11270), - ('\u{2c37}', 11271), ('\u{2c38}', 11272), ('\u{2c39}', 11273), ('\u{2c3a}', 11274), - ('\u{2c3b}', 11275), ('\u{2c3c}', 11276), ('\u{2c3d}', 11277), ('\u{2c3e}', 11278), - ('\u{2c3f}', 11279), ('\u{2c40}', 11280), ('\u{2c41}', 11281), ('\u{2c42}', 11282), - ('\u{2c43}', 11283), ('\u{2c44}', 11284), ('\u{2c45}', 11285), ('\u{2c46}', 11286), - ('\u{2c47}', 11287), ('\u{2c48}', 11288), ('\u{2c49}', 11289), ('\u{2c4a}', 11290), - ('\u{2c4b}', 11291), ('\u{2c4c}', 11292), ('\u{2c4d}', 11293), ('\u{2c4e}', 11294), - ('\u{2c4f}', 11295), ('\u{2c50}', 11296), ('\u{2c51}', 11297), ('\u{2c52}', 11298), - ('\u{2c53}', 11299), ('\u{2c54}', 11300), ('\u{2c55}', 11301), ('\u{2c56}', 11302), - ('\u{2c57}', 11303), ('\u{2c58}', 11304), ('\u{2c59}', 11305), ('\u{2c5a}', 11306), - ('\u{2c5b}', 11307), ('\u{2c5c}', 11308), ('\u{2c5d}', 11309), ('\u{2c5e}', 11310), - ('\u{2c5f}', 11311), ('\u{2c61}', 11360), ('\u{2c65}', 570), ('\u{2c66}', 574), - ('\u{2c68}', 11367), ('\u{2c6a}', 11369), ('\u{2c6c}', 11371), ('\u{2c73}', 11378), - ('\u{2c76}', 11381), ('\u{2c81}', 11392), ('\u{2c83}', 11394), ('\u{2c85}', 11396), - ('\u{2c87}', 11398), ('\u{2c89}', 11400), ('\u{2c8b}', 11402), ('\u{2c8d}', 11404), - ('\u{2c8f}', 11406), ('\u{2c91}', 11408), ('\u{2c93}', 11410), ('\u{2c95}', 11412), - ('\u{2c97}', 11414), ('\u{2c99}', 11416), ('\u{2c9b}', 11418), ('\u{2c9d}', 11420), - ('\u{2c9f}', 11422), ('\u{2ca1}', 11424), ('\u{2ca3}', 11426), ('\u{2ca5}', 11428), - ('\u{2ca7}', 11430), ('\u{2ca9}', 11432), ('\u{2cab}', 11434), ('\u{2cad}', 11436), - ('\u{2caf}', 11438), ('\u{2cb1}', 11440), ('\u{2cb3}', 11442), ('\u{2cb5}', 11444), - ('\u{2cb7}', 11446), ('\u{2cb9}', 11448), ('\u{2cbb}', 11450), ('\u{2cbd}', 11452), - ('\u{2cbf}', 11454), ('\u{2cc1}', 11456), ('\u{2cc3}', 11458), ('\u{2cc5}', 11460), - ('\u{2cc7}', 11462), ('\u{2cc9}', 11464), ('\u{2ccb}', 11466), ('\u{2ccd}', 11468), - ('\u{2ccf}', 11470), ('\u{2cd1}', 11472), ('\u{2cd3}', 11474), ('\u{2cd5}', 11476), - ('\u{2cd7}', 11478), ('\u{2cd9}', 11480), ('\u{2cdb}', 11482), ('\u{2cdd}', 11484), - ('\u{2cdf}', 11486), ('\u{2ce1}', 11488), ('\u{2ce3}', 11490), ('\u{2cec}', 11499), - ('\u{2cee}', 11501), ('\u{2cf3}', 11506), ('\u{2d00}', 4256), ('\u{2d01}', 4257), - ('\u{2d02}', 4258), ('\u{2d03}', 4259), ('\u{2d04}', 4260), ('\u{2d05}', 4261), - ('\u{2d06}', 4262), ('\u{2d07}', 4263), ('\u{2d08}', 4264), ('\u{2d09}', 4265), - ('\u{2d0a}', 4266), ('\u{2d0b}', 4267), ('\u{2d0c}', 4268), ('\u{2d0d}', 4269), - ('\u{2d0e}', 4270), ('\u{2d0f}', 4271), ('\u{2d10}', 4272), ('\u{2d11}', 4273), - ('\u{2d12}', 4274), ('\u{2d13}', 4275), ('\u{2d14}', 4276), ('\u{2d15}', 4277), - ('\u{2d16}', 4278), ('\u{2d17}', 4279), ('\u{2d18}', 4280), ('\u{2d19}', 4281), - ('\u{2d1a}', 4282), ('\u{2d1b}', 4283), ('\u{2d1c}', 4284), ('\u{2d1d}', 4285), - ('\u{2d1e}', 4286), ('\u{2d1f}', 4287), ('\u{2d20}', 4288), ('\u{2d21}', 4289), - ('\u{2d22}', 4290), ('\u{2d23}', 4291), ('\u{2d24}', 4292), ('\u{2d25}', 4293), - ('\u{2d27}', 4295), ('\u{2d2d}', 4301), ('\u{a641}', 42560), ('\u{a643}', 42562), - ('\u{a645}', 42564), ('\u{a647}', 42566), ('\u{a649}', 42568), ('\u{a64b}', 42570), - ('\u{a64d}', 42572), ('\u{a64f}', 42574), ('\u{a651}', 42576), ('\u{a653}', 42578), - ('\u{a655}', 42580), ('\u{a657}', 42582), ('\u{a659}', 42584), ('\u{a65b}', 42586), - ('\u{a65d}', 42588), ('\u{a65f}', 42590), ('\u{a661}', 42592), ('\u{a663}', 42594), - ('\u{a665}', 42596), ('\u{a667}', 42598), ('\u{a669}', 42600), ('\u{a66b}', 42602), - ('\u{a66d}', 42604), ('\u{a681}', 42624), ('\u{a683}', 42626), ('\u{a685}', 42628), - ('\u{a687}', 42630), ('\u{a689}', 42632), ('\u{a68b}', 42634), ('\u{a68d}', 42636), - ('\u{a68f}', 42638), ('\u{a691}', 42640), ('\u{a693}', 42642), ('\u{a695}', 42644), - ('\u{a697}', 42646), ('\u{a699}', 42648), ('\u{a69b}', 42650), ('\u{a723}', 42786), - ('\u{a725}', 42788), ('\u{a727}', 42790), ('\u{a729}', 42792), ('\u{a72b}', 42794), - ('\u{a72d}', 42796), ('\u{a72f}', 42798), ('\u{a733}', 42802), ('\u{a735}', 42804), - ('\u{a737}', 42806), ('\u{a739}', 42808), ('\u{a73b}', 42810), ('\u{a73d}', 42812), - ('\u{a73f}', 42814), ('\u{a741}', 42816), ('\u{a743}', 42818), ('\u{a745}', 42820), - ('\u{a747}', 42822), ('\u{a749}', 42824), ('\u{a74b}', 42826), ('\u{a74d}', 42828), - ('\u{a74f}', 42830), ('\u{a751}', 42832), ('\u{a753}', 42834), ('\u{a755}', 42836), - ('\u{a757}', 42838), ('\u{a759}', 42840), ('\u{a75b}', 42842), ('\u{a75d}', 42844), - ('\u{a75f}', 42846), ('\u{a761}', 42848), ('\u{a763}', 42850), ('\u{a765}', 42852), - ('\u{a767}', 42854), ('\u{a769}', 42856), ('\u{a76b}', 42858), ('\u{a76d}', 42860), - ('\u{a76f}', 42862), ('\u{a77a}', 42873), ('\u{a77c}', 42875), ('\u{a77f}', 42878), - ('\u{a781}', 42880), ('\u{a783}', 42882), ('\u{a785}', 42884), ('\u{a787}', 42886), - ('\u{a78c}', 42891), ('\u{a791}', 42896), ('\u{a793}', 42898), ('\u{a794}', 42948), - ('\u{a797}', 42902), ('\u{a799}', 42904), ('\u{a79b}', 42906), ('\u{a79d}', 42908), - ('\u{a79f}', 42910), ('\u{a7a1}', 42912), ('\u{a7a3}', 42914), ('\u{a7a5}', 42916), - ('\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{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), - ('\u{1e931}', 125199), ('\u{1e932}', 125200), ('\u{1e933}', 125201), ('\u{1e934}', 125202), - ('\u{1e935}', 125203), ('\u{1e936}', 125204), ('\u{1e937}', 125205), ('\u{1e938}', 125206), - ('\u{1e939}', 125207), ('\u{1e93a}', 125208), ('\u{1e93b}', 125209), ('\u{1e93c}', 125210), - ('\u{1e93d}', 125211), ('\u{1e93e}', 125212), ('\u{1e93f}', 125213), ('\u{1e940}', 125214), - ('\u{1e941}', 125215), ('\u{1e942}', 125216), ('\u{1e943}', 125217), - ]; - - #[rustfmt::skip] - static UPPERCASE_TABLE_MULTI: &[[char; 3]; 102] = &[ - ['S', 'S', '\u{0}'], ['\u{2bc}', 'N', '\u{0}'], ['J', '\u{30c}', '\u{0}'], - ['\u{399}', '\u{308}', '\u{301}'], ['\u{3a5}', '\u{308}', '\u{301}'], - ['\u{535}', '\u{552}', '\u{0}'], ['H', '\u{331}', '\u{0}'], ['T', '\u{308}', '\u{0}'], - ['W', '\u{30a}', '\u{0}'], ['Y', '\u{30a}', '\u{0}'], ['A', '\u{2be}', '\u{0}'], - ['\u{3a5}', '\u{313}', '\u{0}'], ['\u{3a5}', '\u{313}', '\u{300}'], - ['\u{3a5}', '\u{313}', '\u{301}'], ['\u{3a5}', '\u{313}', '\u{342}'], - ['\u{1f08}', '\u{399}', '\u{0}'], ['\u{1f09}', '\u{399}', '\u{0}'], - ['\u{1f0a}', '\u{399}', '\u{0}'], ['\u{1f0b}', '\u{399}', '\u{0}'], - ['\u{1f0c}', '\u{399}', '\u{0}'], ['\u{1f0d}', '\u{399}', '\u{0}'], - ['\u{1f0e}', '\u{399}', '\u{0}'], ['\u{1f0f}', '\u{399}', '\u{0}'], - ['\u{1f08}', '\u{399}', '\u{0}'], ['\u{1f09}', '\u{399}', '\u{0}'], - ['\u{1f0a}', '\u{399}', '\u{0}'], ['\u{1f0b}', '\u{399}', '\u{0}'], - ['\u{1f0c}', '\u{399}', '\u{0}'], ['\u{1f0d}', '\u{399}', '\u{0}'], - ['\u{1f0e}', '\u{399}', '\u{0}'], ['\u{1f0f}', '\u{399}', '\u{0}'], - ['\u{1f28}', '\u{399}', '\u{0}'], ['\u{1f29}', '\u{399}', '\u{0}'], - ['\u{1f2a}', '\u{399}', '\u{0}'], ['\u{1f2b}', '\u{399}', '\u{0}'], - ['\u{1f2c}', '\u{399}', '\u{0}'], ['\u{1f2d}', '\u{399}', '\u{0}'], - ['\u{1f2e}', '\u{399}', '\u{0}'], ['\u{1f2f}', '\u{399}', '\u{0}'], - ['\u{1f28}', '\u{399}', '\u{0}'], ['\u{1f29}', '\u{399}', '\u{0}'], - ['\u{1f2a}', '\u{399}', '\u{0}'], ['\u{1f2b}', '\u{399}', '\u{0}'], - ['\u{1f2c}', '\u{399}', '\u{0}'], ['\u{1f2d}', '\u{399}', '\u{0}'], - ['\u{1f2e}', '\u{399}', '\u{0}'], ['\u{1f2f}', '\u{399}', '\u{0}'], - ['\u{1f68}', '\u{399}', '\u{0}'], ['\u{1f69}', '\u{399}', '\u{0}'], - ['\u{1f6a}', '\u{399}', '\u{0}'], ['\u{1f6b}', '\u{399}', '\u{0}'], - ['\u{1f6c}', '\u{399}', '\u{0}'], ['\u{1f6d}', '\u{399}', '\u{0}'], - ['\u{1f6e}', '\u{399}', '\u{0}'], ['\u{1f6f}', '\u{399}', '\u{0}'], - ['\u{1f68}', '\u{399}', '\u{0}'], ['\u{1f69}', '\u{399}', '\u{0}'], - ['\u{1f6a}', '\u{399}', '\u{0}'], ['\u{1f6b}', '\u{399}', '\u{0}'], - ['\u{1f6c}', '\u{399}', '\u{0}'], ['\u{1f6d}', '\u{399}', '\u{0}'], - ['\u{1f6e}', '\u{399}', '\u{0}'], ['\u{1f6f}', '\u{399}', '\u{0}'], - ['\u{1fba}', '\u{399}', '\u{0}'], ['\u{391}', '\u{399}', '\u{0}'], - ['\u{386}', '\u{399}', '\u{0}'], ['\u{391}', '\u{342}', '\u{0}'], - ['\u{391}', '\u{342}', '\u{399}'], ['\u{391}', '\u{399}', '\u{0}'], - ['\u{1fca}', '\u{399}', '\u{0}'], ['\u{397}', '\u{399}', '\u{0}'], - ['\u{389}', '\u{399}', '\u{0}'], ['\u{397}', '\u{342}', '\u{0}'], - ['\u{397}', '\u{342}', '\u{399}'], ['\u{397}', '\u{399}', '\u{0}'], - ['\u{399}', '\u{308}', '\u{300}'], ['\u{399}', '\u{308}', '\u{301}'], - ['\u{399}', '\u{342}', '\u{0}'], ['\u{399}', '\u{308}', '\u{342}'], - ['\u{3a5}', '\u{308}', '\u{300}'], ['\u{3a5}', '\u{308}', '\u{301}'], - ['\u{3a1}', '\u{313}', '\u{0}'], ['\u{3a5}', '\u{342}', '\u{0}'], - ['\u{3a5}', '\u{308}', '\u{342}'], ['\u{1ffa}', '\u{399}', '\u{0}'], - ['\u{3a9}', '\u{399}', '\u{0}'], ['\u{38f}', '\u{399}', '\u{0}'], - ['\u{3a9}', '\u{342}', '\u{0}'], ['\u{3a9}', '\u{342}', '\u{399}'], - ['\u{3a9}', '\u{399}', '\u{0}'], ['F', 'F', '\u{0}'], ['F', 'I', '\u{0}'], - ['F', 'L', '\u{0}'], ['F', 'F', 'I'], ['F', 'F', 'L'], ['S', 'T', '\u{0}'], - ['S', 'T', '\u{0}'], ['\u{544}', '\u{546}', '\u{0}'], ['\u{544}', '\u{535}', '\u{0}'], - ['\u{544}', '\u{53b}', '\u{0}'], ['\u{54e}', '\u{546}', '\u{0}'], - ['\u{544}', '\u{53d}', '\u{0}'], - ]; } diff --git a/src/tools/unicode-table-generator/src/cascading_map.rs b/src/tools/unicode-table-generator/src/cascading_map.rs index 56e6401908dcf..41124a8e85ee5 100644 --- a/src/tools/unicode-table-generator/src/cascading_map.rs +++ b/src/tools/unicode-table-generator/src/cascading_map.rs @@ -1,9 +1,8 @@ use std::collections::HashMap; -use std::fmt::Write as _; use std::ops::Range; -use crate::fmt_list; use crate::raw_emitter::RawEmitter; +use crate::writeln; impl RawEmitter { pub fn emit_cascading_map(&mut self, ranges: &[Range]) -> bool { @@ -24,8 +23,6 @@ impl RawEmitter { .flat_map(|r| (r.start..r.end).collect::>()) .collect::>(); - println!("there are {} points", points.len()); - // how many distinct ranges need to be counted? let mut codepoints_by_high_bytes = HashMap::>::new(); for point in points { @@ -37,7 +34,7 @@ impl RawEmitter { } let mut bit_for_high_byte = 1u8; - let mut arms = Vec::::new(); + let mut arms = String::new(); let mut high_bytes: Vec = codepoints_by_high_bytes.keys().copied().collect(); high_bytes.sort(); @@ -45,33 +42,33 @@ impl RawEmitter { let codepoints = codepoints_by_high_bytes.get_mut(&high_byte).unwrap(); if codepoints.len() == 1 { let ch = codepoints.pop().unwrap(); - arms.push(format!("{high_byte} => c as u32 == {ch:#04x}")); + writeln!(arms, "{high_byte:#04x} => c as u32 == {ch:#04x},"); continue; } // more than 1 codepoint in this arm for codepoint in codepoints { map[(*codepoint & 0xff) as usize] |= bit_for_high_byte; } - arms.push(format!( - "{high_byte} => WHITESPACE_MAP[c as usize & 0xff] & {bit_for_high_byte} != 0" - )); + writeln!( + arms, + "{high_byte:#04x} => WHITESPACE_MAP[c as usize & 0xff] & {bit_for_high_byte} != 0," + ); bit_for_high_byte <<= 1; } - writeln!(&mut self.file, "static WHITESPACE_MAP: [u8; 256] = [{}];", fmt_list(map.iter())) - .unwrap(); self.bytes_used += 256; + self.file = format!( + "static WHITESPACE_MAP: [u8; 256] = {map:?}; - writeln!(&mut self.file, "#[inline]").unwrap(); - writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap(); - writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); - writeln!(&mut self.file, " match c as u32 >> 8 {{").unwrap(); - for arm in arms { - writeln!(&mut self.file, " {arm},").unwrap(); - } - writeln!(&mut self.file, " _ => false,").unwrap(); - writeln!(&mut self.file, " }}").unwrap(); - writeln!(&mut self.file, "}}").unwrap(); + #[inline] + pub const fn lookup(c: char) -> bool {{ + debug_assert!(!c.is_ascii()); + match c as u32 >> 8 {{ + {arms}\ + _ => false, + }} + }}" + ); true } diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index ae9705d67f83b..3280514692b07 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -1,19 +1,18 @@ use std::char; use std::collections::BTreeMap; -use std::fmt::{self, Write}; -use crate::{UnicodeData, fmt_list}; +use crate::fmt_helpers::Hex; +use crate::{CharEscape, UnicodeData, fmt_list}; const INDEX_MASK: u32 = 1 << 22; pub(crate) fn generate_case_mapping(data: &UnicodeData) -> (String, [usize; 2]) { - let mut file = String::new(); - let (lower_tables, lower_size) = generate_tables("LOWER", &data.to_lower); - file.push_str(&lower_tables); - file.push_str("\n\n"); let (upper_tables, upper_size) = generate_tables("UPPER", &data.to_upper); - file.push_str(&upper_tables); + let file = format!( + "{lower_tables} + {upper_tables}" + ); (file, [lower_size, upper_size]) } @@ -43,14 +42,18 @@ fn generate_tables(case: &str, data: &BTreeMap) -> (String, usize INDEX_MASK | (u32::try_from(multis.len()).unwrap() - 1) }; - mappings.push((CharEscape(key), value)); + mappings.push((CharEscape(key), Hex(value))); } - let mut size = 0; - let mut tables = String::new(); - writeln!( - tables, - "\ + let size = size_of_val(mappings.as_slice()) + size_of_val(multis.as_slice()); + let file = format!( + " +#[rustfmt::skip] +static {case}CASE_TABLE: &[(char, u32); {mappings_len}] = &[{mappings}]; + +#[rustfmt::skip] +static {case}CASE_TABLE_MULTI: &[[char; 3]; {multis_len}] = &[{multis}]; + #[inline] pub fn to_{case_lower}(c: char) -> [char; 3] {{ const {{ @@ -81,40 +84,7 @@ pub fn to_{case_lower}(c: char) -> [char; 3] {{ mappings_len = mappings.len(), multis = fmt_list(&multis), multis_len = multis.len(), - ) - .unwrap(); - - size += size_of_val(mappings.as_slice()); - writeln!(tables, "#[rustfmt::skip]").unwrap(); - write!( - tables, - "static {}CASE_TABLE: &[(char, u32); {}] = &[{}];", - case, - mappings.len(), - fmt_list(mappings), - ) - .unwrap(); - - tables.push_str("\n\n"); + ); - size += size_of_val(multis.as_slice()); - writeln!(tables, "#[rustfmt::skip]").unwrap(); - write!( - tables, - "static {}CASE_TABLE_MULTI: &[[char; 3]; {}] = &[{}];", - case, - multis.len(), - fmt_list(multis), - ) - .unwrap(); - - (tables, size) -} - -struct CharEscape(char); - -impl fmt::Debug for CharEscape { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "'{}'", self.0.escape_default()) - } + (file, size) } diff --git a/src/tools/unicode-table-generator/src/fmt_helpers.rs b/src/tools/unicode-table-generator/src/fmt_helpers.rs new file mode 100644 index 0000000000000..bd7417ca11008 --- /dev/null +++ b/src/tools/unicode-table-generator/src/fmt_helpers.rs @@ -0,0 +1,82 @@ +use std::fmt; + +// Convenience macros for writing and unwrapping. +#[macro_export] +macro_rules! writeln { + ($($args:tt)*) => {{ + use std::fmt::Write as _; + std::writeln!($($args)*).unwrap(); + }}; +} +#[macro_export] +macro_rules! write { + ($($args:tt)*) => {{ + use std::fmt::Write as _; + std::write!($($args)*).unwrap(); + }}; +} + +pub fn fmt_list(values: impl IntoIterator) -> String { + let pieces = values.into_iter().map(|b| format!("{b:?}, ")); + let mut out = String::new(); + let mut line = String::from("\n "); + for piece in pieces { + if line.len() + piece.len() < 98 { + line.push_str(&piece); + } else { + writeln!(out, "{}", line.trim_end()); + line = format!(" {piece}"); + } + } + writeln!(out, "{}", line.trim_end()); + out +} + +/// Wrapper type for formatting a `T` using its `Binary` implementation. +#[derive(Copy, Clone)] +pub struct Bin(pub T); + +impl fmt::Debug for Bin { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let bits = size_of::() * 8; + std::write!(f, "0b{:0bits$b}", self.0) + } +} + +impl fmt::Display for Bin { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self, f) + } +} + +/// Wrapper type for formatting a `T` using its `LowerHex` implementation. +#[derive(Copy, Clone)] +pub struct Hex(pub T); + +impl fmt::Debug for Hex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + std::write!(f, "{:#x}", self.0) + } +} + +impl fmt::Display for Hex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self, f) + } +} + +/// Wrapper type for formatting a `char` using `escape_unicode`. +#[derive(Copy, Clone)] +pub struct CharEscape(pub char); + +impl fmt::Debug for CharEscape { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + std::write!(f, "'{}'", self.0.escape_unicode()) + } +} + +impl fmt::Display for CharEscape { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self, f) + } +} diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index 2f6cde9d49b6f..c2c5650136959 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -72,18 +72,18 @@ //! or not. use std::collections::{BTreeMap, HashMap}; -use std::fmt; -use std::fmt::Write; use std::ops::Range; use ucd_parse::Codepoints; mod cascading_map; mod case_mapping; +mod fmt_helpers; mod raw_emitter; mod skiplist; mod unicode_download; +use fmt_helpers::*; use raw_emitter::{RawEmitter, emit_codepoints, emit_whitespace}; static PROPERTIES: &[&str] = &[ @@ -224,12 +224,13 @@ fn main() { let ranges_by_property = &unicode_data.ranges; if let Some(path) = test_path { - std::fs::write(&path, generate_tests(&unicode_data).unwrap()).unwrap(); + std::fs::write(&path, generate_tests(&unicode_data)).unwrap(); } let mut table_file = String::new(); - table_file.push_str( - "//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!\n", + writeln!( + table_file, + "//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!", ); let mut total_bytes = 0; @@ -245,8 +246,9 @@ fn main() { } modules.push((property.to_lowercase().to_string(), emitter.file)); - table_file.push_str(&format!( - "// {:16}: {:5} bytes, {:6} codepoints in {:3} ranges (U+{:06X} - U+{:06X}) using {}\n", + writeln!( + table_file, + "// {:16}: {:5} bytes, {:6} codepoints in {:3} ranges (U+{:06X} - U+{:06X}) using {}", property, emitter.bytes_used, datapoints, @@ -254,36 +256,30 @@ fn main() { ranges.first().unwrap().start, ranges.last().unwrap().end, emitter.desc, - )); + ); total_bytes += emitter.bytes_used; } let (conversions, sizes) = case_mapping::generate_case_mapping(&unicode_data); for (name, size) in ["to_lower", "to_upper"].iter().zip(sizes) { - table_file.push_str(&format!("// {:16}: {:5} bytes\n", name, size)); + writeln!(table_file, "// {:16}: {:5} bytes", name, size); total_bytes += size; } - table_file.push_str(&format!("// {:16}: {:5} bytes\n", "Total", total_bytes)); + writeln!(table_file, "// {:16}: {:5} bytes\n", "Total", total_bytes); - table_file.push('\n'); - table_file.push_str("use super::rt::*;\n"); - table_file.push_str(&version()); - table_file.push('\n'); + writeln!(table_file, "use super::rt::*;\n"); + writeln!(table_file, "{}\n", version()); modules.push((String::from("conversions"), conversions)); for (name, contents) in modules { - table_file.push_str(&format!("pub mod {name} {{\n")); - for line in contents.lines() { - if !line.trim().is_empty() { - table_file.push_str(" "); - table_file.push_str(line); - } - table_file.push('\n'); + writeln!(table_file, "pub mod {name} {{"); + for line in contents.trim().lines() { + writeln!(table_file, " {line}"); } - table_file.push_str("}\n\n"); + writeln!(table_file, "}}\n"); } - std::fs::write(&write_location, format!("{}\n", table_file.trim_end())).unwrap(); + std::fs::write(&write_location, table_file).unwrap(); rustfmt(&write_location); } @@ -292,9 +288,6 @@ fn rustfmt(path: &str) { } fn version() -> String { - let mut out = String::new(); - out.push_str("pub const UNICODE_VERSION: (u8, u8, u8) = "); - let readme = std::fs::read_to_string(std::path::Path::new(UNICODE_DIRECTORY).join("ReadMe.txt")) .unwrap(); @@ -306,66 +299,44 @@ fn version() -> String { readme[start..end].split('.').map(|v| v.parse::().expect(v)).collect::>(); let [major, minor, micro] = [version[0], version[1], version[2]]; - out.push_str(&format!("({major}, {minor}, {micro});\n")); - out -} - -fn fmt_list(values: impl IntoIterator) -> String { - let pieces = values.into_iter().map(|b| format!("{b:?}, ")).collect::>(); - let mut out = String::new(); - let mut line = String::from("\n "); - for piece in pieces { - if line.len() + piece.len() < 98 { - line.push_str(&piece); - } else { - out.push_str(line.trim_end()); - out.push('\n'); - line = format!(" {piece}"); - } - } - out.push_str(line.trim_end()); - out.push('\n'); - out + format!("pub const UNICODE_VERSION: (u8, u8, u8) = ({major}, {minor}, {micro});") } -fn generate_tests(data: &UnicodeData) -> Result { - let mut s = String::new(); - writeln!(s, "#![feature(core_intrinsics)]")?; - writeln!(s, "#![allow(internal_features, dead_code)]")?; - writeln!(s, "// ignore-tidy-filelength")?; - writeln!(s, "use std::intrinsics;")?; - writeln!(s, "mod rt;")?; - writeln!(s, "mod unicode_data;")?; - writeln!(s, "fn main() {{")?; +fn generate_tests(data: &UnicodeData) -> String { + let mut s = format!( + "#![feature(core_intrinsics)] + #![allow(internal_features, dead_code)] + // ignore-tidy-filelength + mod rt; + mod unicode_data; + fn main() {{" + ); for (property, ranges) in &data.ranges { let prop = property.to_lowercase(); - writeln!(s, r#" println!("Testing {prop}");"#)?; - writeln!(s, " {prop}_true();")?; - writeln!(s, " {prop}_false();")?; let (is_true, is_false): (Vec<_>, Vec<_>) = (char::MIN..=char::MAX) .filter(|c| !c.is_ascii()) .map(u32::from) .partition(|c| ranges.iter().any(|r| r.contains(c))); - writeln!(s, " fn {prop}_true() {{")?; - generate_asserts(&mut s, &prop, &is_true, true)?; - writeln!(s, " }}")?; - - writeln!(s, " fn {prop}_false() {{")?; - generate_asserts(&mut s, &prop, &is_false, false)?; - writeln!(s, " }}")?; + writeln!( + s, + "println!(\"Testing {prop}\"); + {prop}_true(); + {prop}_false(); + fn {prop}_true() {{\n{}\n}} + fn {prop}_false() {{\n{}\n}}", + generate_asserts(&prop, &is_true, true), + generate_asserts(&prop, &is_false, false) + ); } for (name, conversion) in ["to_lower", "to_upper"].iter().zip([&data.to_lower, &data.to_upper]) { - writeln!(s, r#" println!("Testing {name}");"#)?; + writeln!(s, r#"println!("Testing {name}");"#); for (c, mapping) in conversion { let c = char::from_u32(*c).unwrap(); let mapping = mapping.map(|c| char::from_u32(c).unwrap()); - writeln!( - s, - r#" assert_eq!(unicode_data::conversions::{name}({c:?}), {mapping:?});"# - )?; + writeln!(s, "assert_eq!(unicode_data::conversions::{name}({c:?}), {mapping:?});"); } let unmapped: Vec<_> = (char::MIN..=char::MAX) .filter(|c| !c.is_ascii()) @@ -376,40 +347,36 @@ fn generate_tests(data: &UnicodeData) -> Result { for range in unmapped_ranges { let start = char::from_u32(range.start).unwrap(); let end = char::from_u32(range.end - 1).unwrap(); - writeln!(s, " for c in {start:?}..={end:?} {{")?; writeln!( s, - r#" assert_eq!(unicode_data::conversions::{name}(c), [c, '\0', '\0']);"# - )?; - - writeln!(s, " }}")?; + r#"for c in {start:?}..={end:?} {{ + assert_eq!(unicode_data::conversions::{name}(c), [c, '\0', '\0']); + }}"# + ); } } - writeln!(s, "}}")?; - Ok(s) + writeln!(s, "}}"); + s } -fn generate_asserts( - s: &mut String, - prop: &str, - points: &[u32], - truthy: bool, -) -> Result<(), fmt::Error> { +fn generate_asserts(prop: &str, points: &[u32], truthy: bool) -> String { + let mut s = String::new(); let truthy = if truthy { "" } else { "!" }; for range in ranges_from_set(points) { let start = char::from_u32(range.start).unwrap(); let end = char::from_u32(range.end - 1).unwrap(); match range.len() { - 1 => writeln!(s, " assert!({truthy}unicode_data::{prop}::lookup({start:?}));")?, - _ => { - writeln!(s, " for c in {start:?}..={end:?} {{")?; - writeln!(s, " assert!({truthy}unicode_data::{prop}::lookup(c));")?; - writeln!(s, " }}")?; - } + 1 => writeln!(s, "assert!({truthy}unicode_data::{prop}::lookup({start:?}));"), + _ => writeln!( + s, + "for c in {start:?}..={end:?} {{ + assert!({truthy}unicode_data::{prop}::lookup(c)); + }}" + ), } } - Ok(()) + s } /// Group the elements of `set` into contigous ranges diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs index 297965615c1a5..048507a06d44f 100644 --- a/src/tools/unicode-table-generator/src/raw_emitter.rs +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -1,8 +1,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap}; -use std::fmt::{self, Write}; use std::ops::Range; -use crate::fmt_list; +use crate::{Bin, fmt_list, writeln}; #[derive(Clone)] pub struct RawEmitter { @@ -16,13 +15,6 @@ impl RawEmitter { RawEmitter { file: String::new(), bytes_used: 0, desc: String::new() } } - fn blank_line(&mut self) { - if self.file.is_empty() || self.file.ends_with("\n\n") { - return; - } - writeln!(&mut self.file).unwrap(); - } - fn emit_bitset(&mut self, ranges: &[Range]) -> Result<(), String> { let first_code_point = ranges.first().unwrap().start; let last_code_point = ranges.last().unwrap().end; @@ -68,48 +60,33 @@ impl RawEmitter { } self.emit_chunk_map(word_indices[&0], &compressed_words, best.unwrap().0); - struct Bits(u64); - impl fmt::Debug for Bits { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "0b{:064b}", self.0) - } - } - - writeln!( - &mut self.file, - "static BITSET_CANONICAL: [u64; {}] = [{}];", - canonicalized.canonical_words.len(), - fmt_list(canonicalized.canonical_words.iter().map(|v| Bits(*v))), - ) - .unwrap(); self.bytes_used += 8 * canonicalized.canonical_words.len(); - writeln!( - &mut self.file, - "static BITSET_MAPPING: [(u8, u8); {}] = [{}];", - canonicalized.canonicalized_words.len(), - fmt_list(&canonicalized.canonicalized_words), - ) - .unwrap(); // 8 bit index into shifted words, 7 bits for shift + optional flip // We only need it for the words that we removed by applying a shift and // flip to them. self.bytes_used += 2 * canonicalized.canonicalized_words.len(); - self.blank_line(); - - writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap(); - writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); - if first_code_point > 0x7f { - writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} &&").unwrap(); - } - writeln!(&mut self.file, " super::bitset_search(").unwrap(); - writeln!(&mut self.file, " c as u32,").unwrap(); - writeln!(&mut self.file, " &BITSET_CHUNKS_MAP,").unwrap(); - writeln!(&mut self.file, " &BITSET_INDEX_CHUNKS,").unwrap(); - writeln!(&mut self.file, " &BITSET_CANONICAL,").unwrap(); - writeln!(&mut self.file, " &BITSET_MAPPING,").unwrap(); - writeln!(&mut self.file, " )").unwrap(); - writeln!(&mut self.file, "}}").unwrap(); + writeln!( + self.file, + "static BITSET_CANONICAL: [u64; {canonical_words_len}] = {canonical_words:?}; + static BITSET_MAPPING: [(u8, u8); {canonicalized_words_len}] = {canonicalized_words:?}; + + pub const fn lookup(c: char) -> bool {{ + debug_assert!(!c.is_ascii()); + (c as u32) >= {first_code_point:#04x} && + super::bitset_search( + c as u32, + &BITSET_CHUNKS_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET_CANONICAL, + &BITSET_MAPPING, + ) + }}", + canonical_words = canonicalized.canonical_words, + canonical_words_len = canonicalized.canonical_words.len(), + canonicalized_words = canonicalized.canonicalized_words, + canonicalized_words_len = canonicalized.canonicalized_words.len(), + ); Ok(()) } @@ -133,29 +110,21 @@ impl RawEmitter { chunk_indices.push(chunk_map[chunk]); } - writeln!( - &mut self.file, - "static BITSET_CHUNKS_MAP: [u8; {}] = [{}];", - chunk_indices.len(), - fmt_list(&chunk_indices), - ) - .unwrap(); self.bytes_used += chunk_indices.len(); writeln!( - &mut self.file, - "static BITSET_INDEX_CHUNKS: [[u8; {}]; {}] = [{}];", - chunk_length, - chunks.len(), - fmt_list(chunks.iter()), - ) - .unwrap(); + self.file, + "static BITSET_CHUNKS_MAP: [u8; {chunk_indices_len}] = {chunk_indices:?}; + static BITSET_INDEX_CHUNKS: [[u8; {chunk_len}]; {chunks_len}] = [{chunks}];", + chunk_indices_len = chunk_indices.len(), + chunk_len = chunk_length, + chunks_len = chunks.len(), + chunks = fmt_list(chunks.iter()), + ); self.bytes_used += chunk_length * chunks.len(); } } pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range]) { - emitter.blank_line(); - let mut bitset = emitter.clone(); let bitset_ok = bitset.emit_bitset(ranges).is_ok(); @@ -172,8 +141,6 @@ pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range]) { } pub fn emit_whitespace(emitter: &mut RawEmitter, ranges: &[Range]) { - emitter.blank_line(); - let mut cascading = emitter.clone(); cascading.emit_cascading_map(ranges); *emitter = cascading; @@ -181,7 +148,7 @@ pub fn emit_whitespace(emitter: &mut RawEmitter, ranges: &[Range]) { } struct Canonicalized { - canonical_words: Vec, + canonical_words: Vec>, canonicalized_words: Vec<(u8, u8)>, /// Maps an input unique word to the associated index (u8) which is into @@ -394,6 +361,7 @@ impl Canonicalized { ) }) .collect::>(); + let canonical_words = canonical_words.into_iter().map(Bin).collect::>(); Canonicalized { unique_mapping, canonical_words, canonicalized_words } } } diff --git a/src/tools/unicode-table-generator/src/skiplist.rs b/src/tools/unicode-table-generator/src/skiplist.rs index 9b38fd4864f10..742d61153db3d 100644 --- a/src/tools/unicode-table-generator/src/skiplist.rs +++ b/src/tools/unicode-table-generator/src/skiplist.rs @@ -1,8 +1,8 @@ -use std::fmt::{self, Write as _}; +use std::fmt::{self}; use std::ops::Range; -use crate::fmt_list; use crate::raw_emitter::RawEmitter; +use crate::writeln; /// This will get packed into a single u32 before inserting into the data set. #[derive(PartialEq)] @@ -68,22 +68,7 @@ impl RawEmitter { assert!(inserted); } - writeln!(&mut self.file, "use super::ShortOffsetRunHeader;\n").unwrap(); - writeln!( - &mut self.file, - "static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; {}] = [{}];", - short_offset_runs.len(), - fmt_list(short_offset_runs.iter()) - ) - .unwrap(); self.bytes_used += 4 * short_offset_runs.len(); - writeln!( - &mut self.file, - "static OFFSETS: [u8; {}] = [{}];", - coded_offsets.len(), - fmt_list(&coded_offsets) - ) - .unwrap(); self.bytes_used += coded_offsets.len(); // The inlining in this code works like the following: @@ -94,46 +79,34 @@ impl RawEmitter { // The lower-bounds check is inlined into the caller, and slower-path // `skip_search` is outlined into a separate `lookup_slow` fn. assert!(first_code_point > 0x7f); - writeln!(&mut self.file, "#[inline]").unwrap(); - writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); - writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); - writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} && lookup_slow(c)") - .unwrap(); - writeln!(&mut self.file, "}}").unwrap(); - writeln!(&mut self.file).unwrap(); - writeln!(&mut self.file, "#[inline(never)]").unwrap(); - writeln!(&mut self.file, "fn lookup_slow(c: char) -> bool {{").unwrap(); - writeln!(&mut self.file, " const {{").unwrap(); - writeln!( - &mut self.file, - " assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);", - ) - .unwrap(); - writeln!(&mut self.file, " let mut i = 0;").unwrap(); - writeln!(&mut self.file, " while i < SHORT_OFFSET_RUNS.len() {{").unwrap(); - writeln!( - &mut self.file, - " assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());", - ) - .unwrap(); - writeln!(&mut self.file, " i += 1;").unwrap(); - writeln!(&mut self.file, " }}").unwrap(); - writeln!(&mut self.file, " }}").unwrap(); - writeln!( - &mut self.file, - " // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`", - ) - .unwrap(); - writeln!( - &mut self.file, - " // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.", - ) - .unwrap(); - writeln!( - &mut self.file, - " unsafe {{ super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }}" - ) - .unwrap(); - writeln!(&mut self.file, "}}").unwrap(); + writeln!(self.file, + "use super::ShortOffsetRunHeader; + + static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; {short_offset_runs_len}] = {short_offset_runs:?}; + static OFFSETS: [u8; {coded_offset_len}] = {coded_offsets:?}; + + #[inline] + pub fn lookup(c: char) -> bool {{ + debug_assert!(!c.is_ascii()); + (c as u32) >= {first_code_point:#04x} && lookup_slow(c) + }} + + #[inline(never)] + fn lookup_slow(c: char) -> bool {{ + const {{ + assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32); + let mut i = 0; + while i < SHORT_OFFSET_RUNS.len() {{ + assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len()); + i += 1; + }} + }} + // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX` + // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`. + unsafe {{ super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }} + }}", + short_offset_runs_len = short_offset_runs.len(), + coded_offset_len = coded_offsets.len(), + ); } } From 0e6131c9aad0668f08a4a08672c74ac140feae13 Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Mon, 20 Oct 2025 00:17:09 +0100 Subject: [PATCH 30/45] refactor: make `unicode_data` tests normal tests Instead of generating a standalone executable to test `unicode_data`, generate normal tests in `coretests`. This ensures tests are always generated, and will be run as part of the normal testsuite. Also change the generated tests to loop over lookup tables, rather than generating a separate `assert_eq!()` statement for every codepoint. The old approach produced a massive (20,000 lines plus) file which took minutes to compile! --- library/core/src/unicode/mod.rs | 2 +- library/coretests/tests/lib.rs | 1 + library/coretests/tests/unicode.rs | 96 + library/coretests/tests/unicode/test_data.rs | 2928 +++++++++++++++++ src/bootstrap/src/core/build_steps/run.rs | 1 + src/tools/unicode-table-generator/src/main.rs | 137 +- 6 files changed, 3090 insertions(+), 75 deletions(-) create mode 100644 library/coretests/tests/unicode/test_data.rs diff --git a/library/core/src/unicode/mod.rs b/library/core/src/unicode/mod.rs index 9bc4136517fae..1ee97d64d01bc 100644 --- a/library/core/src/unicode/mod.rs +++ b/library/core/src/unicode/mod.rs @@ -20,7 +20,7 @@ pub(crate) mod printable; mod rt; #[allow(unreachable_pub)] -mod unicode_data; +pub mod unicode_data; /// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of /// `char` and `str` methods are based on. diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index c2dc3a99ab109..2f00197f82bb3 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -111,6 +111,7 @@ #![feature(try_find)] #![feature(try_trait_v2)] #![feature(uint_bit_width)] +#![feature(unicode_internals)] #![feature(unsize)] #![feature(unwrap_infallible)] // tidy-alphabetical-end diff --git a/library/coretests/tests/unicode.rs b/library/coretests/tests/unicode.rs index bbace0ef66ca3..445175c685784 100644 --- a/library/coretests/tests/unicode.rs +++ b/library/coretests/tests/unicode.rs @@ -1,5 +1,101 @@ +use core::unicode::unicode_data; +use std::ops::RangeInclusive; + +mod test_data; + #[test] pub fn version() { let (major, _minor, _update) = core::char::UNICODE_VERSION; assert!(major >= 10); } + +#[track_caller] +fn test_boolean_property(ranges: &[RangeInclusive], lookup: fn(char) -> bool) { + let mut start = '\u{80}'; + for range in ranges { + for c in start..*range.start() { + assert!(!lookup(c), "{c:?}"); + } + for c in range.clone() { + assert!(lookup(c), "{c:?}"); + } + start = char::from_u32(*range.end() as u32 + 1).unwrap(); + } + for c in start..=char::MAX { + assert!(!lookup(c), "{c:?}"); + } +} + +#[track_caller] +fn test_case_mapping(ranges: &[(char, [char; 3])], lookup: fn(char) -> [char; 3]) { + let mut start = '\u{80}'; + for &(key, val) in ranges { + for c in start..key { + assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); + } + assert_eq!(lookup(key), val, "{key:?}"); + start = char::from_u32(key as u32 + 1).unwrap(); + } + for c in start..=char::MAX { + assert_eq!(lookup(c), [c, '\0', '\0'], "{c:?}"); + } +} + +#[test] +#[cfg_attr(miri, ignore)] +fn alphabetic() { + test_boolean_property(test_data::ALPHABETIC, unicode_data::alphabetic::lookup); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn case_ignorable() { + test_boolean_property(test_data::CASE_IGNORABLE, unicode_data::case_ignorable::lookup); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn cased() { + test_boolean_property(test_data::CASED, unicode_data::cased::lookup); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn grapheme_extend() { + test_boolean_property(test_data::GRAPHEME_EXTEND, unicode_data::grapheme_extend::lookup); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn lowercase() { + test_boolean_property(test_data::LOWERCASE, unicode_data::lowercase::lookup); +} + +#[test] +fn n() { + test_boolean_property(test_data::N, unicode_data::n::lookup); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn uppercase() { + test_boolean_property(test_data::UPPERCASE, unicode_data::uppercase::lookup); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn white_space() { + test_boolean_property(test_data::WHITE_SPACE, unicode_data::white_space::lookup); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn to_lowercase() { + test_case_mapping(test_data::TO_LOWER, unicode_data::conversions::to_lower); +} + +#[test] +#[cfg_attr(miri, ignore)] +fn to_uppercase() { + test_case_mapping(test_data::TO_UPPER, unicode_data::conversions::to_upper); +} diff --git a/library/coretests/tests/unicode/test_data.rs b/library/coretests/tests/unicode/test_data.rs new file mode 100644 index 0000000000000..f53cd7dc22705 --- /dev/null +++ b/library/coretests/tests/unicode/test_data.rs @@ -0,0 +1,2928 @@ +//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually! +// ignore-tidy-filelength + +use std::ops::RangeInclusive; + +#[rustfmt::skip] +pub(super) static ALPHABETIC: &[RangeInclusive; 759] = &[ + '\u{aa}'..='\u{aa}', '\u{b5}'..='\u{b5}', '\u{ba}'..='\u{ba}', '\u{c0}'..='\u{d6}', + '\u{d8}'..='\u{f6}', '\u{f8}'..='\u{2c1}', '\u{2c6}'..='\u{2d1}', '\u{2e0}'..='\u{2e4}', + '\u{2ec}'..='\u{2ec}', '\u{2ee}'..='\u{2ee}', '\u{345}'..='\u{345}', '\u{363}'..='\u{374}', + '\u{376}'..='\u{377}', '\u{37a}'..='\u{37d}', '\u{37f}'..='\u{37f}', '\u{386}'..='\u{386}', + '\u{388}'..='\u{38a}', '\u{38c}'..='\u{38c}', '\u{38e}'..='\u{3a1}', '\u{3a3}'..='\u{3f5}', + '\u{3f7}'..='\u{481}', '\u{48a}'..='\u{52f}', '\u{531}'..='\u{556}', '\u{559}'..='\u{559}', + '\u{560}'..='\u{588}', '\u{5b0}'..='\u{5bd}', '\u{5bf}'..='\u{5bf}', '\u{5c1}'..='\u{5c2}', + '\u{5c4}'..='\u{5c5}', '\u{5c7}'..='\u{5c7}', '\u{5d0}'..='\u{5ea}', '\u{5ef}'..='\u{5f2}', + '\u{610}'..='\u{61a}', '\u{620}'..='\u{657}', '\u{659}'..='\u{65f}', '\u{66e}'..='\u{6d3}', + '\u{6d5}'..='\u{6dc}', '\u{6e1}'..='\u{6e8}', '\u{6ed}'..='\u{6ef}', '\u{6fa}'..='\u{6fc}', + '\u{6ff}'..='\u{6ff}', '\u{710}'..='\u{73f}', '\u{74d}'..='\u{7b1}', '\u{7ca}'..='\u{7ea}', + '\u{7f4}'..='\u{7f5}', '\u{7fa}'..='\u{7fa}', '\u{800}'..='\u{817}', '\u{81a}'..='\u{82c}', + '\u{840}'..='\u{858}', '\u{860}'..='\u{86a}', '\u{870}'..='\u{887}', '\u{889}'..='\u{88f}', + '\u{897}'..='\u{897}', '\u{8a0}'..='\u{8c9}', '\u{8d4}'..='\u{8df}', '\u{8e3}'..='\u{8e9}', + '\u{8f0}'..='\u{93b}', '\u{93d}'..='\u{94c}', '\u{94e}'..='\u{950}', '\u{955}'..='\u{963}', + '\u{971}'..='\u{983}', '\u{985}'..='\u{98c}', '\u{98f}'..='\u{990}', '\u{993}'..='\u{9a8}', + '\u{9aa}'..='\u{9b0}', '\u{9b2}'..='\u{9b2}', '\u{9b6}'..='\u{9b9}', '\u{9bd}'..='\u{9c4}', + '\u{9c7}'..='\u{9c8}', '\u{9cb}'..='\u{9cc}', '\u{9ce}'..='\u{9ce}', '\u{9d7}'..='\u{9d7}', + '\u{9dc}'..='\u{9dd}', '\u{9df}'..='\u{9e3}', '\u{9f0}'..='\u{9f1}', '\u{9fc}'..='\u{9fc}', + '\u{a01}'..='\u{a03}', '\u{a05}'..='\u{a0a}', '\u{a0f}'..='\u{a10}', '\u{a13}'..='\u{a28}', + '\u{a2a}'..='\u{a30}', '\u{a32}'..='\u{a33}', '\u{a35}'..='\u{a36}', '\u{a38}'..='\u{a39}', + '\u{a3e}'..='\u{a42}', '\u{a47}'..='\u{a48}', '\u{a4b}'..='\u{a4c}', '\u{a51}'..='\u{a51}', + '\u{a59}'..='\u{a5c}', '\u{a5e}'..='\u{a5e}', '\u{a70}'..='\u{a75}', '\u{a81}'..='\u{a83}', + '\u{a85}'..='\u{a8d}', '\u{a8f}'..='\u{a91}', '\u{a93}'..='\u{aa8}', '\u{aaa}'..='\u{ab0}', + '\u{ab2}'..='\u{ab3}', '\u{ab5}'..='\u{ab9}', '\u{abd}'..='\u{ac5}', '\u{ac7}'..='\u{ac9}', + '\u{acb}'..='\u{acc}', '\u{ad0}'..='\u{ad0}', '\u{ae0}'..='\u{ae3}', '\u{af9}'..='\u{afc}', + '\u{b01}'..='\u{b03}', '\u{b05}'..='\u{b0c}', '\u{b0f}'..='\u{b10}', '\u{b13}'..='\u{b28}', + '\u{b2a}'..='\u{b30}', '\u{b32}'..='\u{b33}', '\u{b35}'..='\u{b39}', '\u{b3d}'..='\u{b44}', + '\u{b47}'..='\u{b48}', '\u{b4b}'..='\u{b4c}', '\u{b56}'..='\u{b57}', '\u{b5c}'..='\u{b5d}', + '\u{b5f}'..='\u{b63}', '\u{b71}'..='\u{b71}', '\u{b82}'..='\u{b83}', '\u{b85}'..='\u{b8a}', + '\u{b8e}'..='\u{b90}', '\u{b92}'..='\u{b95}', '\u{b99}'..='\u{b9a}', '\u{b9c}'..='\u{b9c}', + '\u{b9e}'..='\u{b9f}', '\u{ba3}'..='\u{ba4}', '\u{ba8}'..='\u{baa}', '\u{bae}'..='\u{bb9}', + '\u{bbe}'..='\u{bc2}', '\u{bc6}'..='\u{bc8}', '\u{bca}'..='\u{bcc}', '\u{bd0}'..='\u{bd0}', + '\u{bd7}'..='\u{bd7}', '\u{c00}'..='\u{c0c}', '\u{c0e}'..='\u{c10}', '\u{c12}'..='\u{c28}', + '\u{c2a}'..='\u{c39}', '\u{c3d}'..='\u{c44}', '\u{c46}'..='\u{c48}', '\u{c4a}'..='\u{c4c}', + '\u{c55}'..='\u{c56}', '\u{c58}'..='\u{c5a}', '\u{c5c}'..='\u{c5d}', '\u{c60}'..='\u{c63}', + '\u{c80}'..='\u{c83}', '\u{c85}'..='\u{c8c}', '\u{c8e}'..='\u{c90}', '\u{c92}'..='\u{ca8}', + '\u{caa}'..='\u{cb3}', '\u{cb5}'..='\u{cb9}', '\u{cbd}'..='\u{cc4}', '\u{cc6}'..='\u{cc8}', + '\u{cca}'..='\u{ccc}', '\u{cd5}'..='\u{cd6}', '\u{cdc}'..='\u{cde}', '\u{ce0}'..='\u{ce3}', + '\u{cf1}'..='\u{cf3}', '\u{d00}'..='\u{d0c}', '\u{d0e}'..='\u{d10}', '\u{d12}'..='\u{d3a}', + '\u{d3d}'..='\u{d44}', '\u{d46}'..='\u{d48}', '\u{d4a}'..='\u{d4c}', '\u{d4e}'..='\u{d4e}', + '\u{d54}'..='\u{d57}', '\u{d5f}'..='\u{d63}', '\u{d7a}'..='\u{d7f}', '\u{d81}'..='\u{d83}', + '\u{d85}'..='\u{d96}', '\u{d9a}'..='\u{db1}', '\u{db3}'..='\u{dbb}', '\u{dbd}'..='\u{dbd}', + '\u{dc0}'..='\u{dc6}', '\u{dcf}'..='\u{dd4}', '\u{dd6}'..='\u{dd6}', '\u{dd8}'..='\u{ddf}', + '\u{df2}'..='\u{df3}', '\u{e01}'..='\u{e3a}', '\u{e40}'..='\u{e46}', '\u{e4d}'..='\u{e4d}', + '\u{e81}'..='\u{e82}', '\u{e84}'..='\u{e84}', '\u{e86}'..='\u{e8a}', '\u{e8c}'..='\u{ea3}', + '\u{ea5}'..='\u{ea5}', '\u{ea7}'..='\u{eb9}', '\u{ebb}'..='\u{ebd}', '\u{ec0}'..='\u{ec4}', + '\u{ec6}'..='\u{ec6}', '\u{ecd}'..='\u{ecd}', '\u{edc}'..='\u{edf}', '\u{f00}'..='\u{f00}', + '\u{f40}'..='\u{f47}', '\u{f49}'..='\u{f6c}', '\u{f71}'..='\u{f83}', '\u{f88}'..='\u{f97}', + '\u{f99}'..='\u{fbc}', '\u{1000}'..='\u{1036}', '\u{1038}'..='\u{1038}', + '\u{103b}'..='\u{103f}', '\u{1050}'..='\u{108f}', '\u{109a}'..='\u{109d}', + '\u{10a0}'..='\u{10c5}', '\u{10c7}'..='\u{10c7}', '\u{10cd}'..='\u{10cd}', + '\u{10d0}'..='\u{10fa}', '\u{10fc}'..='\u{1248}', '\u{124a}'..='\u{124d}', + '\u{1250}'..='\u{1256}', '\u{1258}'..='\u{1258}', '\u{125a}'..='\u{125d}', + '\u{1260}'..='\u{1288}', '\u{128a}'..='\u{128d}', '\u{1290}'..='\u{12b0}', + '\u{12b2}'..='\u{12b5}', '\u{12b8}'..='\u{12be}', '\u{12c0}'..='\u{12c0}', + '\u{12c2}'..='\u{12c5}', '\u{12c8}'..='\u{12d6}', '\u{12d8}'..='\u{1310}', + '\u{1312}'..='\u{1315}', '\u{1318}'..='\u{135a}', '\u{1380}'..='\u{138f}', + '\u{13a0}'..='\u{13f5}', '\u{13f8}'..='\u{13fd}', '\u{1401}'..='\u{166c}', + '\u{166f}'..='\u{167f}', '\u{1681}'..='\u{169a}', '\u{16a0}'..='\u{16ea}', + '\u{16ee}'..='\u{16f8}', '\u{1700}'..='\u{1713}', '\u{171f}'..='\u{1733}', + '\u{1740}'..='\u{1753}', '\u{1760}'..='\u{176c}', '\u{176e}'..='\u{1770}', + '\u{1772}'..='\u{1773}', '\u{1780}'..='\u{17b3}', '\u{17b6}'..='\u{17c8}', + '\u{17d7}'..='\u{17d7}', '\u{17dc}'..='\u{17dc}', '\u{1820}'..='\u{1878}', + '\u{1880}'..='\u{18aa}', '\u{18b0}'..='\u{18f5}', '\u{1900}'..='\u{191e}', + '\u{1920}'..='\u{192b}', '\u{1930}'..='\u{1938}', '\u{1950}'..='\u{196d}', + '\u{1970}'..='\u{1974}', '\u{1980}'..='\u{19ab}', '\u{19b0}'..='\u{19c9}', + '\u{1a00}'..='\u{1a1b}', '\u{1a20}'..='\u{1a5e}', '\u{1a61}'..='\u{1a74}', + '\u{1aa7}'..='\u{1aa7}', '\u{1abf}'..='\u{1ac0}', '\u{1acc}'..='\u{1ace}', + '\u{1b00}'..='\u{1b33}', '\u{1b35}'..='\u{1b43}', '\u{1b45}'..='\u{1b4c}', + '\u{1b80}'..='\u{1ba9}', '\u{1bac}'..='\u{1baf}', '\u{1bba}'..='\u{1be5}', + '\u{1be7}'..='\u{1bf1}', '\u{1c00}'..='\u{1c36}', '\u{1c4d}'..='\u{1c4f}', + '\u{1c5a}'..='\u{1c7d}', '\u{1c80}'..='\u{1c8a}', '\u{1c90}'..='\u{1cba}', + '\u{1cbd}'..='\u{1cbf}', '\u{1ce9}'..='\u{1cec}', '\u{1cee}'..='\u{1cf3}', + '\u{1cf5}'..='\u{1cf6}', '\u{1cfa}'..='\u{1cfa}', '\u{1d00}'..='\u{1dbf}', + '\u{1dd3}'..='\u{1df4}', '\u{1e00}'..='\u{1f15}', '\u{1f18}'..='\u{1f1d}', + '\u{1f20}'..='\u{1f45}', '\u{1f48}'..='\u{1f4d}', '\u{1f50}'..='\u{1f57}', + '\u{1f59}'..='\u{1f59}', '\u{1f5b}'..='\u{1f5b}', '\u{1f5d}'..='\u{1f5d}', + '\u{1f5f}'..='\u{1f7d}', '\u{1f80}'..='\u{1fb4}', '\u{1fb6}'..='\u{1fbc}', + '\u{1fbe}'..='\u{1fbe}', '\u{1fc2}'..='\u{1fc4}', '\u{1fc6}'..='\u{1fcc}', + '\u{1fd0}'..='\u{1fd3}', '\u{1fd6}'..='\u{1fdb}', '\u{1fe0}'..='\u{1fec}', + '\u{1ff2}'..='\u{1ff4}', '\u{1ff6}'..='\u{1ffc}', '\u{2071}'..='\u{2071}', + '\u{207f}'..='\u{207f}', '\u{2090}'..='\u{209c}', '\u{2102}'..='\u{2102}', + '\u{2107}'..='\u{2107}', '\u{210a}'..='\u{2113}', '\u{2115}'..='\u{2115}', + '\u{2119}'..='\u{211d}', '\u{2124}'..='\u{2124}', '\u{2126}'..='\u{2126}', + '\u{2128}'..='\u{2128}', '\u{212a}'..='\u{212d}', '\u{212f}'..='\u{2139}', + '\u{213c}'..='\u{213f}', '\u{2145}'..='\u{2149}', '\u{214e}'..='\u{214e}', + '\u{2160}'..='\u{2188}', '\u{24b6}'..='\u{24e9}', '\u{2c00}'..='\u{2ce4}', + '\u{2ceb}'..='\u{2cee}', '\u{2cf2}'..='\u{2cf3}', '\u{2d00}'..='\u{2d25}', + '\u{2d27}'..='\u{2d27}', '\u{2d2d}'..='\u{2d2d}', '\u{2d30}'..='\u{2d67}', + '\u{2d6f}'..='\u{2d6f}', '\u{2d80}'..='\u{2d96}', '\u{2da0}'..='\u{2da6}', + '\u{2da8}'..='\u{2dae}', '\u{2db0}'..='\u{2db6}', '\u{2db8}'..='\u{2dbe}', + '\u{2dc0}'..='\u{2dc6}', '\u{2dc8}'..='\u{2dce}', '\u{2dd0}'..='\u{2dd6}', + '\u{2dd8}'..='\u{2dde}', '\u{2de0}'..='\u{2dff}', '\u{2e2f}'..='\u{2e2f}', + '\u{3005}'..='\u{3007}', '\u{3021}'..='\u{3029}', '\u{3031}'..='\u{3035}', + '\u{3038}'..='\u{303c}', '\u{3041}'..='\u{3096}', '\u{309d}'..='\u{309f}', + '\u{30a1}'..='\u{30fa}', '\u{30fc}'..='\u{30ff}', '\u{3105}'..='\u{312f}', + '\u{3131}'..='\u{318e}', '\u{31a0}'..='\u{31bf}', '\u{31f0}'..='\u{31ff}', + '\u{3400}'..='\u{4dbf}', '\u{4e00}'..='\u{a48c}', '\u{a4d0}'..='\u{a4fd}', + '\u{a500}'..='\u{a60c}', '\u{a610}'..='\u{a61f}', '\u{a62a}'..='\u{a62b}', + '\u{a640}'..='\u{a66e}', '\u{a674}'..='\u{a67b}', '\u{a67f}'..='\u{a6ef}', + '\u{a717}'..='\u{a71f}', '\u{a722}'..='\u{a788}', '\u{a78b}'..='\u{a7dc}', + '\u{a7f1}'..='\u{a805}', '\u{a807}'..='\u{a827}', '\u{a840}'..='\u{a873}', + '\u{a880}'..='\u{a8c3}', '\u{a8c5}'..='\u{a8c5}', '\u{a8f2}'..='\u{a8f7}', + '\u{a8fb}'..='\u{a8fb}', '\u{a8fd}'..='\u{a8ff}', '\u{a90a}'..='\u{a92a}', + '\u{a930}'..='\u{a952}', '\u{a960}'..='\u{a97c}', '\u{a980}'..='\u{a9b2}', + '\u{a9b4}'..='\u{a9bf}', '\u{a9cf}'..='\u{a9cf}', '\u{a9e0}'..='\u{a9ef}', + '\u{a9fa}'..='\u{a9fe}', '\u{aa00}'..='\u{aa36}', '\u{aa40}'..='\u{aa4d}', + '\u{aa60}'..='\u{aa76}', '\u{aa7a}'..='\u{aabe}', '\u{aac0}'..='\u{aac0}', + '\u{aac2}'..='\u{aac2}', '\u{aadb}'..='\u{aadd}', '\u{aae0}'..='\u{aaef}', + '\u{aaf2}'..='\u{aaf5}', '\u{ab01}'..='\u{ab06}', '\u{ab09}'..='\u{ab0e}', + '\u{ab11}'..='\u{ab16}', '\u{ab20}'..='\u{ab26}', '\u{ab28}'..='\u{ab2e}', + '\u{ab30}'..='\u{ab5a}', '\u{ab5c}'..='\u{ab69}', '\u{ab70}'..='\u{abea}', + '\u{ac00}'..='\u{d7a3}', '\u{d7b0}'..='\u{d7c6}', '\u{d7cb}'..='\u{d7fb}', + '\u{f900}'..='\u{fa6d}', '\u{fa70}'..='\u{fad9}', '\u{fb00}'..='\u{fb06}', + '\u{fb13}'..='\u{fb17}', '\u{fb1d}'..='\u{fb28}', '\u{fb2a}'..='\u{fb36}', + '\u{fb38}'..='\u{fb3c}', '\u{fb3e}'..='\u{fb3e}', '\u{fb40}'..='\u{fb41}', + '\u{fb43}'..='\u{fb44}', '\u{fb46}'..='\u{fbb1}', '\u{fbd3}'..='\u{fd3d}', + '\u{fd50}'..='\u{fd8f}', '\u{fd92}'..='\u{fdc7}', '\u{fdf0}'..='\u{fdfb}', + '\u{fe70}'..='\u{fe74}', '\u{fe76}'..='\u{fefc}', '\u{ff21}'..='\u{ff3a}', + '\u{ff41}'..='\u{ff5a}', '\u{ff66}'..='\u{ffbe}', '\u{ffc2}'..='\u{ffc7}', + '\u{ffca}'..='\u{ffcf}', '\u{ffd2}'..='\u{ffd7}', '\u{ffda}'..='\u{ffdc}', + '\u{10000}'..='\u{1000b}', '\u{1000d}'..='\u{10026}', '\u{10028}'..='\u{1003a}', + '\u{1003c}'..='\u{1003d}', '\u{1003f}'..='\u{1004d}', '\u{10050}'..='\u{1005d}', + '\u{10080}'..='\u{100fa}', '\u{10140}'..='\u{10174}', '\u{10280}'..='\u{1029c}', + '\u{102a0}'..='\u{102d0}', '\u{10300}'..='\u{1031f}', '\u{1032d}'..='\u{1034a}', + '\u{10350}'..='\u{1037a}', '\u{10380}'..='\u{1039d}', '\u{103a0}'..='\u{103c3}', + '\u{103c8}'..='\u{103cf}', '\u{103d1}'..='\u{103d5}', '\u{10400}'..='\u{1049d}', + '\u{104b0}'..='\u{104d3}', '\u{104d8}'..='\u{104fb}', '\u{10500}'..='\u{10527}', + '\u{10530}'..='\u{10563}', '\u{10570}'..='\u{1057a}', '\u{1057c}'..='\u{1058a}', + '\u{1058c}'..='\u{10592}', '\u{10594}'..='\u{10595}', '\u{10597}'..='\u{105a1}', + '\u{105a3}'..='\u{105b1}', '\u{105b3}'..='\u{105b9}', '\u{105bb}'..='\u{105bc}', + '\u{105c0}'..='\u{105f3}', '\u{10600}'..='\u{10736}', '\u{10740}'..='\u{10755}', + '\u{10760}'..='\u{10767}', '\u{10780}'..='\u{10785}', '\u{10787}'..='\u{107b0}', + '\u{107b2}'..='\u{107ba}', '\u{10800}'..='\u{10805}', '\u{10808}'..='\u{10808}', + '\u{1080a}'..='\u{10835}', '\u{10837}'..='\u{10838}', '\u{1083c}'..='\u{1083c}', + '\u{1083f}'..='\u{10855}', '\u{10860}'..='\u{10876}', '\u{10880}'..='\u{1089e}', + '\u{108e0}'..='\u{108f2}', '\u{108f4}'..='\u{108f5}', '\u{10900}'..='\u{10915}', + '\u{10920}'..='\u{10939}', '\u{10940}'..='\u{10959}', '\u{10980}'..='\u{109b7}', + '\u{109be}'..='\u{109bf}', '\u{10a00}'..='\u{10a03}', '\u{10a05}'..='\u{10a06}', + '\u{10a0c}'..='\u{10a13}', '\u{10a15}'..='\u{10a17}', '\u{10a19}'..='\u{10a35}', + '\u{10a60}'..='\u{10a7c}', '\u{10a80}'..='\u{10a9c}', '\u{10ac0}'..='\u{10ac7}', + '\u{10ac9}'..='\u{10ae4}', '\u{10b00}'..='\u{10b35}', '\u{10b40}'..='\u{10b55}', + '\u{10b60}'..='\u{10b72}', '\u{10b80}'..='\u{10b91}', '\u{10c00}'..='\u{10c48}', + '\u{10c80}'..='\u{10cb2}', '\u{10cc0}'..='\u{10cf2}', '\u{10d00}'..='\u{10d27}', + '\u{10d4a}'..='\u{10d65}', '\u{10d69}'..='\u{10d69}', '\u{10d6f}'..='\u{10d85}', + '\u{10e80}'..='\u{10ea9}', '\u{10eab}'..='\u{10eac}', '\u{10eb0}'..='\u{10eb1}', + '\u{10ec2}'..='\u{10ec7}', '\u{10efa}'..='\u{10efc}', '\u{10f00}'..='\u{10f1c}', + '\u{10f27}'..='\u{10f27}', '\u{10f30}'..='\u{10f45}', '\u{10f70}'..='\u{10f81}', + '\u{10fb0}'..='\u{10fc4}', '\u{10fe0}'..='\u{10ff6}', '\u{11000}'..='\u{11045}', + '\u{11071}'..='\u{11075}', '\u{11080}'..='\u{110b8}', '\u{110c2}'..='\u{110c2}', + '\u{110d0}'..='\u{110e8}', '\u{11100}'..='\u{11132}', '\u{11144}'..='\u{11147}', + '\u{11150}'..='\u{11172}', '\u{11176}'..='\u{11176}', '\u{11180}'..='\u{111bf}', + '\u{111c1}'..='\u{111c4}', '\u{111ce}'..='\u{111cf}', '\u{111da}'..='\u{111da}', + '\u{111dc}'..='\u{111dc}', '\u{11200}'..='\u{11211}', '\u{11213}'..='\u{11234}', + '\u{11237}'..='\u{11237}', '\u{1123e}'..='\u{11241}', '\u{11280}'..='\u{11286}', + '\u{11288}'..='\u{11288}', '\u{1128a}'..='\u{1128d}', '\u{1128f}'..='\u{1129d}', + '\u{1129f}'..='\u{112a8}', '\u{112b0}'..='\u{112e8}', '\u{11300}'..='\u{11303}', + '\u{11305}'..='\u{1130c}', '\u{1130f}'..='\u{11310}', '\u{11313}'..='\u{11328}', + '\u{1132a}'..='\u{11330}', '\u{11332}'..='\u{11333}', '\u{11335}'..='\u{11339}', + '\u{1133d}'..='\u{11344}', '\u{11347}'..='\u{11348}', '\u{1134b}'..='\u{1134c}', + '\u{11350}'..='\u{11350}', '\u{11357}'..='\u{11357}', '\u{1135d}'..='\u{11363}', + '\u{11380}'..='\u{11389}', '\u{1138b}'..='\u{1138b}', '\u{1138e}'..='\u{1138e}', + '\u{11390}'..='\u{113b5}', '\u{113b7}'..='\u{113c0}', '\u{113c2}'..='\u{113c2}', + '\u{113c5}'..='\u{113c5}', '\u{113c7}'..='\u{113ca}', '\u{113cc}'..='\u{113cd}', + '\u{113d1}'..='\u{113d1}', '\u{113d3}'..='\u{113d3}', '\u{11400}'..='\u{11441}', + '\u{11443}'..='\u{11445}', '\u{11447}'..='\u{1144a}', '\u{1145f}'..='\u{11461}', + '\u{11480}'..='\u{114c1}', '\u{114c4}'..='\u{114c5}', '\u{114c7}'..='\u{114c7}', + '\u{11580}'..='\u{115b5}', '\u{115b8}'..='\u{115be}', '\u{115d8}'..='\u{115dd}', + '\u{11600}'..='\u{1163e}', '\u{11640}'..='\u{11640}', '\u{11644}'..='\u{11644}', + '\u{11680}'..='\u{116b5}', '\u{116b8}'..='\u{116b8}', '\u{11700}'..='\u{1171a}', + '\u{1171d}'..='\u{1172a}', '\u{11740}'..='\u{11746}', '\u{11800}'..='\u{11838}', + '\u{118a0}'..='\u{118df}', '\u{118ff}'..='\u{11906}', '\u{11909}'..='\u{11909}', + '\u{1190c}'..='\u{11913}', '\u{11915}'..='\u{11916}', '\u{11918}'..='\u{11935}', + '\u{11937}'..='\u{11938}', '\u{1193b}'..='\u{1193c}', '\u{1193f}'..='\u{11942}', + '\u{119a0}'..='\u{119a7}', '\u{119aa}'..='\u{119d7}', '\u{119da}'..='\u{119df}', + '\u{119e1}'..='\u{119e1}', '\u{119e3}'..='\u{119e4}', '\u{11a00}'..='\u{11a32}', + '\u{11a35}'..='\u{11a3e}', '\u{11a50}'..='\u{11a97}', '\u{11a9d}'..='\u{11a9d}', + '\u{11ab0}'..='\u{11af8}', '\u{11b60}'..='\u{11b67}', '\u{11bc0}'..='\u{11be0}', + '\u{11c00}'..='\u{11c08}', '\u{11c0a}'..='\u{11c36}', '\u{11c38}'..='\u{11c3e}', + '\u{11c40}'..='\u{11c40}', '\u{11c72}'..='\u{11c8f}', '\u{11c92}'..='\u{11ca7}', + '\u{11ca9}'..='\u{11cb6}', '\u{11d00}'..='\u{11d06}', '\u{11d08}'..='\u{11d09}', + '\u{11d0b}'..='\u{11d36}', '\u{11d3a}'..='\u{11d3a}', '\u{11d3c}'..='\u{11d3d}', + '\u{11d3f}'..='\u{11d41}', '\u{11d43}'..='\u{11d43}', '\u{11d46}'..='\u{11d47}', + '\u{11d60}'..='\u{11d65}', '\u{11d67}'..='\u{11d68}', '\u{11d6a}'..='\u{11d8e}', + '\u{11d90}'..='\u{11d91}', '\u{11d93}'..='\u{11d96}', '\u{11d98}'..='\u{11d98}', + '\u{11db0}'..='\u{11ddb}', '\u{11ee0}'..='\u{11ef6}', '\u{11f00}'..='\u{11f10}', + '\u{11f12}'..='\u{11f3a}', '\u{11f3e}'..='\u{11f40}', '\u{11fb0}'..='\u{11fb0}', + '\u{12000}'..='\u{12399}', '\u{12400}'..='\u{1246e}', '\u{12480}'..='\u{12543}', + '\u{12f90}'..='\u{12ff0}', '\u{13000}'..='\u{1342f}', '\u{13441}'..='\u{13446}', + '\u{13460}'..='\u{143fa}', '\u{14400}'..='\u{14646}', '\u{16100}'..='\u{1612e}', + '\u{16800}'..='\u{16a38}', '\u{16a40}'..='\u{16a5e}', '\u{16a70}'..='\u{16abe}', + '\u{16ad0}'..='\u{16aed}', '\u{16b00}'..='\u{16b2f}', '\u{16b40}'..='\u{16b43}', + '\u{16b63}'..='\u{16b77}', '\u{16b7d}'..='\u{16b8f}', '\u{16d40}'..='\u{16d6c}', + '\u{16e40}'..='\u{16e7f}', '\u{16ea0}'..='\u{16eb8}', '\u{16ebb}'..='\u{16ed3}', + '\u{16f00}'..='\u{16f4a}', '\u{16f4f}'..='\u{16f87}', '\u{16f8f}'..='\u{16f9f}', + '\u{16fe0}'..='\u{16fe1}', '\u{16fe3}'..='\u{16fe3}', '\u{16ff0}'..='\u{16ff6}', + '\u{17000}'..='\u{18cd5}', '\u{18cff}'..='\u{18d1e}', '\u{18d80}'..='\u{18df2}', + '\u{1aff0}'..='\u{1aff3}', '\u{1aff5}'..='\u{1affb}', '\u{1affd}'..='\u{1affe}', + '\u{1b000}'..='\u{1b122}', '\u{1b132}'..='\u{1b132}', '\u{1b150}'..='\u{1b152}', + '\u{1b155}'..='\u{1b155}', '\u{1b164}'..='\u{1b167}', '\u{1b170}'..='\u{1b2fb}', + '\u{1bc00}'..='\u{1bc6a}', '\u{1bc70}'..='\u{1bc7c}', '\u{1bc80}'..='\u{1bc88}', + '\u{1bc90}'..='\u{1bc99}', '\u{1bc9e}'..='\u{1bc9e}', '\u{1d400}'..='\u{1d454}', + '\u{1d456}'..='\u{1d49c}', '\u{1d49e}'..='\u{1d49f}', '\u{1d4a2}'..='\u{1d4a2}', + '\u{1d4a5}'..='\u{1d4a6}', '\u{1d4a9}'..='\u{1d4ac}', '\u{1d4ae}'..='\u{1d4b9}', + '\u{1d4bb}'..='\u{1d4bb}', '\u{1d4bd}'..='\u{1d4c3}', '\u{1d4c5}'..='\u{1d505}', + '\u{1d507}'..='\u{1d50a}', '\u{1d50d}'..='\u{1d514}', '\u{1d516}'..='\u{1d51c}', + '\u{1d51e}'..='\u{1d539}', '\u{1d53b}'..='\u{1d53e}', '\u{1d540}'..='\u{1d544}', + '\u{1d546}'..='\u{1d546}', '\u{1d54a}'..='\u{1d550}', '\u{1d552}'..='\u{1d6a5}', + '\u{1d6a8}'..='\u{1d6c0}', '\u{1d6c2}'..='\u{1d6da}', '\u{1d6dc}'..='\u{1d6fa}', + '\u{1d6fc}'..='\u{1d714}', '\u{1d716}'..='\u{1d734}', '\u{1d736}'..='\u{1d74e}', + '\u{1d750}'..='\u{1d76e}', '\u{1d770}'..='\u{1d788}', '\u{1d78a}'..='\u{1d7a8}', + '\u{1d7aa}'..='\u{1d7c2}', '\u{1d7c4}'..='\u{1d7cb}', '\u{1df00}'..='\u{1df1e}', + '\u{1df25}'..='\u{1df2a}', '\u{1e000}'..='\u{1e006}', '\u{1e008}'..='\u{1e018}', + '\u{1e01b}'..='\u{1e021}', '\u{1e023}'..='\u{1e024}', '\u{1e026}'..='\u{1e02a}', + '\u{1e030}'..='\u{1e06d}', '\u{1e08f}'..='\u{1e08f}', '\u{1e100}'..='\u{1e12c}', + '\u{1e137}'..='\u{1e13d}', '\u{1e14e}'..='\u{1e14e}', '\u{1e290}'..='\u{1e2ad}', + '\u{1e2c0}'..='\u{1e2eb}', '\u{1e4d0}'..='\u{1e4eb}', '\u{1e5d0}'..='\u{1e5ed}', + '\u{1e5f0}'..='\u{1e5f0}', '\u{1e6c0}'..='\u{1e6de}', '\u{1e6e0}'..='\u{1e6f5}', + '\u{1e6fe}'..='\u{1e6ff}', '\u{1e7e0}'..='\u{1e7e6}', '\u{1e7e8}'..='\u{1e7eb}', + '\u{1e7ed}'..='\u{1e7ee}', '\u{1e7f0}'..='\u{1e7fe}', '\u{1e800}'..='\u{1e8c4}', + '\u{1e900}'..='\u{1e943}', '\u{1e947}'..='\u{1e947}', '\u{1e94b}'..='\u{1e94b}', + '\u{1ee00}'..='\u{1ee03}', '\u{1ee05}'..='\u{1ee1f}', '\u{1ee21}'..='\u{1ee22}', + '\u{1ee24}'..='\u{1ee24}', '\u{1ee27}'..='\u{1ee27}', '\u{1ee29}'..='\u{1ee32}', + '\u{1ee34}'..='\u{1ee37}', '\u{1ee39}'..='\u{1ee39}', '\u{1ee3b}'..='\u{1ee3b}', + '\u{1ee42}'..='\u{1ee42}', '\u{1ee47}'..='\u{1ee47}', '\u{1ee49}'..='\u{1ee49}', + '\u{1ee4b}'..='\u{1ee4b}', '\u{1ee4d}'..='\u{1ee4f}', '\u{1ee51}'..='\u{1ee52}', + '\u{1ee54}'..='\u{1ee54}', '\u{1ee57}'..='\u{1ee57}', '\u{1ee59}'..='\u{1ee59}', + '\u{1ee5b}'..='\u{1ee5b}', '\u{1ee5d}'..='\u{1ee5d}', '\u{1ee5f}'..='\u{1ee5f}', + '\u{1ee61}'..='\u{1ee62}', '\u{1ee64}'..='\u{1ee64}', '\u{1ee67}'..='\u{1ee6a}', + '\u{1ee6c}'..='\u{1ee72}', '\u{1ee74}'..='\u{1ee77}', '\u{1ee79}'..='\u{1ee7c}', + '\u{1ee7e}'..='\u{1ee7e}', '\u{1ee80}'..='\u{1ee89}', '\u{1ee8b}'..='\u{1ee9b}', + '\u{1eea1}'..='\u{1eea3}', '\u{1eea5}'..='\u{1eea9}', '\u{1eeab}'..='\u{1eebb}', + '\u{1f130}'..='\u{1f149}', '\u{1f150}'..='\u{1f169}', '\u{1f170}'..='\u{1f189}', + '\u{20000}'..='\u{2a6df}', '\u{2a700}'..='\u{2b81d}', '\u{2b820}'..='\u{2cead}', + '\u{2ceb0}'..='\u{2ebe0}', '\u{2ebf0}'..='\u{2ee5d}', '\u{2f800}'..='\u{2fa1d}', + '\u{30000}'..='\u{3134a}', '\u{31350}'..='\u{33479}', +]; + +#[rustfmt::skip] +pub(super) static CASE_IGNORABLE: &[RangeInclusive; 459] = &[ + '\u{a8}'..='\u{a8}', '\u{ad}'..='\u{ad}', '\u{af}'..='\u{af}', '\u{b4}'..='\u{b4}', + '\u{b7}'..='\u{b8}', '\u{2b0}'..='\u{36f}', '\u{374}'..='\u{375}', '\u{37a}'..='\u{37a}', + '\u{384}'..='\u{385}', '\u{387}'..='\u{387}', '\u{483}'..='\u{489}', '\u{559}'..='\u{559}', + '\u{55f}'..='\u{55f}', '\u{591}'..='\u{5bd}', '\u{5bf}'..='\u{5bf}', '\u{5c1}'..='\u{5c2}', + '\u{5c4}'..='\u{5c5}', '\u{5c7}'..='\u{5c7}', '\u{5f4}'..='\u{5f4}', '\u{600}'..='\u{605}', + '\u{610}'..='\u{61a}', '\u{61c}'..='\u{61c}', '\u{640}'..='\u{640}', '\u{64b}'..='\u{65f}', + '\u{670}'..='\u{670}', '\u{6d6}'..='\u{6dd}', '\u{6df}'..='\u{6e8}', '\u{6ea}'..='\u{6ed}', + '\u{70f}'..='\u{70f}', '\u{711}'..='\u{711}', '\u{730}'..='\u{74a}', '\u{7a6}'..='\u{7b0}', + '\u{7eb}'..='\u{7f5}', '\u{7fa}'..='\u{7fa}', '\u{7fd}'..='\u{7fd}', '\u{816}'..='\u{82d}', + '\u{859}'..='\u{85b}', '\u{888}'..='\u{888}', '\u{890}'..='\u{891}', '\u{897}'..='\u{89f}', + '\u{8c9}'..='\u{902}', '\u{93a}'..='\u{93a}', '\u{93c}'..='\u{93c}', '\u{941}'..='\u{948}', + '\u{94d}'..='\u{94d}', '\u{951}'..='\u{957}', '\u{962}'..='\u{963}', '\u{971}'..='\u{971}', + '\u{981}'..='\u{981}', '\u{9bc}'..='\u{9bc}', '\u{9c1}'..='\u{9c4}', '\u{9cd}'..='\u{9cd}', + '\u{9e2}'..='\u{9e3}', '\u{9fe}'..='\u{9fe}', '\u{a01}'..='\u{a02}', '\u{a3c}'..='\u{a3c}', + '\u{a41}'..='\u{a42}', '\u{a47}'..='\u{a48}', '\u{a4b}'..='\u{a4d}', '\u{a51}'..='\u{a51}', + '\u{a70}'..='\u{a71}', '\u{a75}'..='\u{a75}', '\u{a81}'..='\u{a82}', '\u{abc}'..='\u{abc}', + '\u{ac1}'..='\u{ac5}', '\u{ac7}'..='\u{ac8}', '\u{acd}'..='\u{acd}', '\u{ae2}'..='\u{ae3}', + '\u{afa}'..='\u{aff}', '\u{b01}'..='\u{b01}', '\u{b3c}'..='\u{b3c}', '\u{b3f}'..='\u{b3f}', + '\u{b41}'..='\u{b44}', '\u{b4d}'..='\u{b4d}', '\u{b55}'..='\u{b56}', '\u{b62}'..='\u{b63}', + '\u{b82}'..='\u{b82}', '\u{bc0}'..='\u{bc0}', '\u{bcd}'..='\u{bcd}', '\u{c00}'..='\u{c00}', + '\u{c04}'..='\u{c04}', '\u{c3c}'..='\u{c3c}', '\u{c3e}'..='\u{c40}', '\u{c46}'..='\u{c48}', + '\u{c4a}'..='\u{c4d}', '\u{c55}'..='\u{c56}', '\u{c62}'..='\u{c63}', '\u{c81}'..='\u{c81}', + '\u{cbc}'..='\u{cbc}', '\u{cbf}'..='\u{cbf}', '\u{cc6}'..='\u{cc6}', '\u{ccc}'..='\u{ccd}', + '\u{ce2}'..='\u{ce3}', '\u{d00}'..='\u{d01}', '\u{d3b}'..='\u{d3c}', '\u{d41}'..='\u{d44}', + '\u{d4d}'..='\u{d4d}', '\u{d62}'..='\u{d63}', '\u{d81}'..='\u{d81}', '\u{dca}'..='\u{dca}', + '\u{dd2}'..='\u{dd4}', '\u{dd6}'..='\u{dd6}', '\u{e31}'..='\u{e31}', '\u{e34}'..='\u{e3a}', + '\u{e46}'..='\u{e4e}', '\u{eb1}'..='\u{eb1}', '\u{eb4}'..='\u{ebc}', '\u{ec6}'..='\u{ec6}', + '\u{ec8}'..='\u{ece}', '\u{f18}'..='\u{f19}', '\u{f35}'..='\u{f35}', '\u{f37}'..='\u{f37}', + '\u{f39}'..='\u{f39}', '\u{f71}'..='\u{f7e}', '\u{f80}'..='\u{f84}', '\u{f86}'..='\u{f87}', + '\u{f8d}'..='\u{f97}', '\u{f99}'..='\u{fbc}', '\u{fc6}'..='\u{fc6}', + '\u{102d}'..='\u{1030}', '\u{1032}'..='\u{1037}', '\u{1039}'..='\u{103a}', + '\u{103d}'..='\u{103e}', '\u{1058}'..='\u{1059}', '\u{105e}'..='\u{1060}', + '\u{1071}'..='\u{1074}', '\u{1082}'..='\u{1082}', '\u{1085}'..='\u{1086}', + '\u{108d}'..='\u{108d}', '\u{109d}'..='\u{109d}', '\u{10fc}'..='\u{10fc}', + '\u{135d}'..='\u{135f}', '\u{1712}'..='\u{1714}', '\u{1732}'..='\u{1733}', + '\u{1752}'..='\u{1753}', '\u{1772}'..='\u{1773}', '\u{17b4}'..='\u{17b5}', + '\u{17b7}'..='\u{17bd}', '\u{17c6}'..='\u{17c6}', '\u{17c9}'..='\u{17d3}', + '\u{17d7}'..='\u{17d7}', '\u{17dd}'..='\u{17dd}', '\u{180b}'..='\u{180f}', + '\u{1843}'..='\u{1843}', '\u{1885}'..='\u{1886}', '\u{18a9}'..='\u{18a9}', + '\u{1920}'..='\u{1922}', '\u{1927}'..='\u{1928}', '\u{1932}'..='\u{1932}', + '\u{1939}'..='\u{193b}', '\u{1a17}'..='\u{1a18}', '\u{1a1b}'..='\u{1a1b}', + '\u{1a56}'..='\u{1a56}', '\u{1a58}'..='\u{1a5e}', '\u{1a60}'..='\u{1a60}', + '\u{1a62}'..='\u{1a62}', '\u{1a65}'..='\u{1a6c}', '\u{1a73}'..='\u{1a7c}', + '\u{1a7f}'..='\u{1a7f}', '\u{1aa7}'..='\u{1aa7}', '\u{1ab0}'..='\u{1add}', + '\u{1ae0}'..='\u{1aeb}', '\u{1b00}'..='\u{1b03}', '\u{1b34}'..='\u{1b34}', + '\u{1b36}'..='\u{1b3a}', '\u{1b3c}'..='\u{1b3c}', '\u{1b42}'..='\u{1b42}', + '\u{1b6b}'..='\u{1b73}', '\u{1b80}'..='\u{1b81}', '\u{1ba2}'..='\u{1ba5}', + '\u{1ba8}'..='\u{1ba9}', '\u{1bab}'..='\u{1bad}', '\u{1be6}'..='\u{1be6}', + '\u{1be8}'..='\u{1be9}', '\u{1bed}'..='\u{1bed}', '\u{1bef}'..='\u{1bf1}', + '\u{1c2c}'..='\u{1c33}', '\u{1c36}'..='\u{1c37}', '\u{1c78}'..='\u{1c7d}', + '\u{1cd0}'..='\u{1cd2}', '\u{1cd4}'..='\u{1ce0}', '\u{1ce2}'..='\u{1ce8}', + '\u{1ced}'..='\u{1ced}', '\u{1cf4}'..='\u{1cf4}', '\u{1cf8}'..='\u{1cf9}', + '\u{1d2c}'..='\u{1d6a}', '\u{1d78}'..='\u{1d78}', '\u{1d9b}'..='\u{1dff}', + '\u{1fbd}'..='\u{1fbd}', '\u{1fbf}'..='\u{1fc1}', '\u{1fcd}'..='\u{1fcf}', + '\u{1fdd}'..='\u{1fdf}', '\u{1fed}'..='\u{1fef}', '\u{1ffd}'..='\u{1ffe}', + '\u{200b}'..='\u{200f}', '\u{2018}'..='\u{2019}', '\u{2024}'..='\u{2024}', + '\u{2027}'..='\u{2027}', '\u{202a}'..='\u{202e}', '\u{2060}'..='\u{2064}', + '\u{2066}'..='\u{206f}', '\u{2071}'..='\u{2071}', '\u{207f}'..='\u{207f}', + '\u{2090}'..='\u{209c}', '\u{20d0}'..='\u{20f0}', '\u{2c7c}'..='\u{2c7d}', + '\u{2cef}'..='\u{2cf1}', '\u{2d6f}'..='\u{2d6f}', '\u{2d7f}'..='\u{2d7f}', + '\u{2de0}'..='\u{2dff}', '\u{2e2f}'..='\u{2e2f}', '\u{3005}'..='\u{3005}', + '\u{302a}'..='\u{302d}', '\u{3031}'..='\u{3035}', '\u{303b}'..='\u{303b}', + '\u{3099}'..='\u{309e}', '\u{30fc}'..='\u{30fe}', '\u{a015}'..='\u{a015}', + '\u{a4f8}'..='\u{a4fd}', '\u{a60c}'..='\u{a60c}', '\u{a66f}'..='\u{a672}', + '\u{a674}'..='\u{a67d}', '\u{a67f}'..='\u{a67f}', '\u{a69c}'..='\u{a69f}', + '\u{a6f0}'..='\u{a6f1}', '\u{a700}'..='\u{a721}', '\u{a770}'..='\u{a770}', + '\u{a788}'..='\u{a78a}', '\u{a7f1}'..='\u{a7f4}', '\u{a7f8}'..='\u{a7f9}', + '\u{a802}'..='\u{a802}', '\u{a806}'..='\u{a806}', '\u{a80b}'..='\u{a80b}', + '\u{a825}'..='\u{a826}', '\u{a82c}'..='\u{a82c}', '\u{a8c4}'..='\u{a8c5}', + '\u{a8e0}'..='\u{a8f1}', '\u{a8ff}'..='\u{a8ff}', '\u{a926}'..='\u{a92d}', + '\u{a947}'..='\u{a951}', '\u{a980}'..='\u{a982}', '\u{a9b3}'..='\u{a9b3}', + '\u{a9b6}'..='\u{a9b9}', '\u{a9bc}'..='\u{a9bd}', '\u{a9cf}'..='\u{a9cf}', + '\u{a9e5}'..='\u{a9e6}', '\u{aa29}'..='\u{aa2e}', '\u{aa31}'..='\u{aa32}', + '\u{aa35}'..='\u{aa36}', '\u{aa43}'..='\u{aa43}', '\u{aa4c}'..='\u{aa4c}', + '\u{aa70}'..='\u{aa70}', '\u{aa7c}'..='\u{aa7c}', '\u{aab0}'..='\u{aab0}', + '\u{aab2}'..='\u{aab4}', '\u{aab7}'..='\u{aab8}', '\u{aabe}'..='\u{aabf}', + '\u{aac1}'..='\u{aac1}', '\u{aadd}'..='\u{aadd}', '\u{aaec}'..='\u{aaed}', + '\u{aaf3}'..='\u{aaf4}', '\u{aaf6}'..='\u{aaf6}', '\u{ab5b}'..='\u{ab5f}', + '\u{ab69}'..='\u{ab6b}', '\u{abe5}'..='\u{abe5}', '\u{abe8}'..='\u{abe8}', + '\u{abed}'..='\u{abed}', '\u{fb1e}'..='\u{fb1e}', '\u{fbb2}'..='\u{fbc2}', + '\u{fe00}'..='\u{fe0f}', '\u{fe13}'..='\u{fe13}', '\u{fe20}'..='\u{fe2f}', + '\u{fe52}'..='\u{fe52}', '\u{fe55}'..='\u{fe55}', '\u{feff}'..='\u{feff}', + '\u{ff07}'..='\u{ff07}', '\u{ff0e}'..='\u{ff0e}', '\u{ff1a}'..='\u{ff1a}', + '\u{ff3e}'..='\u{ff3e}', '\u{ff40}'..='\u{ff40}', '\u{ff70}'..='\u{ff70}', + '\u{ff9e}'..='\u{ff9f}', '\u{ffe3}'..='\u{ffe3}', '\u{fff9}'..='\u{fffb}', + '\u{101fd}'..='\u{101fd}', '\u{102e0}'..='\u{102e0}', '\u{10376}'..='\u{1037a}', + '\u{10780}'..='\u{10785}', '\u{10787}'..='\u{107b0}', '\u{107b2}'..='\u{107ba}', + '\u{10a01}'..='\u{10a03}', '\u{10a05}'..='\u{10a06}', '\u{10a0c}'..='\u{10a0f}', + '\u{10a38}'..='\u{10a3a}', '\u{10a3f}'..='\u{10a3f}', '\u{10ae5}'..='\u{10ae6}', + '\u{10d24}'..='\u{10d27}', '\u{10d4e}'..='\u{10d4e}', '\u{10d69}'..='\u{10d6d}', + '\u{10d6f}'..='\u{10d6f}', '\u{10eab}'..='\u{10eac}', '\u{10ec5}'..='\u{10ec5}', + '\u{10efa}'..='\u{10eff}', '\u{10f46}'..='\u{10f50}', '\u{10f82}'..='\u{10f85}', + '\u{11001}'..='\u{11001}', '\u{11038}'..='\u{11046}', '\u{11070}'..='\u{11070}', + '\u{11073}'..='\u{11074}', '\u{1107f}'..='\u{11081}', '\u{110b3}'..='\u{110b6}', + '\u{110b9}'..='\u{110ba}', '\u{110bd}'..='\u{110bd}', '\u{110c2}'..='\u{110c2}', + '\u{110cd}'..='\u{110cd}', '\u{11100}'..='\u{11102}', '\u{11127}'..='\u{1112b}', + '\u{1112d}'..='\u{11134}', '\u{11173}'..='\u{11173}', '\u{11180}'..='\u{11181}', + '\u{111b6}'..='\u{111be}', '\u{111c9}'..='\u{111cc}', '\u{111cf}'..='\u{111cf}', + '\u{1122f}'..='\u{11231}', '\u{11234}'..='\u{11234}', '\u{11236}'..='\u{11237}', + '\u{1123e}'..='\u{1123e}', '\u{11241}'..='\u{11241}', '\u{112df}'..='\u{112df}', + '\u{112e3}'..='\u{112ea}', '\u{11300}'..='\u{11301}', '\u{1133b}'..='\u{1133c}', + '\u{11340}'..='\u{11340}', '\u{11366}'..='\u{1136c}', '\u{11370}'..='\u{11374}', + '\u{113bb}'..='\u{113c0}', '\u{113ce}'..='\u{113ce}', '\u{113d0}'..='\u{113d0}', + '\u{113d2}'..='\u{113d2}', '\u{113e1}'..='\u{113e2}', '\u{11438}'..='\u{1143f}', + '\u{11442}'..='\u{11444}', '\u{11446}'..='\u{11446}', '\u{1145e}'..='\u{1145e}', + '\u{114b3}'..='\u{114b8}', '\u{114ba}'..='\u{114ba}', '\u{114bf}'..='\u{114c0}', + '\u{114c2}'..='\u{114c3}', '\u{115b2}'..='\u{115b5}', '\u{115bc}'..='\u{115bd}', + '\u{115bf}'..='\u{115c0}', '\u{115dc}'..='\u{115dd}', '\u{11633}'..='\u{1163a}', + '\u{1163d}'..='\u{1163d}', '\u{1163f}'..='\u{11640}', '\u{116ab}'..='\u{116ab}', + '\u{116ad}'..='\u{116ad}', '\u{116b0}'..='\u{116b5}', '\u{116b7}'..='\u{116b7}', + '\u{1171d}'..='\u{1171d}', '\u{1171f}'..='\u{1171f}', '\u{11722}'..='\u{11725}', + '\u{11727}'..='\u{1172b}', '\u{1182f}'..='\u{11837}', '\u{11839}'..='\u{1183a}', + '\u{1193b}'..='\u{1193c}', '\u{1193e}'..='\u{1193e}', '\u{11943}'..='\u{11943}', + '\u{119d4}'..='\u{119d7}', '\u{119da}'..='\u{119db}', '\u{119e0}'..='\u{119e0}', + '\u{11a01}'..='\u{11a0a}', '\u{11a33}'..='\u{11a38}', '\u{11a3b}'..='\u{11a3e}', + '\u{11a47}'..='\u{11a47}', '\u{11a51}'..='\u{11a56}', '\u{11a59}'..='\u{11a5b}', + '\u{11a8a}'..='\u{11a96}', '\u{11a98}'..='\u{11a99}', '\u{11b60}'..='\u{11b60}', + '\u{11b62}'..='\u{11b64}', '\u{11b66}'..='\u{11b66}', '\u{11c30}'..='\u{11c36}', + '\u{11c38}'..='\u{11c3d}', '\u{11c3f}'..='\u{11c3f}', '\u{11c92}'..='\u{11ca7}', + '\u{11caa}'..='\u{11cb0}', '\u{11cb2}'..='\u{11cb3}', '\u{11cb5}'..='\u{11cb6}', + '\u{11d31}'..='\u{11d36}', '\u{11d3a}'..='\u{11d3a}', '\u{11d3c}'..='\u{11d3d}', + '\u{11d3f}'..='\u{11d45}', '\u{11d47}'..='\u{11d47}', '\u{11d90}'..='\u{11d91}', + '\u{11d95}'..='\u{11d95}', '\u{11d97}'..='\u{11d97}', '\u{11dd9}'..='\u{11dd9}', + '\u{11ef3}'..='\u{11ef4}', '\u{11f00}'..='\u{11f01}', '\u{11f36}'..='\u{11f3a}', + '\u{11f40}'..='\u{11f40}', '\u{11f42}'..='\u{11f42}', '\u{11f5a}'..='\u{11f5a}', + '\u{13430}'..='\u{13440}', '\u{13447}'..='\u{13455}', '\u{1611e}'..='\u{16129}', + '\u{1612d}'..='\u{1612f}', '\u{16af0}'..='\u{16af4}', '\u{16b30}'..='\u{16b36}', + '\u{16b40}'..='\u{16b43}', '\u{16d40}'..='\u{16d42}', '\u{16d6b}'..='\u{16d6c}', + '\u{16f4f}'..='\u{16f4f}', '\u{16f8f}'..='\u{16f9f}', '\u{16fe0}'..='\u{16fe1}', + '\u{16fe3}'..='\u{16fe4}', '\u{16ff2}'..='\u{16ff3}', '\u{1aff0}'..='\u{1aff3}', + '\u{1aff5}'..='\u{1affb}', '\u{1affd}'..='\u{1affe}', '\u{1bc9d}'..='\u{1bc9e}', + '\u{1bca0}'..='\u{1bca3}', '\u{1cf00}'..='\u{1cf2d}', '\u{1cf30}'..='\u{1cf46}', + '\u{1d167}'..='\u{1d169}', '\u{1d173}'..='\u{1d182}', '\u{1d185}'..='\u{1d18b}', + '\u{1d1aa}'..='\u{1d1ad}', '\u{1d242}'..='\u{1d244}', '\u{1da00}'..='\u{1da36}', + '\u{1da3b}'..='\u{1da6c}', '\u{1da75}'..='\u{1da75}', '\u{1da84}'..='\u{1da84}', + '\u{1da9b}'..='\u{1da9f}', '\u{1daa1}'..='\u{1daaf}', '\u{1e000}'..='\u{1e006}', + '\u{1e008}'..='\u{1e018}', '\u{1e01b}'..='\u{1e021}', '\u{1e023}'..='\u{1e024}', + '\u{1e026}'..='\u{1e02a}', '\u{1e030}'..='\u{1e06d}', '\u{1e08f}'..='\u{1e08f}', + '\u{1e130}'..='\u{1e13d}', '\u{1e2ae}'..='\u{1e2ae}', '\u{1e2ec}'..='\u{1e2ef}', + '\u{1e4eb}'..='\u{1e4ef}', '\u{1e5ee}'..='\u{1e5ef}', '\u{1e6e3}'..='\u{1e6e3}', + '\u{1e6e6}'..='\u{1e6e6}', '\u{1e6ee}'..='\u{1e6ef}', '\u{1e6f5}'..='\u{1e6f5}', + '\u{1e6ff}'..='\u{1e6ff}', '\u{1e8d0}'..='\u{1e8d6}', '\u{1e944}'..='\u{1e94b}', + '\u{1f3fb}'..='\u{1f3ff}', '\u{e0001}'..='\u{e0001}', '\u{e0020}'..='\u{e007f}', + '\u{e0100}'..='\u{e01ef}', +]; + +#[rustfmt::skip] +pub(super) static CASED: &[RangeInclusive; 156] = &[ + '\u{aa}'..='\u{aa}', '\u{b5}'..='\u{b5}', '\u{ba}'..='\u{ba}', '\u{c0}'..='\u{d6}', + '\u{d8}'..='\u{f6}', '\u{f8}'..='\u{1ba}', '\u{1bc}'..='\u{1bf}', '\u{1c4}'..='\u{293}', + '\u{296}'..='\u{2b8}', '\u{2c0}'..='\u{2c1}', '\u{2e0}'..='\u{2e4}', '\u{345}'..='\u{345}', + '\u{370}'..='\u{373}', '\u{376}'..='\u{377}', '\u{37a}'..='\u{37d}', '\u{37f}'..='\u{37f}', + '\u{386}'..='\u{386}', '\u{388}'..='\u{38a}', '\u{38c}'..='\u{38c}', '\u{38e}'..='\u{3a1}', + '\u{3a3}'..='\u{3f5}', '\u{3f7}'..='\u{481}', '\u{48a}'..='\u{52f}', '\u{531}'..='\u{556}', + '\u{560}'..='\u{588}', '\u{10a0}'..='\u{10c5}', '\u{10c7}'..='\u{10c7}', + '\u{10cd}'..='\u{10cd}', '\u{10d0}'..='\u{10fa}', '\u{10fc}'..='\u{10ff}', + '\u{13a0}'..='\u{13f5}', '\u{13f8}'..='\u{13fd}', '\u{1c80}'..='\u{1c8a}', + '\u{1c90}'..='\u{1cba}', '\u{1cbd}'..='\u{1cbf}', '\u{1d00}'..='\u{1dbf}', + '\u{1e00}'..='\u{1f15}', '\u{1f18}'..='\u{1f1d}', '\u{1f20}'..='\u{1f45}', + '\u{1f48}'..='\u{1f4d}', '\u{1f50}'..='\u{1f57}', '\u{1f59}'..='\u{1f59}', + '\u{1f5b}'..='\u{1f5b}', '\u{1f5d}'..='\u{1f5d}', '\u{1f5f}'..='\u{1f7d}', + '\u{1f80}'..='\u{1fb4}', '\u{1fb6}'..='\u{1fbc}', '\u{1fbe}'..='\u{1fbe}', + '\u{1fc2}'..='\u{1fc4}', '\u{1fc6}'..='\u{1fcc}', '\u{1fd0}'..='\u{1fd3}', + '\u{1fd6}'..='\u{1fdb}', '\u{1fe0}'..='\u{1fec}', '\u{1ff2}'..='\u{1ff4}', + '\u{1ff6}'..='\u{1ffc}', '\u{2071}'..='\u{2071}', '\u{207f}'..='\u{207f}', + '\u{2090}'..='\u{209c}', '\u{2102}'..='\u{2102}', '\u{2107}'..='\u{2107}', + '\u{210a}'..='\u{2113}', '\u{2115}'..='\u{2115}', '\u{2119}'..='\u{211d}', + '\u{2124}'..='\u{2124}', '\u{2126}'..='\u{2126}', '\u{2128}'..='\u{2128}', + '\u{212a}'..='\u{212d}', '\u{212f}'..='\u{2134}', '\u{2139}'..='\u{2139}', + '\u{213c}'..='\u{213f}', '\u{2145}'..='\u{2149}', '\u{214e}'..='\u{214e}', + '\u{2160}'..='\u{217f}', '\u{2183}'..='\u{2184}', '\u{24b6}'..='\u{24e9}', + '\u{2c00}'..='\u{2ce4}', '\u{2ceb}'..='\u{2cee}', '\u{2cf2}'..='\u{2cf3}', + '\u{2d00}'..='\u{2d25}', '\u{2d27}'..='\u{2d27}', '\u{2d2d}'..='\u{2d2d}', + '\u{a640}'..='\u{a66d}', '\u{a680}'..='\u{a69d}', '\u{a722}'..='\u{a787}', + '\u{a78b}'..='\u{a78e}', '\u{a790}'..='\u{a7dc}', '\u{a7f1}'..='\u{a7f6}', + '\u{a7f8}'..='\u{a7fa}', '\u{ab30}'..='\u{ab5a}', '\u{ab5c}'..='\u{ab69}', + '\u{ab70}'..='\u{abbf}', '\u{fb00}'..='\u{fb06}', '\u{fb13}'..='\u{fb17}', + '\u{ff21}'..='\u{ff3a}', '\u{ff41}'..='\u{ff5a}', '\u{10400}'..='\u{1044f}', + '\u{104b0}'..='\u{104d3}', '\u{104d8}'..='\u{104fb}', '\u{10570}'..='\u{1057a}', + '\u{1057c}'..='\u{1058a}', '\u{1058c}'..='\u{10592}', '\u{10594}'..='\u{10595}', + '\u{10597}'..='\u{105a1}', '\u{105a3}'..='\u{105b1}', '\u{105b3}'..='\u{105b9}', + '\u{105bb}'..='\u{105bc}', '\u{10780}'..='\u{10780}', '\u{10783}'..='\u{10785}', + '\u{10787}'..='\u{107b0}', '\u{107b2}'..='\u{107ba}', '\u{10c80}'..='\u{10cb2}', + '\u{10cc0}'..='\u{10cf2}', '\u{10d50}'..='\u{10d65}', '\u{10d70}'..='\u{10d85}', + '\u{118a0}'..='\u{118df}', '\u{16e40}'..='\u{16e7f}', '\u{16ea0}'..='\u{16eb8}', + '\u{16ebb}'..='\u{16ed3}', '\u{1d400}'..='\u{1d454}', '\u{1d456}'..='\u{1d49c}', + '\u{1d49e}'..='\u{1d49f}', '\u{1d4a2}'..='\u{1d4a2}', '\u{1d4a5}'..='\u{1d4a6}', + '\u{1d4a9}'..='\u{1d4ac}', '\u{1d4ae}'..='\u{1d4b9}', '\u{1d4bb}'..='\u{1d4bb}', + '\u{1d4bd}'..='\u{1d4c3}', '\u{1d4c5}'..='\u{1d505}', '\u{1d507}'..='\u{1d50a}', + '\u{1d50d}'..='\u{1d514}', '\u{1d516}'..='\u{1d51c}', '\u{1d51e}'..='\u{1d539}', + '\u{1d53b}'..='\u{1d53e}', '\u{1d540}'..='\u{1d544}', '\u{1d546}'..='\u{1d546}', + '\u{1d54a}'..='\u{1d550}', '\u{1d552}'..='\u{1d6a5}', '\u{1d6a8}'..='\u{1d6c0}', + '\u{1d6c2}'..='\u{1d6da}', '\u{1d6dc}'..='\u{1d6fa}', '\u{1d6fc}'..='\u{1d714}', + '\u{1d716}'..='\u{1d734}', '\u{1d736}'..='\u{1d74e}', '\u{1d750}'..='\u{1d76e}', + '\u{1d770}'..='\u{1d788}', '\u{1d78a}'..='\u{1d7a8}', '\u{1d7aa}'..='\u{1d7c2}', + '\u{1d7c4}'..='\u{1d7cb}', '\u{1df00}'..='\u{1df09}', '\u{1df0b}'..='\u{1df1e}', + '\u{1df25}'..='\u{1df2a}', '\u{1e030}'..='\u{1e06d}', '\u{1e900}'..='\u{1e943}', + '\u{1f130}'..='\u{1f149}', '\u{1f150}'..='\u{1f169}', '\u{1f170}'..='\u{1f189}', +]; + +#[rustfmt::skip] +pub(super) static GRAPHEME_EXTEND: &[RangeInclusive; 383] = &[ + '\u{300}'..='\u{36f}', '\u{483}'..='\u{489}', '\u{591}'..='\u{5bd}', '\u{5bf}'..='\u{5bf}', + '\u{5c1}'..='\u{5c2}', '\u{5c4}'..='\u{5c5}', '\u{5c7}'..='\u{5c7}', '\u{610}'..='\u{61a}', + '\u{64b}'..='\u{65f}', '\u{670}'..='\u{670}', '\u{6d6}'..='\u{6dc}', '\u{6df}'..='\u{6e4}', + '\u{6e7}'..='\u{6e8}', '\u{6ea}'..='\u{6ed}', '\u{711}'..='\u{711}', '\u{730}'..='\u{74a}', + '\u{7a6}'..='\u{7b0}', '\u{7eb}'..='\u{7f3}', '\u{7fd}'..='\u{7fd}', '\u{816}'..='\u{819}', + '\u{81b}'..='\u{823}', '\u{825}'..='\u{827}', '\u{829}'..='\u{82d}', '\u{859}'..='\u{85b}', + '\u{897}'..='\u{89f}', '\u{8ca}'..='\u{8e1}', '\u{8e3}'..='\u{902}', '\u{93a}'..='\u{93a}', + '\u{93c}'..='\u{93c}', '\u{941}'..='\u{948}', '\u{94d}'..='\u{94d}', '\u{951}'..='\u{957}', + '\u{962}'..='\u{963}', '\u{981}'..='\u{981}', '\u{9bc}'..='\u{9bc}', '\u{9be}'..='\u{9be}', + '\u{9c1}'..='\u{9c4}', '\u{9cd}'..='\u{9cd}', '\u{9d7}'..='\u{9d7}', '\u{9e2}'..='\u{9e3}', + '\u{9fe}'..='\u{9fe}', '\u{a01}'..='\u{a02}', '\u{a3c}'..='\u{a3c}', '\u{a41}'..='\u{a42}', + '\u{a47}'..='\u{a48}', '\u{a4b}'..='\u{a4d}', '\u{a51}'..='\u{a51}', '\u{a70}'..='\u{a71}', + '\u{a75}'..='\u{a75}', '\u{a81}'..='\u{a82}', '\u{abc}'..='\u{abc}', '\u{ac1}'..='\u{ac5}', + '\u{ac7}'..='\u{ac8}', '\u{acd}'..='\u{acd}', '\u{ae2}'..='\u{ae3}', '\u{afa}'..='\u{aff}', + '\u{b01}'..='\u{b01}', '\u{b3c}'..='\u{b3c}', '\u{b3e}'..='\u{b3f}', '\u{b41}'..='\u{b44}', + '\u{b4d}'..='\u{b4d}', '\u{b55}'..='\u{b57}', '\u{b62}'..='\u{b63}', '\u{b82}'..='\u{b82}', + '\u{bbe}'..='\u{bbe}', '\u{bc0}'..='\u{bc0}', '\u{bcd}'..='\u{bcd}', '\u{bd7}'..='\u{bd7}', + '\u{c00}'..='\u{c00}', '\u{c04}'..='\u{c04}', '\u{c3c}'..='\u{c3c}', '\u{c3e}'..='\u{c40}', + '\u{c46}'..='\u{c48}', '\u{c4a}'..='\u{c4d}', '\u{c55}'..='\u{c56}', '\u{c62}'..='\u{c63}', + '\u{c81}'..='\u{c81}', '\u{cbc}'..='\u{cbc}', '\u{cbf}'..='\u{cc0}', '\u{cc2}'..='\u{cc2}', + '\u{cc6}'..='\u{cc8}', '\u{cca}'..='\u{ccd}', '\u{cd5}'..='\u{cd6}', '\u{ce2}'..='\u{ce3}', + '\u{d00}'..='\u{d01}', '\u{d3b}'..='\u{d3c}', '\u{d3e}'..='\u{d3e}', '\u{d41}'..='\u{d44}', + '\u{d4d}'..='\u{d4d}', '\u{d57}'..='\u{d57}', '\u{d62}'..='\u{d63}', '\u{d81}'..='\u{d81}', + '\u{dca}'..='\u{dca}', '\u{dcf}'..='\u{dcf}', '\u{dd2}'..='\u{dd4}', '\u{dd6}'..='\u{dd6}', + '\u{ddf}'..='\u{ddf}', '\u{e31}'..='\u{e31}', '\u{e34}'..='\u{e3a}', '\u{e47}'..='\u{e4e}', + '\u{eb1}'..='\u{eb1}', '\u{eb4}'..='\u{ebc}', '\u{ec8}'..='\u{ece}', '\u{f18}'..='\u{f19}', + '\u{f35}'..='\u{f35}', '\u{f37}'..='\u{f37}', '\u{f39}'..='\u{f39}', '\u{f71}'..='\u{f7e}', + '\u{f80}'..='\u{f84}', '\u{f86}'..='\u{f87}', '\u{f8d}'..='\u{f97}', '\u{f99}'..='\u{fbc}', + '\u{fc6}'..='\u{fc6}', '\u{102d}'..='\u{1030}', '\u{1032}'..='\u{1037}', + '\u{1039}'..='\u{103a}', '\u{103d}'..='\u{103e}', '\u{1058}'..='\u{1059}', + '\u{105e}'..='\u{1060}', '\u{1071}'..='\u{1074}', '\u{1082}'..='\u{1082}', + '\u{1085}'..='\u{1086}', '\u{108d}'..='\u{108d}', '\u{109d}'..='\u{109d}', + '\u{135d}'..='\u{135f}', '\u{1712}'..='\u{1715}', '\u{1732}'..='\u{1734}', + '\u{1752}'..='\u{1753}', '\u{1772}'..='\u{1773}', '\u{17b4}'..='\u{17b5}', + '\u{17b7}'..='\u{17bd}', '\u{17c6}'..='\u{17c6}', '\u{17c9}'..='\u{17d3}', + '\u{17dd}'..='\u{17dd}', '\u{180b}'..='\u{180d}', '\u{180f}'..='\u{180f}', + '\u{1885}'..='\u{1886}', '\u{18a9}'..='\u{18a9}', '\u{1920}'..='\u{1922}', + '\u{1927}'..='\u{1928}', '\u{1932}'..='\u{1932}', '\u{1939}'..='\u{193b}', + '\u{1a17}'..='\u{1a18}', '\u{1a1b}'..='\u{1a1b}', '\u{1a56}'..='\u{1a56}', + '\u{1a58}'..='\u{1a5e}', '\u{1a60}'..='\u{1a60}', '\u{1a62}'..='\u{1a62}', + '\u{1a65}'..='\u{1a6c}', '\u{1a73}'..='\u{1a7c}', '\u{1a7f}'..='\u{1a7f}', + '\u{1ab0}'..='\u{1add}', '\u{1ae0}'..='\u{1aeb}', '\u{1b00}'..='\u{1b03}', + '\u{1b34}'..='\u{1b3d}', '\u{1b42}'..='\u{1b44}', '\u{1b6b}'..='\u{1b73}', + '\u{1b80}'..='\u{1b81}', '\u{1ba2}'..='\u{1ba5}', '\u{1ba8}'..='\u{1bad}', + '\u{1be6}'..='\u{1be6}', '\u{1be8}'..='\u{1be9}', '\u{1bed}'..='\u{1bed}', + '\u{1bef}'..='\u{1bf3}', '\u{1c2c}'..='\u{1c33}', '\u{1c36}'..='\u{1c37}', + '\u{1cd0}'..='\u{1cd2}', '\u{1cd4}'..='\u{1ce0}', '\u{1ce2}'..='\u{1ce8}', + '\u{1ced}'..='\u{1ced}', '\u{1cf4}'..='\u{1cf4}', '\u{1cf8}'..='\u{1cf9}', + '\u{1dc0}'..='\u{1dff}', '\u{200c}'..='\u{200c}', '\u{20d0}'..='\u{20f0}', + '\u{2cef}'..='\u{2cf1}', '\u{2d7f}'..='\u{2d7f}', '\u{2de0}'..='\u{2dff}', + '\u{302a}'..='\u{302f}', '\u{3099}'..='\u{309a}', '\u{a66f}'..='\u{a672}', + '\u{a674}'..='\u{a67d}', '\u{a69e}'..='\u{a69f}', '\u{a6f0}'..='\u{a6f1}', + '\u{a802}'..='\u{a802}', '\u{a806}'..='\u{a806}', '\u{a80b}'..='\u{a80b}', + '\u{a825}'..='\u{a826}', '\u{a82c}'..='\u{a82c}', '\u{a8c4}'..='\u{a8c5}', + '\u{a8e0}'..='\u{a8f1}', '\u{a8ff}'..='\u{a8ff}', '\u{a926}'..='\u{a92d}', + '\u{a947}'..='\u{a951}', '\u{a953}'..='\u{a953}', '\u{a980}'..='\u{a982}', + '\u{a9b3}'..='\u{a9b3}', '\u{a9b6}'..='\u{a9b9}', '\u{a9bc}'..='\u{a9bd}', + '\u{a9c0}'..='\u{a9c0}', '\u{a9e5}'..='\u{a9e5}', '\u{aa29}'..='\u{aa2e}', + '\u{aa31}'..='\u{aa32}', '\u{aa35}'..='\u{aa36}', '\u{aa43}'..='\u{aa43}', + '\u{aa4c}'..='\u{aa4c}', '\u{aa7c}'..='\u{aa7c}', '\u{aab0}'..='\u{aab0}', + '\u{aab2}'..='\u{aab4}', '\u{aab7}'..='\u{aab8}', '\u{aabe}'..='\u{aabf}', + '\u{aac1}'..='\u{aac1}', '\u{aaec}'..='\u{aaed}', '\u{aaf6}'..='\u{aaf6}', + '\u{abe5}'..='\u{abe5}', '\u{abe8}'..='\u{abe8}', '\u{abed}'..='\u{abed}', + '\u{fb1e}'..='\u{fb1e}', '\u{fe00}'..='\u{fe0f}', '\u{fe20}'..='\u{fe2f}', + '\u{ff9e}'..='\u{ff9f}', '\u{101fd}'..='\u{101fd}', '\u{102e0}'..='\u{102e0}', + '\u{10376}'..='\u{1037a}', '\u{10a01}'..='\u{10a03}', '\u{10a05}'..='\u{10a06}', + '\u{10a0c}'..='\u{10a0f}', '\u{10a38}'..='\u{10a3a}', '\u{10a3f}'..='\u{10a3f}', + '\u{10ae5}'..='\u{10ae6}', '\u{10d24}'..='\u{10d27}', '\u{10d69}'..='\u{10d6d}', + '\u{10eab}'..='\u{10eac}', '\u{10efa}'..='\u{10eff}', '\u{10f46}'..='\u{10f50}', + '\u{10f82}'..='\u{10f85}', '\u{11001}'..='\u{11001}', '\u{11038}'..='\u{11046}', + '\u{11070}'..='\u{11070}', '\u{11073}'..='\u{11074}', '\u{1107f}'..='\u{11081}', + '\u{110b3}'..='\u{110b6}', '\u{110b9}'..='\u{110ba}', '\u{110c2}'..='\u{110c2}', + '\u{11100}'..='\u{11102}', '\u{11127}'..='\u{1112b}', '\u{1112d}'..='\u{11134}', + '\u{11173}'..='\u{11173}', '\u{11180}'..='\u{11181}', '\u{111b6}'..='\u{111be}', + '\u{111c0}'..='\u{111c0}', '\u{111c9}'..='\u{111cc}', '\u{111cf}'..='\u{111cf}', + '\u{1122f}'..='\u{11231}', '\u{11234}'..='\u{11237}', '\u{1123e}'..='\u{1123e}', + '\u{11241}'..='\u{11241}', '\u{112df}'..='\u{112df}', '\u{112e3}'..='\u{112ea}', + '\u{11300}'..='\u{11301}', '\u{1133b}'..='\u{1133c}', '\u{1133e}'..='\u{1133e}', + '\u{11340}'..='\u{11340}', '\u{1134d}'..='\u{1134d}', '\u{11357}'..='\u{11357}', + '\u{11366}'..='\u{1136c}', '\u{11370}'..='\u{11374}', '\u{113b8}'..='\u{113b8}', + '\u{113bb}'..='\u{113c0}', '\u{113c2}'..='\u{113c2}', '\u{113c5}'..='\u{113c5}', + '\u{113c7}'..='\u{113c9}', '\u{113ce}'..='\u{113d0}', '\u{113d2}'..='\u{113d2}', + '\u{113e1}'..='\u{113e2}', '\u{11438}'..='\u{1143f}', '\u{11442}'..='\u{11444}', + '\u{11446}'..='\u{11446}', '\u{1145e}'..='\u{1145e}', '\u{114b0}'..='\u{114b0}', + '\u{114b3}'..='\u{114b8}', '\u{114ba}'..='\u{114ba}', '\u{114bd}'..='\u{114bd}', + '\u{114bf}'..='\u{114c0}', '\u{114c2}'..='\u{114c3}', '\u{115af}'..='\u{115af}', + '\u{115b2}'..='\u{115b5}', '\u{115bc}'..='\u{115bd}', '\u{115bf}'..='\u{115c0}', + '\u{115dc}'..='\u{115dd}', '\u{11633}'..='\u{1163a}', '\u{1163d}'..='\u{1163d}', + '\u{1163f}'..='\u{11640}', '\u{116ab}'..='\u{116ab}', '\u{116ad}'..='\u{116ad}', + '\u{116b0}'..='\u{116b7}', '\u{1171d}'..='\u{1171d}', '\u{1171f}'..='\u{1171f}', + '\u{11722}'..='\u{11725}', '\u{11727}'..='\u{1172b}', '\u{1182f}'..='\u{11837}', + '\u{11839}'..='\u{1183a}', '\u{11930}'..='\u{11930}', '\u{1193b}'..='\u{1193e}', + '\u{11943}'..='\u{11943}', '\u{119d4}'..='\u{119d7}', '\u{119da}'..='\u{119db}', + '\u{119e0}'..='\u{119e0}', '\u{11a01}'..='\u{11a0a}', '\u{11a33}'..='\u{11a38}', + '\u{11a3b}'..='\u{11a3e}', '\u{11a47}'..='\u{11a47}', '\u{11a51}'..='\u{11a56}', + '\u{11a59}'..='\u{11a5b}', '\u{11a8a}'..='\u{11a96}', '\u{11a98}'..='\u{11a99}', + '\u{11b60}'..='\u{11b60}', '\u{11b62}'..='\u{11b64}', '\u{11b66}'..='\u{11b66}', + '\u{11c30}'..='\u{11c36}', '\u{11c38}'..='\u{11c3d}', '\u{11c3f}'..='\u{11c3f}', + '\u{11c92}'..='\u{11ca7}', '\u{11caa}'..='\u{11cb0}', '\u{11cb2}'..='\u{11cb3}', + '\u{11cb5}'..='\u{11cb6}', '\u{11d31}'..='\u{11d36}', '\u{11d3a}'..='\u{11d3a}', + '\u{11d3c}'..='\u{11d3d}', '\u{11d3f}'..='\u{11d45}', '\u{11d47}'..='\u{11d47}', + '\u{11d90}'..='\u{11d91}', '\u{11d95}'..='\u{11d95}', '\u{11d97}'..='\u{11d97}', + '\u{11ef3}'..='\u{11ef4}', '\u{11f00}'..='\u{11f01}', '\u{11f36}'..='\u{11f3a}', + '\u{11f40}'..='\u{11f42}', '\u{11f5a}'..='\u{11f5a}', '\u{13440}'..='\u{13440}', + '\u{13447}'..='\u{13455}', '\u{1611e}'..='\u{16129}', '\u{1612d}'..='\u{1612f}', + '\u{16af0}'..='\u{16af4}', '\u{16b30}'..='\u{16b36}', '\u{16f4f}'..='\u{16f4f}', + '\u{16f8f}'..='\u{16f92}', '\u{16fe4}'..='\u{16fe4}', '\u{16ff0}'..='\u{16ff1}', + '\u{1bc9d}'..='\u{1bc9e}', '\u{1cf00}'..='\u{1cf2d}', '\u{1cf30}'..='\u{1cf46}', + '\u{1d165}'..='\u{1d169}', '\u{1d16d}'..='\u{1d172}', '\u{1d17b}'..='\u{1d182}', + '\u{1d185}'..='\u{1d18b}', '\u{1d1aa}'..='\u{1d1ad}', '\u{1d242}'..='\u{1d244}', + '\u{1da00}'..='\u{1da36}', '\u{1da3b}'..='\u{1da6c}', '\u{1da75}'..='\u{1da75}', + '\u{1da84}'..='\u{1da84}', '\u{1da9b}'..='\u{1da9f}', '\u{1daa1}'..='\u{1daaf}', + '\u{1e000}'..='\u{1e006}', '\u{1e008}'..='\u{1e018}', '\u{1e01b}'..='\u{1e021}', + '\u{1e023}'..='\u{1e024}', '\u{1e026}'..='\u{1e02a}', '\u{1e08f}'..='\u{1e08f}', + '\u{1e130}'..='\u{1e136}', '\u{1e2ae}'..='\u{1e2ae}', '\u{1e2ec}'..='\u{1e2ef}', + '\u{1e4ec}'..='\u{1e4ef}', '\u{1e5ee}'..='\u{1e5ef}', '\u{1e6e3}'..='\u{1e6e3}', + '\u{1e6e6}'..='\u{1e6e6}', '\u{1e6ee}'..='\u{1e6ef}', '\u{1e6f5}'..='\u{1e6f5}', + '\u{1e8d0}'..='\u{1e8d6}', '\u{1e944}'..='\u{1e94a}', '\u{e0020}'..='\u{e007f}', + '\u{e0100}'..='\u{e01ef}', +]; + +#[rustfmt::skip] +pub(super) static LOWERCASE: &[RangeInclusive; 676] = &[ + '\u{aa}'..='\u{aa}', '\u{b5}'..='\u{b5}', '\u{ba}'..='\u{ba}', '\u{df}'..='\u{f6}', + '\u{f8}'..='\u{ff}', '\u{101}'..='\u{101}', '\u{103}'..='\u{103}', '\u{105}'..='\u{105}', + '\u{107}'..='\u{107}', '\u{109}'..='\u{109}', '\u{10b}'..='\u{10b}', '\u{10d}'..='\u{10d}', + '\u{10f}'..='\u{10f}', '\u{111}'..='\u{111}', '\u{113}'..='\u{113}', '\u{115}'..='\u{115}', + '\u{117}'..='\u{117}', '\u{119}'..='\u{119}', '\u{11b}'..='\u{11b}', '\u{11d}'..='\u{11d}', + '\u{11f}'..='\u{11f}', '\u{121}'..='\u{121}', '\u{123}'..='\u{123}', '\u{125}'..='\u{125}', + '\u{127}'..='\u{127}', '\u{129}'..='\u{129}', '\u{12b}'..='\u{12b}', '\u{12d}'..='\u{12d}', + '\u{12f}'..='\u{12f}', '\u{131}'..='\u{131}', '\u{133}'..='\u{133}', '\u{135}'..='\u{135}', + '\u{137}'..='\u{138}', '\u{13a}'..='\u{13a}', '\u{13c}'..='\u{13c}', '\u{13e}'..='\u{13e}', + '\u{140}'..='\u{140}', '\u{142}'..='\u{142}', '\u{144}'..='\u{144}', '\u{146}'..='\u{146}', + '\u{148}'..='\u{149}', '\u{14b}'..='\u{14b}', '\u{14d}'..='\u{14d}', '\u{14f}'..='\u{14f}', + '\u{151}'..='\u{151}', '\u{153}'..='\u{153}', '\u{155}'..='\u{155}', '\u{157}'..='\u{157}', + '\u{159}'..='\u{159}', '\u{15b}'..='\u{15b}', '\u{15d}'..='\u{15d}', '\u{15f}'..='\u{15f}', + '\u{161}'..='\u{161}', '\u{163}'..='\u{163}', '\u{165}'..='\u{165}', '\u{167}'..='\u{167}', + '\u{169}'..='\u{169}', '\u{16b}'..='\u{16b}', '\u{16d}'..='\u{16d}', '\u{16f}'..='\u{16f}', + '\u{171}'..='\u{171}', '\u{173}'..='\u{173}', '\u{175}'..='\u{175}', '\u{177}'..='\u{177}', + '\u{17a}'..='\u{17a}', '\u{17c}'..='\u{17c}', '\u{17e}'..='\u{180}', '\u{183}'..='\u{183}', + '\u{185}'..='\u{185}', '\u{188}'..='\u{188}', '\u{18c}'..='\u{18d}', '\u{192}'..='\u{192}', + '\u{195}'..='\u{195}', '\u{199}'..='\u{19b}', '\u{19e}'..='\u{19e}', '\u{1a1}'..='\u{1a1}', + '\u{1a3}'..='\u{1a3}', '\u{1a5}'..='\u{1a5}', '\u{1a8}'..='\u{1a8}', '\u{1aa}'..='\u{1ab}', + '\u{1ad}'..='\u{1ad}', '\u{1b0}'..='\u{1b0}', '\u{1b4}'..='\u{1b4}', '\u{1b6}'..='\u{1b6}', + '\u{1b9}'..='\u{1ba}', '\u{1bd}'..='\u{1bf}', '\u{1c6}'..='\u{1c6}', '\u{1c9}'..='\u{1c9}', + '\u{1cc}'..='\u{1cc}', '\u{1ce}'..='\u{1ce}', '\u{1d0}'..='\u{1d0}', '\u{1d2}'..='\u{1d2}', + '\u{1d4}'..='\u{1d4}', '\u{1d6}'..='\u{1d6}', '\u{1d8}'..='\u{1d8}', '\u{1da}'..='\u{1da}', + '\u{1dc}'..='\u{1dd}', '\u{1df}'..='\u{1df}', '\u{1e1}'..='\u{1e1}', '\u{1e3}'..='\u{1e3}', + '\u{1e5}'..='\u{1e5}', '\u{1e7}'..='\u{1e7}', '\u{1e9}'..='\u{1e9}', '\u{1eb}'..='\u{1eb}', + '\u{1ed}'..='\u{1ed}', '\u{1ef}'..='\u{1f0}', '\u{1f3}'..='\u{1f3}', '\u{1f5}'..='\u{1f5}', + '\u{1f9}'..='\u{1f9}', '\u{1fb}'..='\u{1fb}', '\u{1fd}'..='\u{1fd}', '\u{1ff}'..='\u{1ff}', + '\u{201}'..='\u{201}', '\u{203}'..='\u{203}', '\u{205}'..='\u{205}', '\u{207}'..='\u{207}', + '\u{209}'..='\u{209}', '\u{20b}'..='\u{20b}', '\u{20d}'..='\u{20d}', '\u{20f}'..='\u{20f}', + '\u{211}'..='\u{211}', '\u{213}'..='\u{213}', '\u{215}'..='\u{215}', '\u{217}'..='\u{217}', + '\u{219}'..='\u{219}', '\u{21b}'..='\u{21b}', '\u{21d}'..='\u{21d}', '\u{21f}'..='\u{21f}', + '\u{221}'..='\u{221}', '\u{223}'..='\u{223}', '\u{225}'..='\u{225}', '\u{227}'..='\u{227}', + '\u{229}'..='\u{229}', '\u{22b}'..='\u{22b}', '\u{22d}'..='\u{22d}', '\u{22f}'..='\u{22f}', + '\u{231}'..='\u{231}', '\u{233}'..='\u{239}', '\u{23c}'..='\u{23c}', '\u{23f}'..='\u{240}', + '\u{242}'..='\u{242}', '\u{247}'..='\u{247}', '\u{249}'..='\u{249}', '\u{24b}'..='\u{24b}', + '\u{24d}'..='\u{24d}', '\u{24f}'..='\u{293}', '\u{296}'..='\u{2b8}', '\u{2c0}'..='\u{2c1}', + '\u{2e0}'..='\u{2e4}', '\u{345}'..='\u{345}', '\u{371}'..='\u{371}', '\u{373}'..='\u{373}', + '\u{377}'..='\u{377}', '\u{37a}'..='\u{37d}', '\u{390}'..='\u{390}', '\u{3ac}'..='\u{3ce}', + '\u{3d0}'..='\u{3d1}', '\u{3d5}'..='\u{3d7}', '\u{3d9}'..='\u{3d9}', '\u{3db}'..='\u{3db}', + '\u{3dd}'..='\u{3dd}', '\u{3df}'..='\u{3df}', '\u{3e1}'..='\u{3e1}', '\u{3e3}'..='\u{3e3}', + '\u{3e5}'..='\u{3e5}', '\u{3e7}'..='\u{3e7}', '\u{3e9}'..='\u{3e9}', '\u{3eb}'..='\u{3eb}', + '\u{3ed}'..='\u{3ed}', '\u{3ef}'..='\u{3f3}', '\u{3f5}'..='\u{3f5}', '\u{3f8}'..='\u{3f8}', + '\u{3fb}'..='\u{3fc}', '\u{430}'..='\u{45f}', '\u{461}'..='\u{461}', '\u{463}'..='\u{463}', + '\u{465}'..='\u{465}', '\u{467}'..='\u{467}', '\u{469}'..='\u{469}', '\u{46b}'..='\u{46b}', + '\u{46d}'..='\u{46d}', '\u{46f}'..='\u{46f}', '\u{471}'..='\u{471}', '\u{473}'..='\u{473}', + '\u{475}'..='\u{475}', '\u{477}'..='\u{477}', '\u{479}'..='\u{479}', '\u{47b}'..='\u{47b}', + '\u{47d}'..='\u{47d}', '\u{47f}'..='\u{47f}', '\u{481}'..='\u{481}', '\u{48b}'..='\u{48b}', + '\u{48d}'..='\u{48d}', '\u{48f}'..='\u{48f}', '\u{491}'..='\u{491}', '\u{493}'..='\u{493}', + '\u{495}'..='\u{495}', '\u{497}'..='\u{497}', '\u{499}'..='\u{499}', '\u{49b}'..='\u{49b}', + '\u{49d}'..='\u{49d}', '\u{49f}'..='\u{49f}', '\u{4a1}'..='\u{4a1}', '\u{4a3}'..='\u{4a3}', + '\u{4a5}'..='\u{4a5}', '\u{4a7}'..='\u{4a7}', '\u{4a9}'..='\u{4a9}', '\u{4ab}'..='\u{4ab}', + '\u{4ad}'..='\u{4ad}', '\u{4af}'..='\u{4af}', '\u{4b1}'..='\u{4b1}', '\u{4b3}'..='\u{4b3}', + '\u{4b5}'..='\u{4b5}', '\u{4b7}'..='\u{4b7}', '\u{4b9}'..='\u{4b9}', '\u{4bb}'..='\u{4bb}', + '\u{4bd}'..='\u{4bd}', '\u{4bf}'..='\u{4bf}', '\u{4c2}'..='\u{4c2}', '\u{4c4}'..='\u{4c4}', + '\u{4c6}'..='\u{4c6}', '\u{4c8}'..='\u{4c8}', '\u{4ca}'..='\u{4ca}', '\u{4cc}'..='\u{4cc}', + '\u{4ce}'..='\u{4cf}', '\u{4d1}'..='\u{4d1}', '\u{4d3}'..='\u{4d3}', '\u{4d5}'..='\u{4d5}', + '\u{4d7}'..='\u{4d7}', '\u{4d9}'..='\u{4d9}', '\u{4db}'..='\u{4db}', '\u{4dd}'..='\u{4dd}', + '\u{4df}'..='\u{4df}', '\u{4e1}'..='\u{4e1}', '\u{4e3}'..='\u{4e3}', '\u{4e5}'..='\u{4e5}', + '\u{4e7}'..='\u{4e7}', '\u{4e9}'..='\u{4e9}', '\u{4eb}'..='\u{4eb}', '\u{4ed}'..='\u{4ed}', + '\u{4ef}'..='\u{4ef}', '\u{4f1}'..='\u{4f1}', '\u{4f3}'..='\u{4f3}', '\u{4f5}'..='\u{4f5}', + '\u{4f7}'..='\u{4f7}', '\u{4f9}'..='\u{4f9}', '\u{4fb}'..='\u{4fb}', '\u{4fd}'..='\u{4fd}', + '\u{4ff}'..='\u{4ff}', '\u{501}'..='\u{501}', '\u{503}'..='\u{503}', '\u{505}'..='\u{505}', + '\u{507}'..='\u{507}', '\u{509}'..='\u{509}', '\u{50b}'..='\u{50b}', '\u{50d}'..='\u{50d}', + '\u{50f}'..='\u{50f}', '\u{511}'..='\u{511}', '\u{513}'..='\u{513}', '\u{515}'..='\u{515}', + '\u{517}'..='\u{517}', '\u{519}'..='\u{519}', '\u{51b}'..='\u{51b}', '\u{51d}'..='\u{51d}', + '\u{51f}'..='\u{51f}', '\u{521}'..='\u{521}', '\u{523}'..='\u{523}', '\u{525}'..='\u{525}', + '\u{527}'..='\u{527}', '\u{529}'..='\u{529}', '\u{52b}'..='\u{52b}', '\u{52d}'..='\u{52d}', + '\u{52f}'..='\u{52f}', '\u{560}'..='\u{588}', '\u{10d0}'..='\u{10fa}', + '\u{10fc}'..='\u{10ff}', '\u{13f8}'..='\u{13fd}', '\u{1c80}'..='\u{1c88}', + '\u{1c8a}'..='\u{1c8a}', '\u{1d00}'..='\u{1dbf}', '\u{1e01}'..='\u{1e01}', + '\u{1e03}'..='\u{1e03}', '\u{1e05}'..='\u{1e05}', '\u{1e07}'..='\u{1e07}', + '\u{1e09}'..='\u{1e09}', '\u{1e0b}'..='\u{1e0b}', '\u{1e0d}'..='\u{1e0d}', + '\u{1e0f}'..='\u{1e0f}', '\u{1e11}'..='\u{1e11}', '\u{1e13}'..='\u{1e13}', + '\u{1e15}'..='\u{1e15}', '\u{1e17}'..='\u{1e17}', '\u{1e19}'..='\u{1e19}', + '\u{1e1b}'..='\u{1e1b}', '\u{1e1d}'..='\u{1e1d}', '\u{1e1f}'..='\u{1e1f}', + '\u{1e21}'..='\u{1e21}', '\u{1e23}'..='\u{1e23}', '\u{1e25}'..='\u{1e25}', + '\u{1e27}'..='\u{1e27}', '\u{1e29}'..='\u{1e29}', '\u{1e2b}'..='\u{1e2b}', + '\u{1e2d}'..='\u{1e2d}', '\u{1e2f}'..='\u{1e2f}', '\u{1e31}'..='\u{1e31}', + '\u{1e33}'..='\u{1e33}', '\u{1e35}'..='\u{1e35}', '\u{1e37}'..='\u{1e37}', + '\u{1e39}'..='\u{1e39}', '\u{1e3b}'..='\u{1e3b}', '\u{1e3d}'..='\u{1e3d}', + '\u{1e3f}'..='\u{1e3f}', '\u{1e41}'..='\u{1e41}', '\u{1e43}'..='\u{1e43}', + '\u{1e45}'..='\u{1e45}', '\u{1e47}'..='\u{1e47}', '\u{1e49}'..='\u{1e49}', + '\u{1e4b}'..='\u{1e4b}', '\u{1e4d}'..='\u{1e4d}', '\u{1e4f}'..='\u{1e4f}', + '\u{1e51}'..='\u{1e51}', '\u{1e53}'..='\u{1e53}', '\u{1e55}'..='\u{1e55}', + '\u{1e57}'..='\u{1e57}', '\u{1e59}'..='\u{1e59}', '\u{1e5b}'..='\u{1e5b}', + '\u{1e5d}'..='\u{1e5d}', '\u{1e5f}'..='\u{1e5f}', '\u{1e61}'..='\u{1e61}', + '\u{1e63}'..='\u{1e63}', '\u{1e65}'..='\u{1e65}', '\u{1e67}'..='\u{1e67}', + '\u{1e69}'..='\u{1e69}', '\u{1e6b}'..='\u{1e6b}', '\u{1e6d}'..='\u{1e6d}', + '\u{1e6f}'..='\u{1e6f}', '\u{1e71}'..='\u{1e71}', '\u{1e73}'..='\u{1e73}', + '\u{1e75}'..='\u{1e75}', '\u{1e77}'..='\u{1e77}', '\u{1e79}'..='\u{1e79}', + '\u{1e7b}'..='\u{1e7b}', '\u{1e7d}'..='\u{1e7d}', '\u{1e7f}'..='\u{1e7f}', + '\u{1e81}'..='\u{1e81}', '\u{1e83}'..='\u{1e83}', '\u{1e85}'..='\u{1e85}', + '\u{1e87}'..='\u{1e87}', '\u{1e89}'..='\u{1e89}', '\u{1e8b}'..='\u{1e8b}', + '\u{1e8d}'..='\u{1e8d}', '\u{1e8f}'..='\u{1e8f}', '\u{1e91}'..='\u{1e91}', + '\u{1e93}'..='\u{1e93}', '\u{1e95}'..='\u{1e9d}', '\u{1e9f}'..='\u{1e9f}', + '\u{1ea1}'..='\u{1ea1}', '\u{1ea3}'..='\u{1ea3}', '\u{1ea5}'..='\u{1ea5}', + '\u{1ea7}'..='\u{1ea7}', '\u{1ea9}'..='\u{1ea9}', '\u{1eab}'..='\u{1eab}', + '\u{1ead}'..='\u{1ead}', '\u{1eaf}'..='\u{1eaf}', '\u{1eb1}'..='\u{1eb1}', + '\u{1eb3}'..='\u{1eb3}', '\u{1eb5}'..='\u{1eb5}', '\u{1eb7}'..='\u{1eb7}', + '\u{1eb9}'..='\u{1eb9}', '\u{1ebb}'..='\u{1ebb}', '\u{1ebd}'..='\u{1ebd}', + '\u{1ebf}'..='\u{1ebf}', '\u{1ec1}'..='\u{1ec1}', '\u{1ec3}'..='\u{1ec3}', + '\u{1ec5}'..='\u{1ec5}', '\u{1ec7}'..='\u{1ec7}', '\u{1ec9}'..='\u{1ec9}', + '\u{1ecb}'..='\u{1ecb}', '\u{1ecd}'..='\u{1ecd}', '\u{1ecf}'..='\u{1ecf}', + '\u{1ed1}'..='\u{1ed1}', '\u{1ed3}'..='\u{1ed3}', '\u{1ed5}'..='\u{1ed5}', + '\u{1ed7}'..='\u{1ed7}', '\u{1ed9}'..='\u{1ed9}', '\u{1edb}'..='\u{1edb}', + '\u{1edd}'..='\u{1edd}', '\u{1edf}'..='\u{1edf}', '\u{1ee1}'..='\u{1ee1}', + '\u{1ee3}'..='\u{1ee3}', '\u{1ee5}'..='\u{1ee5}', '\u{1ee7}'..='\u{1ee7}', + '\u{1ee9}'..='\u{1ee9}', '\u{1eeb}'..='\u{1eeb}', '\u{1eed}'..='\u{1eed}', + '\u{1eef}'..='\u{1eef}', '\u{1ef1}'..='\u{1ef1}', '\u{1ef3}'..='\u{1ef3}', + '\u{1ef5}'..='\u{1ef5}', '\u{1ef7}'..='\u{1ef7}', '\u{1ef9}'..='\u{1ef9}', + '\u{1efb}'..='\u{1efb}', '\u{1efd}'..='\u{1efd}', '\u{1eff}'..='\u{1f07}', + '\u{1f10}'..='\u{1f15}', '\u{1f20}'..='\u{1f27}', '\u{1f30}'..='\u{1f37}', + '\u{1f40}'..='\u{1f45}', '\u{1f50}'..='\u{1f57}', '\u{1f60}'..='\u{1f67}', + '\u{1f70}'..='\u{1f7d}', '\u{1f80}'..='\u{1f87}', '\u{1f90}'..='\u{1f97}', + '\u{1fa0}'..='\u{1fa7}', '\u{1fb0}'..='\u{1fb4}', '\u{1fb6}'..='\u{1fb7}', + '\u{1fbe}'..='\u{1fbe}', '\u{1fc2}'..='\u{1fc4}', '\u{1fc6}'..='\u{1fc7}', + '\u{1fd0}'..='\u{1fd3}', '\u{1fd6}'..='\u{1fd7}', '\u{1fe0}'..='\u{1fe7}', + '\u{1ff2}'..='\u{1ff4}', '\u{1ff6}'..='\u{1ff7}', '\u{2071}'..='\u{2071}', + '\u{207f}'..='\u{207f}', '\u{2090}'..='\u{209c}', '\u{210a}'..='\u{210a}', + '\u{210e}'..='\u{210f}', '\u{2113}'..='\u{2113}', '\u{212f}'..='\u{212f}', + '\u{2134}'..='\u{2134}', '\u{2139}'..='\u{2139}', '\u{213c}'..='\u{213d}', + '\u{2146}'..='\u{2149}', '\u{214e}'..='\u{214e}', '\u{2170}'..='\u{217f}', + '\u{2184}'..='\u{2184}', '\u{24d0}'..='\u{24e9}', '\u{2c30}'..='\u{2c5f}', + '\u{2c61}'..='\u{2c61}', '\u{2c65}'..='\u{2c66}', '\u{2c68}'..='\u{2c68}', + '\u{2c6a}'..='\u{2c6a}', '\u{2c6c}'..='\u{2c6c}', '\u{2c71}'..='\u{2c71}', + '\u{2c73}'..='\u{2c74}', '\u{2c76}'..='\u{2c7d}', '\u{2c81}'..='\u{2c81}', + '\u{2c83}'..='\u{2c83}', '\u{2c85}'..='\u{2c85}', '\u{2c87}'..='\u{2c87}', + '\u{2c89}'..='\u{2c89}', '\u{2c8b}'..='\u{2c8b}', '\u{2c8d}'..='\u{2c8d}', + '\u{2c8f}'..='\u{2c8f}', '\u{2c91}'..='\u{2c91}', '\u{2c93}'..='\u{2c93}', + '\u{2c95}'..='\u{2c95}', '\u{2c97}'..='\u{2c97}', '\u{2c99}'..='\u{2c99}', + '\u{2c9b}'..='\u{2c9b}', '\u{2c9d}'..='\u{2c9d}', '\u{2c9f}'..='\u{2c9f}', + '\u{2ca1}'..='\u{2ca1}', '\u{2ca3}'..='\u{2ca3}', '\u{2ca5}'..='\u{2ca5}', + '\u{2ca7}'..='\u{2ca7}', '\u{2ca9}'..='\u{2ca9}', '\u{2cab}'..='\u{2cab}', + '\u{2cad}'..='\u{2cad}', '\u{2caf}'..='\u{2caf}', '\u{2cb1}'..='\u{2cb1}', + '\u{2cb3}'..='\u{2cb3}', '\u{2cb5}'..='\u{2cb5}', '\u{2cb7}'..='\u{2cb7}', + '\u{2cb9}'..='\u{2cb9}', '\u{2cbb}'..='\u{2cbb}', '\u{2cbd}'..='\u{2cbd}', + '\u{2cbf}'..='\u{2cbf}', '\u{2cc1}'..='\u{2cc1}', '\u{2cc3}'..='\u{2cc3}', + '\u{2cc5}'..='\u{2cc5}', '\u{2cc7}'..='\u{2cc7}', '\u{2cc9}'..='\u{2cc9}', + '\u{2ccb}'..='\u{2ccb}', '\u{2ccd}'..='\u{2ccd}', '\u{2ccf}'..='\u{2ccf}', + '\u{2cd1}'..='\u{2cd1}', '\u{2cd3}'..='\u{2cd3}', '\u{2cd5}'..='\u{2cd5}', + '\u{2cd7}'..='\u{2cd7}', '\u{2cd9}'..='\u{2cd9}', '\u{2cdb}'..='\u{2cdb}', + '\u{2cdd}'..='\u{2cdd}', '\u{2cdf}'..='\u{2cdf}', '\u{2ce1}'..='\u{2ce1}', + '\u{2ce3}'..='\u{2ce4}', '\u{2cec}'..='\u{2cec}', '\u{2cee}'..='\u{2cee}', + '\u{2cf3}'..='\u{2cf3}', '\u{2d00}'..='\u{2d25}', '\u{2d27}'..='\u{2d27}', + '\u{2d2d}'..='\u{2d2d}', '\u{a641}'..='\u{a641}', '\u{a643}'..='\u{a643}', + '\u{a645}'..='\u{a645}', '\u{a647}'..='\u{a647}', '\u{a649}'..='\u{a649}', + '\u{a64b}'..='\u{a64b}', '\u{a64d}'..='\u{a64d}', '\u{a64f}'..='\u{a64f}', + '\u{a651}'..='\u{a651}', '\u{a653}'..='\u{a653}', '\u{a655}'..='\u{a655}', + '\u{a657}'..='\u{a657}', '\u{a659}'..='\u{a659}', '\u{a65b}'..='\u{a65b}', + '\u{a65d}'..='\u{a65d}', '\u{a65f}'..='\u{a65f}', '\u{a661}'..='\u{a661}', + '\u{a663}'..='\u{a663}', '\u{a665}'..='\u{a665}', '\u{a667}'..='\u{a667}', + '\u{a669}'..='\u{a669}', '\u{a66b}'..='\u{a66b}', '\u{a66d}'..='\u{a66d}', + '\u{a681}'..='\u{a681}', '\u{a683}'..='\u{a683}', '\u{a685}'..='\u{a685}', + '\u{a687}'..='\u{a687}', '\u{a689}'..='\u{a689}', '\u{a68b}'..='\u{a68b}', + '\u{a68d}'..='\u{a68d}', '\u{a68f}'..='\u{a68f}', '\u{a691}'..='\u{a691}', + '\u{a693}'..='\u{a693}', '\u{a695}'..='\u{a695}', '\u{a697}'..='\u{a697}', + '\u{a699}'..='\u{a699}', '\u{a69b}'..='\u{a69d}', '\u{a723}'..='\u{a723}', + '\u{a725}'..='\u{a725}', '\u{a727}'..='\u{a727}', '\u{a729}'..='\u{a729}', + '\u{a72b}'..='\u{a72b}', '\u{a72d}'..='\u{a72d}', '\u{a72f}'..='\u{a731}', + '\u{a733}'..='\u{a733}', '\u{a735}'..='\u{a735}', '\u{a737}'..='\u{a737}', + '\u{a739}'..='\u{a739}', '\u{a73b}'..='\u{a73b}', '\u{a73d}'..='\u{a73d}', + '\u{a73f}'..='\u{a73f}', '\u{a741}'..='\u{a741}', '\u{a743}'..='\u{a743}', + '\u{a745}'..='\u{a745}', '\u{a747}'..='\u{a747}', '\u{a749}'..='\u{a749}', + '\u{a74b}'..='\u{a74b}', '\u{a74d}'..='\u{a74d}', '\u{a74f}'..='\u{a74f}', + '\u{a751}'..='\u{a751}', '\u{a753}'..='\u{a753}', '\u{a755}'..='\u{a755}', + '\u{a757}'..='\u{a757}', '\u{a759}'..='\u{a759}', '\u{a75b}'..='\u{a75b}', + '\u{a75d}'..='\u{a75d}', '\u{a75f}'..='\u{a75f}', '\u{a761}'..='\u{a761}', + '\u{a763}'..='\u{a763}', '\u{a765}'..='\u{a765}', '\u{a767}'..='\u{a767}', + '\u{a769}'..='\u{a769}', '\u{a76b}'..='\u{a76b}', '\u{a76d}'..='\u{a76d}', + '\u{a76f}'..='\u{a778}', '\u{a77a}'..='\u{a77a}', '\u{a77c}'..='\u{a77c}', + '\u{a77f}'..='\u{a77f}', '\u{a781}'..='\u{a781}', '\u{a783}'..='\u{a783}', + '\u{a785}'..='\u{a785}', '\u{a787}'..='\u{a787}', '\u{a78c}'..='\u{a78c}', + '\u{a78e}'..='\u{a78e}', '\u{a791}'..='\u{a791}', '\u{a793}'..='\u{a795}', + '\u{a797}'..='\u{a797}', '\u{a799}'..='\u{a799}', '\u{a79b}'..='\u{a79b}', + '\u{a79d}'..='\u{a79d}', '\u{a79f}'..='\u{a79f}', '\u{a7a1}'..='\u{a7a1}', + '\u{a7a3}'..='\u{a7a3}', '\u{a7a5}'..='\u{a7a5}', '\u{a7a7}'..='\u{a7a7}', + '\u{a7a9}'..='\u{a7a9}', '\u{a7af}'..='\u{a7af}', '\u{a7b5}'..='\u{a7b5}', + '\u{a7b7}'..='\u{a7b7}', '\u{a7b9}'..='\u{a7b9}', '\u{a7bb}'..='\u{a7bb}', + '\u{a7bd}'..='\u{a7bd}', '\u{a7bf}'..='\u{a7bf}', '\u{a7c1}'..='\u{a7c1}', + '\u{a7c3}'..='\u{a7c3}', '\u{a7c8}'..='\u{a7c8}', '\u{a7ca}'..='\u{a7ca}', + '\u{a7cd}'..='\u{a7cd}', '\u{a7cf}'..='\u{a7cf}', '\u{a7d1}'..='\u{a7d1}', + '\u{a7d3}'..='\u{a7d3}', '\u{a7d5}'..='\u{a7d5}', '\u{a7d7}'..='\u{a7d7}', + '\u{a7d9}'..='\u{a7d9}', '\u{a7db}'..='\u{a7db}', '\u{a7f1}'..='\u{a7f4}', + '\u{a7f6}'..='\u{a7f6}', '\u{a7f8}'..='\u{a7fa}', '\u{ab30}'..='\u{ab5a}', + '\u{ab5c}'..='\u{ab69}', '\u{ab70}'..='\u{abbf}', '\u{fb00}'..='\u{fb06}', + '\u{fb13}'..='\u{fb17}', '\u{ff41}'..='\u{ff5a}', '\u{10428}'..='\u{1044f}', + '\u{104d8}'..='\u{104fb}', '\u{10597}'..='\u{105a1}', '\u{105a3}'..='\u{105b1}', + '\u{105b3}'..='\u{105b9}', '\u{105bb}'..='\u{105bc}', '\u{10780}'..='\u{10780}', + '\u{10783}'..='\u{10785}', '\u{10787}'..='\u{107b0}', '\u{107b2}'..='\u{107ba}', + '\u{10cc0}'..='\u{10cf2}', '\u{10d70}'..='\u{10d85}', '\u{118c0}'..='\u{118df}', + '\u{16e60}'..='\u{16e7f}', '\u{16ebb}'..='\u{16ed3}', '\u{1d41a}'..='\u{1d433}', + '\u{1d44e}'..='\u{1d454}', '\u{1d456}'..='\u{1d467}', '\u{1d482}'..='\u{1d49b}', + '\u{1d4b6}'..='\u{1d4b9}', '\u{1d4bb}'..='\u{1d4bb}', '\u{1d4bd}'..='\u{1d4c3}', + '\u{1d4c5}'..='\u{1d4cf}', '\u{1d4ea}'..='\u{1d503}', '\u{1d51e}'..='\u{1d537}', + '\u{1d552}'..='\u{1d56b}', '\u{1d586}'..='\u{1d59f}', '\u{1d5ba}'..='\u{1d5d3}', + '\u{1d5ee}'..='\u{1d607}', '\u{1d622}'..='\u{1d63b}', '\u{1d656}'..='\u{1d66f}', + '\u{1d68a}'..='\u{1d6a5}', '\u{1d6c2}'..='\u{1d6da}', '\u{1d6dc}'..='\u{1d6e1}', + '\u{1d6fc}'..='\u{1d714}', '\u{1d716}'..='\u{1d71b}', '\u{1d736}'..='\u{1d74e}', + '\u{1d750}'..='\u{1d755}', '\u{1d770}'..='\u{1d788}', '\u{1d78a}'..='\u{1d78f}', + '\u{1d7aa}'..='\u{1d7c2}', '\u{1d7c4}'..='\u{1d7c9}', '\u{1d7cb}'..='\u{1d7cb}', + '\u{1df00}'..='\u{1df09}', '\u{1df0b}'..='\u{1df1e}', '\u{1df25}'..='\u{1df2a}', + '\u{1e030}'..='\u{1e06d}', '\u{1e922}'..='\u{1e943}', +]; + +#[rustfmt::skip] +pub(super) static N: &[RangeInclusive; 145] = &[ + '\u{b2}'..='\u{b3}', '\u{b9}'..='\u{b9}', '\u{bc}'..='\u{be}', '\u{660}'..='\u{669}', + '\u{6f0}'..='\u{6f9}', '\u{7c0}'..='\u{7c9}', '\u{966}'..='\u{96f}', '\u{9e6}'..='\u{9ef}', + '\u{9f4}'..='\u{9f9}', '\u{a66}'..='\u{a6f}', '\u{ae6}'..='\u{aef}', '\u{b66}'..='\u{b6f}', + '\u{b72}'..='\u{b77}', '\u{be6}'..='\u{bf2}', '\u{c66}'..='\u{c6f}', '\u{c78}'..='\u{c7e}', + '\u{ce6}'..='\u{cef}', '\u{d58}'..='\u{d5e}', '\u{d66}'..='\u{d78}', '\u{de6}'..='\u{def}', + '\u{e50}'..='\u{e59}', '\u{ed0}'..='\u{ed9}', '\u{f20}'..='\u{f33}', + '\u{1040}'..='\u{1049}', '\u{1090}'..='\u{1099}', '\u{1369}'..='\u{137c}', + '\u{16ee}'..='\u{16f0}', '\u{17e0}'..='\u{17e9}', '\u{17f0}'..='\u{17f9}', + '\u{1810}'..='\u{1819}', '\u{1946}'..='\u{194f}', '\u{19d0}'..='\u{19da}', + '\u{1a80}'..='\u{1a89}', '\u{1a90}'..='\u{1a99}', '\u{1b50}'..='\u{1b59}', + '\u{1bb0}'..='\u{1bb9}', '\u{1c40}'..='\u{1c49}', '\u{1c50}'..='\u{1c59}', + '\u{2070}'..='\u{2070}', '\u{2074}'..='\u{2079}', '\u{2080}'..='\u{2089}', + '\u{2150}'..='\u{2182}', '\u{2185}'..='\u{2189}', '\u{2460}'..='\u{249b}', + '\u{24ea}'..='\u{24ff}', '\u{2776}'..='\u{2793}', '\u{2cfd}'..='\u{2cfd}', + '\u{3007}'..='\u{3007}', '\u{3021}'..='\u{3029}', '\u{3038}'..='\u{303a}', + '\u{3192}'..='\u{3195}', '\u{3220}'..='\u{3229}', '\u{3248}'..='\u{324f}', + '\u{3251}'..='\u{325f}', '\u{3280}'..='\u{3289}', '\u{32b1}'..='\u{32bf}', + '\u{a620}'..='\u{a629}', '\u{a6e6}'..='\u{a6ef}', '\u{a830}'..='\u{a835}', + '\u{a8d0}'..='\u{a8d9}', '\u{a900}'..='\u{a909}', '\u{a9d0}'..='\u{a9d9}', + '\u{a9f0}'..='\u{a9f9}', '\u{aa50}'..='\u{aa59}', '\u{abf0}'..='\u{abf9}', + '\u{ff10}'..='\u{ff19}', '\u{10107}'..='\u{10133}', '\u{10140}'..='\u{10178}', + '\u{1018a}'..='\u{1018b}', '\u{102e1}'..='\u{102fb}', '\u{10320}'..='\u{10323}', + '\u{10341}'..='\u{10341}', '\u{1034a}'..='\u{1034a}', '\u{103d1}'..='\u{103d5}', + '\u{104a0}'..='\u{104a9}', '\u{10858}'..='\u{1085f}', '\u{10879}'..='\u{1087f}', + '\u{108a7}'..='\u{108af}', '\u{108fb}'..='\u{108ff}', '\u{10916}'..='\u{1091b}', + '\u{109bc}'..='\u{109bd}', '\u{109c0}'..='\u{109cf}', '\u{109d2}'..='\u{109ff}', + '\u{10a40}'..='\u{10a48}', '\u{10a7d}'..='\u{10a7e}', '\u{10a9d}'..='\u{10a9f}', + '\u{10aeb}'..='\u{10aef}', '\u{10b58}'..='\u{10b5f}', '\u{10b78}'..='\u{10b7f}', + '\u{10ba9}'..='\u{10baf}', '\u{10cfa}'..='\u{10cff}', '\u{10d30}'..='\u{10d39}', + '\u{10d40}'..='\u{10d49}', '\u{10e60}'..='\u{10e7e}', '\u{10f1d}'..='\u{10f26}', + '\u{10f51}'..='\u{10f54}', '\u{10fc5}'..='\u{10fcb}', '\u{11052}'..='\u{1106f}', + '\u{110f0}'..='\u{110f9}', '\u{11136}'..='\u{1113f}', '\u{111d0}'..='\u{111d9}', + '\u{111e1}'..='\u{111f4}', '\u{112f0}'..='\u{112f9}', '\u{11450}'..='\u{11459}', + '\u{114d0}'..='\u{114d9}', '\u{11650}'..='\u{11659}', '\u{116c0}'..='\u{116c9}', + '\u{116d0}'..='\u{116e3}', '\u{11730}'..='\u{1173b}', '\u{118e0}'..='\u{118f2}', + '\u{11950}'..='\u{11959}', '\u{11bf0}'..='\u{11bf9}', '\u{11c50}'..='\u{11c6c}', + '\u{11d50}'..='\u{11d59}', '\u{11da0}'..='\u{11da9}', '\u{11de0}'..='\u{11de9}', + '\u{11f50}'..='\u{11f59}', '\u{11fc0}'..='\u{11fd4}', '\u{12400}'..='\u{1246e}', + '\u{16130}'..='\u{16139}', '\u{16a60}'..='\u{16a69}', '\u{16ac0}'..='\u{16ac9}', + '\u{16b50}'..='\u{16b59}', '\u{16b5b}'..='\u{16b61}', '\u{16d70}'..='\u{16d79}', + '\u{16e80}'..='\u{16e96}', '\u{16ff4}'..='\u{16ff6}', '\u{1ccf0}'..='\u{1ccf9}', + '\u{1d2c0}'..='\u{1d2d3}', '\u{1d2e0}'..='\u{1d2f3}', '\u{1d360}'..='\u{1d378}', + '\u{1d7ce}'..='\u{1d7ff}', '\u{1e140}'..='\u{1e149}', '\u{1e2f0}'..='\u{1e2f9}', + '\u{1e4f0}'..='\u{1e4f9}', '\u{1e5f1}'..='\u{1e5fa}', '\u{1e8c7}'..='\u{1e8cf}', + '\u{1e950}'..='\u{1e959}', '\u{1ec71}'..='\u{1ecab}', '\u{1ecad}'..='\u{1ecaf}', + '\u{1ecb1}'..='\u{1ecb4}', '\u{1ed01}'..='\u{1ed2d}', '\u{1ed2f}'..='\u{1ed3d}', + '\u{1f100}'..='\u{1f10c}', '\u{1fbf0}'..='\u{1fbf9}', +]; + +#[rustfmt::skip] +pub(super) static UPPERCASE: &[RangeInclusive; 659] = &[ + '\u{c0}'..='\u{d6}', '\u{d8}'..='\u{de}', '\u{100}'..='\u{100}', '\u{102}'..='\u{102}', + '\u{104}'..='\u{104}', '\u{106}'..='\u{106}', '\u{108}'..='\u{108}', '\u{10a}'..='\u{10a}', + '\u{10c}'..='\u{10c}', '\u{10e}'..='\u{10e}', '\u{110}'..='\u{110}', '\u{112}'..='\u{112}', + '\u{114}'..='\u{114}', '\u{116}'..='\u{116}', '\u{118}'..='\u{118}', '\u{11a}'..='\u{11a}', + '\u{11c}'..='\u{11c}', '\u{11e}'..='\u{11e}', '\u{120}'..='\u{120}', '\u{122}'..='\u{122}', + '\u{124}'..='\u{124}', '\u{126}'..='\u{126}', '\u{128}'..='\u{128}', '\u{12a}'..='\u{12a}', + '\u{12c}'..='\u{12c}', '\u{12e}'..='\u{12e}', '\u{130}'..='\u{130}', '\u{132}'..='\u{132}', + '\u{134}'..='\u{134}', '\u{136}'..='\u{136}', '\u{139}'..='\u{139}', '\u{13b}'..='\u{13b}', + '\u{13d}'..='\u{13d}', '\u{13f}'..='\u{13f}', '\u{141}'..='\u{141}', '\u{143}'..='\u{143}', + '\u{145}'..='\u{145}', '\u{147}'..='\u{147}', '\u{14a}'..='\u{14a}', '\u{14c}'..='\u{14c}', + '\u{14e}'..='\u{14e}', '\u{150}'..='\u{150}', '\u{152}'..='\u{152}', '\u{154}'..='\u{154}', + '\u{156}'..='\u{156}', '\u{158}'..='\u{158}', '\u{15a}'..='\u{15a}', '\u{15c}'..='\u{15c}', + '\u{15e}'..='\u{15e}', '\u{160}'..='\u{160}', '\u{162}'..='\u{162}', '\u{164}'..='\u{164}', + '\u{166}'..='\u{166}', '\u{168}'..='\u{168}', '\u{16a}'..='\u{16a}', '\u{16c}'..='\u{16c}', + '\u{16e}'..='\u{16e}', '\u{170}'..='\u{170}', '\u{172}'..='\u{172}', '\u{174}'..='\u{174}', + '\u{176}'..='\u{176}', '\u{178}'..='\u{179}', '\u{17b}'..='\u{17b}', '\u{17d}'..='\u{17d}', + '\u{181}'..='\u{182}', '\u{184}'..='\u{184}', '\u{186}'..='\u{187}', '\u{189}'..='\u{18b}', + '\u{18e}'..='\u{191}', '\u{193}'..='\u{194}', '\u{196}'..='\u{198}', '\u{19c}'..='\u{19d}', + '\u{19f}'..='\u{1a0}', '\u{1a2}'..='\u{1a2}', '\u{1a4}'..='\u{1a4}', '\u{1a6}'..='\u{1a7}', + '\u{1a9}'..='\u{1a9}', '\u{1ac}'..='\u{1ac}', '\u{1ae}'..='\u{1af}', '\u{1b1}'..='\u{1b3}', + '\u{1b5}'..='\u{1b5}', '\u{1b7}'..='\u{1b8}', '\u{1bc}'..='\u{1bc}', '\u{1c4}'..='\u{1c4}', + '\u{1c7}'..='\u{1c7}', '\u{1ca}'..='\u{1ca}', '\u{1cd}'..='\u{1cd}', '\u{1cf}'..='\u{1cf}', + '\u{1d1}'..='\u{1d1}', '\u{1d3}'..='\u{1d3}', '\u{1d5}'..='\u{1d5}', '\u{1d7}'..='\u{1d7}', + '\u{1d9}'..='\u{1d9}', '\u{1db}'..='\u{1db}', '\u{1de}'..='\u{1de}', '\u{1e0}'..='\u{1e0}', + '\u{1e2}'..='\u{1e2}', '\u{1e4}'..='\u{1e4}', '\u{1e6}'..='\u{1e6}', '\u{1e8}'..='\u{1e8}', + '\u{1ea}'..='\u{1ea}', '\u{1ec}'..='\u{1ec}', '\u{1ee}'..='\u{1ee}', '\u{1f1}'..='\u{1f1}', + '\u{1f4}'..='\u{1f4}', '\u{1f6}'..='\u{1f8}', '\u{1fa}'..='\u{1fa}', '\u{1fc}'..='\u{1fc}', + '\u{1fe}'..='\u{1fe}', '\u{200}'..='\u{200}', '\u{202}'..='\u{202}', '\u{204}'..='\u{204}', + '\u{206}'..='\u{206}', '\u{208}'..='\u{208}', '\u{20a}'..='\u{20a}', '\u{20c}'..='\u{20c}', + '\u{20e}'..='\u{20e}', '\u{210}'..='\u{210}', '\u{212}'..='\u{212}', '\u{214}'..='\u{214}', + '\u{216}'..='\u{216}', '\u{218}'..='\u{218}', '\u{21a}'..='\u{21a}', '\u{21c}'..='\u{21c}', + '\u{21e}'..='\u{21e}', '\u{220}'..='\u{220}', '\u{222}'..='\u{222}', '\u{224}'..='\u{224}', + '\u{226}'..='\u{226}', '\u{228}'..='\u{228}', '\u{22a}'..='\u{22a}', '\u{22c}'..='\u{22c}', + '\u{22e}'..='\u{22e}', '\u{230}'..='\u{230}', '\u{232}'..='\u{232}', '\u{23a}'..='\u{23b}', + '\u{23d}'..='\u{23e}', '\u{241}'..='\u{241}', '\u{243}'..='\u{246}', '\u{248}'..='\u{248}', + '\u{24a}'..='\u{24a}', '\u{24c}'..='\u{24c}', '\u{24e}'..='\u{24e}', '\u{370}'..='\u{370}', + '\u{372}'..='\u{372}', '\u{376}'..='\u{376}', '\u{37f}'..='\u{37f}', '\u{386}'..='\u{386}', + '\u{388}'..='\u{38a}', '\u{38c}'..='\u{38c}', '\u{38e}'..='\u{38f}', '\u{391}'..='\u{3a1}', + '\u{3a3}'..='\u{3ab}', '\u{3cf}'..='\u{3cf}', '\u{3d2}'..='\u{3d4}', '\u{3d8}'..='\u{3d8}', + '\u{3da}'..='\u{3da}', '\u{3dc}'..='\u{3dc}', '\u{3de}'..='\u{3de}', '\u{3e0}'..='\u{3e0}', + '\u{3e2}'..='\u{3e2}', '\u{3e4}'..='\u{3e4}', '\u{3e6}'..='\u{3e6}', '\u{3e8}'..='\u{3e8}', + '\u{3ea}'..='\u{3ea}', '\u{3ec}'..='\u{3ec}', '\u{3ee}'..='\u{3ee}', '\u{3f4}'..='\u{3f4}', + '\u{3f7}'..='\u{3f7}', '\u{3f9}'..='\u{3fa}', '\u{3fd}'..='\u{42f}', '\u{460}'..='\u{460}', + '\u{462}'..='\u{462}', '\u{464}'..='\u{464}', '\u{466}'..='\u{466}', '\u{468}'..='\u{468}', + '\u{46a}'..='\u{46a}', '\u{46c}'..='\u{46c}', '\u{46e}'..='\u{46e}', '\u{470}'..='\u{470}', + '\u{472}'..='\u{472}', '\u{474}'..='\u{474}', '\u{476}'..='\u{476}', '\u{478}'..='\u{478}', + '\u{47a}'..='\u{47a}', '\u{47c}'..='\u{47c}', '\u{47e}'..='\u{47e}', '\u{480}'..='\u{480}', + '\u{48a}'..='\u{48a}', '\u{48c}'..='\u{48c}', '\u{48e}'..='\u{48e}', '\u{490}'..='\u{490}', + '\u{492}'..='\u{492}', '\u{494}'..='\u{494}', '\u{496}'..='\u{496}', '\u{498}'..='\u{498}', + '\u{49a}'..='\u{49a}', '\u{49c}'..='\u{49c}', '\u{49e}'..='\u{49e}', '\u{4a0}'..='\u{4a0}', + '\u{4a2}'..='\u{4a2}', '\u{4a4}'..='\u{4a4}', '\u{4a6}'..='\u{4a6}', '\u{4a8}'..='\u{4a8}', + '\u{4aa}'..='\u{4aa}', '\u{4ac}'..='\u{4ac}', '\u{4ae}'..='\u{4ae}', '\u{4b0}'..='\u{4b0}', + '\u{4b2}'..='\u{4b2}', '\u{4b4}'..='\u{4b4}', '\u{4b6}'..='\u{4b6}', '\u{4b8}'..='\u{4b8}', + '\u{4ba}'..='\u{4ba}', '\u{4bc}'..='\u{4bc}', '\u{4be}'..='\u{4be}', '\u{4c0}'..='\u{4c1}', + '\u{4c3}'..='\u{4c3}', '\u{4c5}'..='\u{4c5}', '\u{4c7}'..='\u{4c7}', '\u{4c9}'..='\u{4c9}', + '\u{4cb}'..='\u{4cb}', '\u{4cd}'..='\u{4cd}', '\u{4d0}'..='\u{4d0}', '\u{4d2}'..='\u{4d2}', + '\u{4d4}'..='\u{4d4}', '\u{4d6}'..='\u{4d6}', '\u{4d8}'..='\u{4d8}', '\u{4da}'..='\u{4da}', + '\u{4dc}'..='\u{4dc}', '\u{4de}'..='\u{4de}', '\u{4e0}'..='\u{4e0}', '\u{4e2}'..='\u{4e2}', + '\u{4e4}'..='\u{4e4}', '\u{4e6}'..='\u{4e6}', '\u{4e8}'..='\u{4e8}', '\u{4ea}'..='\u{4ea}', + '\u{4ec}'..='\u{4ec}', '\u{4ee}'..='\u{4ee}', '\u{4f0}'..='\u{4f0}', '\u{4f2}'..='\u{4f2}', + '\u{4f4}'..='\u{4f4}', '\u{4f6}'..='\u{4f6}', '\u{4f8}'..='\u{4f8}', '\u{4fa}'..='\u{4fa}', + '\u{4fc}'..='\u{4fc}', '\u{4fe}'..='\u{4fe}', '\u{500}'..='\u{500}', '\u{502}'..='\u{502}', + '\u{504}'..='\u{504}', '\u{506}'..='\u{506}', '\u{508}'..='\u{508}', '\u{50a}'..='\u{50a}', + '\u{50c}'..='\u{50c}', '\u{50e}'..='\u{50e}', '\u{510}'..='\u{510}', '\u{512}'..='\u{512}', + '\u{514}'..='\u{514}', '\u{516}'..='\u{516}', '\u{518}'..='\u{518}', '\u{51a}'..='\u{51a}', + '\u{51c}'..='\u{51c}', '\u{51e}'..='\u{51e}', '\u{520}'..='\u{520}', '\u{522}'..='\u{522}', + '\u{524}'..='\u{524}', '\u{526}'..='\u{526}', '\u{528}'..='\u{528}', '\u{52a}'..='\u{52a}', + '\u{52c}'..='\u{52c}', '\u{52e}'..='\u{52e}', '\u{531}'..='\u{556}', + '\u{10a0}'..='\u{10c5}', '\u{10c7}'..='\u{10c7}', '\u{10cd}'..='\u{10cd}', + '\u{13a0}'..='\u{13f5}', '\u{1c89}'..='\u{1c89}', '\u{1c90}'..='\u{1cba}', + '\u{1cbd}'..='\u{1cbf}', '\u{1e00}'..='\u{1e00}', '\u{1e02}'..='\u{1e02}', + '\u{1e04}'..='\u{1e04}', '\u{1e06}'..='\u{1e06}', '\u{1e08}'..='\u{1e08}', + '\u{1e0a}'..='\u{1e0a}', '\u{1e0c}'..='\u{1e0c}', '\u{1e0e}'..='\u{1e0e}', + '\u{1e10}'..='\u{1e10}', '\u{1e12}'..='\u{1e12}', '\u{1e14}'..='\u{1e14}', + '\u{1e16}'..='\u{1e16}', '\u{1e18}'..='\u{1e18}', '\u{1e1a}'..='\u{1e1a}', + '\u{1e1c}'..='\u{1e1c}', '\u{1e1e}'..='\u{1e1e}', '\u{1e20}'..='\u{1e20}', + '\u{1e22}'..='\u{1e22}', '\u{1e24}'..='\u{1e24}', '\u{1e26}'..='\u{1e26}', + '\u{1e28}'..='\u{1e28}', '\u{1e2a}'..='\u{1e2a}', '\u{1e2c}'..='\u{1e2c}', + '\u{1e2e}'..='\u{1e2e}', '\u{1e30}'..='\u{1e30}', '\u{1e32}'..='\u{1e32}', + '\u{1e34}'..='\u{1e34}', '\u{1e36}'..='\u{1e36}', '\u{1e38}'..='\u{1e38}', + '\u{1e3a}'..='\u{1e3a}', '\u{1e3c}'..='\u{1e3c}', '\u{1e3e}'..='\u{1e3e}', + '\u{1e40}'..='\u{1e40}', '\u{1e42}'..='\u{1e42}', '\u{1e44}'..='\u{1e44}', + '\u{1e46}'..='\u{1e46}', '\u{1e48}'..='\u{1e48}', '\u{1e4a}'..='\u{1e4a}', + '\u{1e4c}'..='\u{1e4c}', '\u{1e4e}'..='\u{1e4e}', '\u{1e50}'..='\u{1e50}', + '\u{1e52}'..='\u{1e52}', '\u{1e54}'..='\u{1e54}', '\u{1e56}'..='\u{1e56}', + '\u{1e58}'..='\u{1e58}', '\u{1e5a}'..='\u{1e5a}', '\u{1e5c}'..='\u{1e5c}', + '\u{1e5e}'..='\u{1e5e}', '\u{1e60}'..='\u{1e60}', '\u{1e62}'..='\u{1e62}', + '\u{1e64}'..='\u{1e64}', '\u{1e66}'..='\u{1e66}', '\u{1e68}'..='\u{1e68}', + '\u{1e6a}'..='\u{1e6a}', '\u{1e6c}'..='\u{1e6c}', '\u{1e6e}'..='\u{1e6e}', + '\u{1e70}'..='\u{1e70}', '\u{1e72}'..='\u{1e72}', '\u{1e74}'..='\u{1e74}', + '\u{1e76}'..='\u{1e76}', '\u{1e78}'..='\u{1e78}', '\u{1e7a}'..='\u{1e7a}', + '\u{1e7c}'..='\u{1e7c}', '\u{1e7e}'..='\u{1e7e}', '\u{1e80}'..='\u{1e80}', + '\u{1e82}'..='\u{1e82}', '\u{1e84}'..='\u{1e84}', '\u{1e86}'..='\u{1e86}', + '\u{1e88}'..='\u{1e88}', '\u{1e8a}'..='\u{1e8a}', '\u{1e8c}'..='\u{1e8c}', + '\u{1e8e}'..='\u{1e8e}', '\u{1e90}'..='\u{1e90}', '\u{1e92}'..='\u{1e92}', + '\u{1e94}'..='\u{1e94}', '\u{1e9e}'..='\u{1e9e}', '\u{1ea0}'..='\u{1ea0}', + '\u{1ea2}'..='\u{1ea2}', '\u{1ea4}'..='\u{1ea4}', '\u{1ea6}'..='\u{1ea6}', + '\u{1ea8}'..='\u{1ea8}', '\u{1eaa}'..='\u{1eaa}', '\u{1eac}'..='\u{1eac}', + '\u{1eae}'..='\u{1eae}', '\u{1eb0}'..='\u{1eb0}', '\u{1eb2}'..='\u{1eb2}', + '\u{1eb4}'..='\u{1eb4}', '\u{1eb6}'..='\u{1eb6}', '\u{1eb8}'..='\u{1eb8}', + '\u{1eba}'..='\u{1eba}', '\u{1ebc}'..='\u{1ebc}', '\u{1ebe}'..='\u{1ebe}', + '\u{1ec0}'..='\u{1ec0}', '\u{1ec2}'..='\u{1ec2}', '\u{1ec4}'..='\u{1ec4}', + '\u{1ec6}'..='\u{1ec6}', '\u{1ec8}'..='\u{1ec8}', '\u{1eca}'..='\u{1eca}', + '\u{1ecc}'..='\u{1ecc}', '\u{1ece}'..='\u{1ece}', '\u{1ed0}'..='\u{1ed0}', + '\u{1ed2}'..='\u{1ed2}', '\u{1ed4}'..='\u{1ed4}', '\u{1ed6}'..='\u{1ed6}', + '\u{1ed8}'..='\u{1ed8}', '\u{1eda}'..='\u{1eda}', '\u{1edc}'..='\u{1edc}', + '\u{1ede}'..='\u{1ede}', '\u{1ee0}'..='\u{1ee0}', '\u{1ee2}'..='\u{1ee2}', + '\u{1ee4}'..='\u{1ee4}', '\u{1ee6}'..='\u{1ee6}', '\u{1ee8}'..='\u{1ee8}', + '\u{1eea}'..='\u{1eea}', '\u{1eec}'..='\u{1eec}', '\u{1eee}'..='\u{1eee}', + '\u{1ef0}'..='\u{1ef0}', '\u{1ef2}'..='\u{1ef2}', '\u{1ef4}'..='\u{1ef4}', + '\u{1ef6}'..='\u{1ef6}', '\u{1ef8}'..='\u{1ef8}', '\u{1efa}'..='\u{1efa}', + '\u{1efc}'..='\u{1efc}', '\u{1efe}'..='\u{1efe}', '\u{1f08}'..='\u{1f0f}', + '\u{1f18}'..='\u{1f1d}', '\u{1f28}'..='\u{1f2f}', '\u{1f38}'..='\u{1f3f}', + '\u{1f48}'..='\u{1f4d}', '\u{1f59}'..='\u{1f59}', '\u{1f5b}'..='\u{1f5b}', + '\u{1f5d}'..='\u{1f5d}', '\u{1f5f}'..='\u{1f5f}', '\u{1f68}'..='\u{1f6f}', + '\u{1fb8}'..='\u{1fbb}', '\u{1fc8}'..='\u{1fcb}', '\u{1fd8}'..='\u{1fdb}', + '\u{1fe8}'..='\u{1fec}', '\u{1ff8}'..='\u{1ffb}', '\u{2102}'..='\u{2102}', + '\u{2107}'..='\u{2107}', '\u{210b}'..='\u{210d}', '\u{2110}'..='\u{2112}', + '\u{2115}'..='\u{2115}', '\u{2119}'..='\u{211d}', '\u{2124}'..='\u{2124}', + '\u{2126}'..='\u{2126}', '\u{2128}'..='\u{2128}', '\u{212a}'..='\u{212d}', + '\u{2130}'..='\u{2133}', '\u{213e}'..='\u{213f}', '\u{2145}'..='\u{2145}', + '\u{2160}'..='\u{216f}', '\u{2183}'..='\u{2183}', '\u{24b6}'..='\u{24cf}', + '\u{2c00}'..='\u{2c2f}', '\u{2c60}'..='\u{2c60}', '\u{2c62}'..='\u{2c64}', + '\u{2c67}'..='\u{2c67}', '\u{2c69}'..='\u{2c69}', '\u{2c6b}'..='\u{2c6b}', + '\u{2c6d}'..='\u{2c70}', '\u{2c72}'..='\u{2c72}', '\u{2c75}'..='\u{2c75}', + '\u{2c7e}'..='\u{2c80}', '\u{2c82}'..='\u{2c82}', '\u{2c84}'..='\u{2c84}', + '\u{2c86}'..='\u{2c86}', '\u{2c88}'..='\u{2c88}', '\u{2c8a}'..='\u{2c8a}', + '\u{2c8c}'..='\u{2c8c}', '\u{2c8e}'..='\u{2c8e}', '\u{2c90}'..='\u{2c90}', + '\u{2c92}'..='\u{2c92}', '\u{2c94}'..='\u{2c94}', '\u{2c96}'..='\u{2c96}', + '\u{2c98}'..='\u{2c98}', '\u{2c9a}'..='\u{2c9a}', '\u{2c9c}'..='\u{2c9c}', + '\u{2c9e}'..='\u{2c9e}', '\u{2ca0}'..='\u{2ca0}', '\u{2ca2}'..='\u{2ca2}', + '\u{2ca4}'..='\u{2ca4}', '\u{2ca6}'..='\u{2ca6}', '\u{2ca8}'..='\u{2ca8}', + '\u{2caa}'..='\u{2caa}', '\u{2cac}'..='\u{2cac}', '\u{2cae}'..='\u{2cae}', + '\u{2cb0}'..='\u{2cb0}', '\u{2cb2}'..='\u{2cb2}', '\u{2cb4}'..='\u{2cb4}', + '\u{2cb6}'..='\u{2cb6}', '\u{2cb8}'..='\u{2cb8}', '\u{2cba}'..='\u{2cba}', + '\u{2cbc}'..='\u{2cbc}', '\u{2cbe}'..='\u{2cbe}', '\u{2cc0}'..='\u{2cc0}', + '\u{2cc2}'..='\u{2cc2}', '\u{2cc4}'..='\u{2cc4}', '\u{2cc6}'..='\u{2cc6}', + '\u{2cc8}'..='\u{2cc8}', '\u{2cca}'..='\u{2cca}', '\u{2ccc}'..='\u{2ccc}', + '\u{2cce}'..='\u{2cce}', '\u{2cd0}'..='\u{2cd0}', '\u{2cd2}'..='\u{2cd2}', + '\u{2cd4}'..='\u{2cd4}', '\u{2cd6}'..='\u{2cd6}', '\u{2cd8}'..='\u{2cd8}', + '\u{2cda}'..='\u{2cda}', '\u{2cdc}'..='\u{2cdc}', '\u{2cde}'..='\u{2cde}', + '\u{2ce0}'..='\u{2ce0}', '\u{2ce2}'..='\u{2ce2}', '\u{2ceb}'..='\u{2ceb}', + '\u{2ced}'..='\u{2ced}', '\u{2cf2}'..='\u{2cf2}', '\u{a640}'..='\u{a640}', + '\u{a642}'..='\u{a642}', '\u{a644}'..='\u{a644}', '\u{a646}'..='\u{a646}', + '\u{a648}'..='\u{a648}', '\u{a64a}'..='\u{a64a}', '\u{a64c}'..='\u{a64c}', + '\u{a64e}'..='\u{a64e}', '\u{a650}'..='\u{a650}', '\u{a652}'..='\u{a652}', + '\u{a654}'..='\u{a654}', '\u{a656}'..='\u{a656}', '\u{a658}'..='\u{a658}', + '\u{a65a}'..='\u{a65a}', '\u{a65c}'..='\u{a65c}', '\u{a65e}'..='\u{a65e}', + '\u{a660}'..='\u{a660}', '\u{a662}'..='\u{a662}', '\u{a664}'..='\u{a664}', + '\u{a666}'..='\u{a666}', '\u{a668}'..='\u{a668}', '\u{a66a}'..='\u{a66a}', + '\u{a66c}'..='\u{a66c}', '\u{a680}'..='\u{a680}', '\u{a682}'..='\u{a682}', + '\u{a684}'..='\u{a684}', '\u{a686}'..='\u{a686}', '\u{a688}'..='\u{a688}', + '\u{a68a}'..='\u{a68a}', '\u{a68c}'..='\u{a68c}', '\u{a68e}'..='\u{a68e}', + '\u{a690}'..='\u{a690}', '\u{a692}'..='\u{a692}', '\u{a694}'..='\u{a694}', + '\u{a696}'..='\u{a696}', '\u{a698}'..='\u{a698}', '\u{a69a}'..='\u{a69a}', + '\u{a722}'..='\u{a722}', '\u{a724}'..='\u{a724}', '\u{a726}'..='\u{a726}', + '\u{a728}'..='\u{a728}', '\u{a72a}'..='\u{a72a}', '\u{a72c}'..='\u{a72c}', + '\u{a72e}'..='\u{a72e}', '\u{a732}'..='\u{a732}', '\u{a734}'..='\u{a734}', + '\u{a736}'..='\u{a736}', '\u{a738}'..='\u{a738}', '\u{a73a}'..='\u{a73a}', + '\u{a73c}'..='\u{a73c}', '\u{a73e}'..='\u{a73e}', '\u{a740}'..='\u{a740}', + '\u{a742}'..='\u{a742}', '\u{a744}'..='\u{a744}', '\u{a746}'..='\u{a746}', + '\u{a748}'..='\u{a748}', '\u{a74a}'..='\u{a74a}', '\u{a74c}'..='\u{a74c}', + '\u{a74e}'..='\u{a74e}', '\u{a750}'..='\u{a750}', '\u{a752}'..='\u{a752}', + '\u{a754}'..='\u{a754}', '\u{a756}'..='\u{a756}', '\u{a758}'..='\u{a758}', + '\u{a75a}'..='\u{a75a}', '\u{a75c}'..='\u{a75c}', '\u{a75e}'..='\u{a75e}', + '\u{a760}'..='\u{a760}', '\u{a762}'..='\u{a762}', '\u{a764}'..='\u{a764}', + '\u{a766}'..='\u{a766}', '\u{a768}'..='\u{a768}', '\u{a76a}'..='\u{a76a}', + '\u{a76c}'..='\u{a76c}', '\u{a76e}'..='\u{a76e}', '\u{a779}'..='\u{a779}', + '\u{a77b}'..='\u{a77b}', '\u{a77d}'..='\u{a77e}', '\u{a780}'..='\u{a780}', + '\u{a782}'..='\u{a782}', '\u{a784}'..='\u{a784}', '\u{a786}'..='\u{a786}', + '\u{a78b}'..='\u{a78b}', '\u{a78d}'..='\u{a78d}', '\u{a790}'..='\u{a790}', + '\u{a792}'..='\u{a792}', '\u{a796}'..='\u{a796}', '\u{a798}'..='\u{a798}', + '\u{a79a}'..='\u{a79a}', '\u{a79c}'..='\u{a79c}', '\u{a79e}'..='\u{a79e}', + '\u{a7a0}'..='\u{a7a0}', '\u{a7a2}'..='\u{a7a2}', '\u{a7a4}'..='\u{a7a4}', + '\u{a7a6}'..='\u{a7a6}', '\u{a7a8}'..='\u{a7a8}', '\u{a7aa}'..='\u{a7ae}', + '\u{a7b0}'..='\u{a7b4}', '\u{a7b6}'..='\u{a7b6}', '\u{a7b8}'..='\u{a7b8}', + '\u{a7ba}'..='\u{a7ba}', '\u{a7bc}'..='\u{a7bc}', '\u{a7be}'..='\u{a7be}', + '\u{a7c0}'..='\u{a7c0}', '\u{a7c2}'..='\u{a7c2}', '\u{a7c4}'..='\u{a7c7}', + '\u{a7c9}'..='\u{a7c9}', '\u{a7cb}'..='\u{a7cc}', '\u{a7ce}'..='\u{a7ce}', + '\u{a7d0}'..='\u{a7d0}', '\u{a7d2}'..='\u{a7d2}', '\u{a7d4}'..='\u{a7d4}', + '\u{a7d6}'..='\u{a7d6}', '\u{a7d8}'..='\u{a7d8}', '\u{a7da}'..='\u{a7da}', + '\u{a7dc}'..='\u{a7dc}', '\u{a7f5}'..='\u{a7f5}', '\u{ff21}'..='\u{ff3a}', + '\u{10400}'..='\u{10427}', '\u{104b0}'..='\u{104d3}', '\u{10570}'..='\u{1057a}', + '\u{1057c}'..='\u{1058a}', '\u{1058c}'..='\u{10592}', '\u{10594}'..='\u{10595}', + '\u{10c80}'..='\u{10cb2}', '\u{10d50}'..='\u{10d65}', '\u{118a0}'..='\u{118bf}', + '\u{16e40}'..='\u{16e5f}', '\u{16ea0}'..='\u{16eb8}', '\u{1d400}'..='\u{1d419}', + '\u{1d434}'..='\u{1d44d}', '\u{1d468}'..='\u{1d481}', '\u{1d49c}'..='\u{1d49c}', + '\u{1d49e}'..='\u{1d49f}', '\u{1d4a2}'..='\u{1d4a2}', '\u{1d4a5}'..='\u{1d4a6}', + '\u{1d4a9}'..='\u{1d4ac}', '\u{1d4ae}'..='\u{1d4b5}', '\u{1d4d0}'..='\u{1d4e9}', + '\u{1d504}'..='\u{1d505}', '\u{1d507}'..='\u{1d50a}', '\u{1d50d}'..='\u{1d514}', + '\u{1d516}'..='\u{1d51c}', '\u{1d538}'..='\u{1d539}', '\u{1d53b}'..='\u{1d53e}', + '\u{1d540}'..='\u{1d544}', '\u{1d546}'..='\u{1d546}', '\u{1d54a}'..='\u{1d550}', + '\u{1d56c}'..='\u{1d585}', '\u{1d5a0}'..='\u{1d5b9}', '\u{1d5d4}'..='\u{1d5ed}', + '\u{1d608}'..='\u{1d621}', '\u{1d63c}'..='\u{1d655}', '\u{1d670}'..='\u{1d689}', + '\u{1d6a8}'..='\u{1d6c0}', '\u{1d6e2}'..='\u{1d6fa}', '\u{1d71c}'..='\u{1d734}', + '\u{1d756}'..='\u{1d76e}', '\u{1d790}'..='\u{1d7a8}', '\u{1d7ca}'..='\u{1d7ca}', + '\u{1e900}'..='\u{1e921}', '\u{1f130}'..='\u{1f149}', '\u{1f150}'..='\u{1f169}', + '\u{1f170}'..='\u{1f189}', +]; + +#[rustfmt::skip] +pub(super) static WHITE_SPACE: &[RangeInclusive; 8] = &[ + '\u{85}'..='\u{85}', '\u{a0}'..='\u{a0}', '\u{1680}'..='\u{1680}', '\u{2000}'..='\u{200a}', + '\u{2028}'..='\u{2029}', '\u{202f}'..='\u{202f}', '\u{205f}'..='\u{205f}', + '\u{3000}'..='\u{3000}', +]; + +#[rustfmt::skip] +pub(super) static TO_LOWER: &[(char, [char; 3]); 1488] = &[ + ('\u{41}', ['\u{61}', '\u{0}', '\u{0}']), ('\u{42}', ['\u{62}', '\u{0}', '\u{0}']), + ('\u{43}', ['\u{63}', '\u{0}', '\u{0}']), ('\u{44}', ['\u{64}', '\u{0}', '\u{0}']), + ('\u{45}', ['\u{65}', '\u{0}', '\u{0}']), ('\u{46}', ['\u{66}', '\u{0}', '\u{0}']), + ('\u{47}', ['\u{67}', '\u{0}', '\u{0}']), ('\u{48}', ['\u{68}', '\u{0}', '\u{0}']), + ('\u{49}', ['\u{69}', '\u{0}', '\u{0}']), ('\u{4a}', ['\u{6a}', '\u{0}', '\u{0}']), + ('\u{4b}', ['\u{6b}', '\u{0}', '\u{0}']), ('\u{4c}', ['\u{6c}', '\u{0}', '\u{0}']), + ('\u{4d}', ['\u{6d}', '\u{0}', '\u{0}']), ('\u{4e}', ['\u{6e}', '\u{0}', '\u{0}']), + ('\u{4f}', ['\u{6f}', '\u{0}', '\u{0}']), ('\u{50}', ['\u{70}', '\u{0}', '\u{0}']), + ('\u{51}', ['\u{71}', '\u{0}', '\u{0}']), ('\u{52}', ['\u{72}', '\u{0}', '\u{0}']), + ('\u{53}', ['\u{73}', '\u{0}', '\u{0}']), ('\u{54}', ['\u{74}', '\u{0}', '\u{0}']), + ('\u{55}', ['\u{75}', '\u{0}', '\u{0}']), ('\u{56}', ['\u{76}', '\u{0}', '\u{0}']), + ('\u{57}', ['\u{77}', '\u{0}', '\u{0}']), ('\u{58}', ['\u{78}', '\u{0}', '\u{0}']), + ('\u{59}', ['\u{79}', '\u{0}', '\u{0}']), ('\u{5a}', ['\u{7a}', '\u{0}', '\u{0}']), + ('\u{c0}', ['\u{e0}', '\u{0}', '\u{0}']), ('\u{c1}', ['\u{e1}', '\u{0}', '\u{0}']), + ('\u{c2}', ['\u{e2}', '\u{0}', '\u{0}']), ('\u{c3}', ['\u{e3}', '\u{0}', '\u{0}']), + ('\u{c4}', ['\u{e4}', '\u{0}', '\u{0}']), ('\u{c5}', ['\u{e5}', '\u{0}', '\u{0}']), + ('\u{c6}', ['\u{e6}', '\u{0}', '\u{0}']), ('\u{c7}', ['\u{e7}', '\u{0}', '\u{0}']), + ('\u{c8}', ['\u{e8}', '\u{0}', '\u{0}']), ('\u{c9}', ['\u{e9}', '\u{0}', '\u{0}']), + ('\u{ca}', ['\u{ea}', '\u{0}', '\u{0}']), ('\u{cb}', ['\u{eb}', '\u{0}', '\u{0}']), + ('\u{cc}', ['\u{ec}', '\u{0}', '\u{0}']), ('\u{cd}', ['\u{ed}', '\u{0}', '\u{0}']), + ('\u{ce}', ['\u{ee}', '\u{0}', '\u{0}']), ('\u{cf}', ['\u{ef}', '\u{0}', '\u{0}']), + ('\u{d0}', ['\u{f0}', '\u{0}', '\u{0}']), ('\u{d1}', ['\u{f1}', '\u{0}', '\u{0}']), + ('\u{d2}', ['\u{f2}', '\u{0}', '\u{0}']), ('\u{d3}', ['\u{f3}', '\u{0}', '\u{0}']), + ('\u{d4}', ['\u{f4}', '\u{0}', '\u{0}']), ('\u{d5}', ['\u{f5}', '\u{0}', '\u{0}']), + ('\u{d6}', ['\u{f6}', '\u{0}', '\u{0}']), ('\u{d8}', ['\u{f8}', '\u{0}', '\u{0}']), + ('\u{d9}', ['\u{f9}', '\u{0}', '\u{0}']), ('\u{da}', ['\u{fa}', '\u{0}', '\u{0}']), + ('\u{db}', ['\u{fb}', '\u{0}', '\u{0}']), ('\u{dc}', ['\u{fc}', '\u{0}', '\u{0}']), + ('\u{dd}', ['\u{fd}', '\u{0}', '\u{0}']), ('\u{de}', ['\u{fe}', '\u{0}', '\u{0}']), + ('\u{100}', ['\u{101}', '\u{0}', '\u{0}']), ('\u{102}', ['\u{103}', '\u{0}', '\u{0}']), + ('\u{104}', ['\u{105}', '\u{0}', '\u{0}']), ('\u{106}', ['\u{107}', '\u{0}', '\u{0}']), + ('\u{108}', ['\u{109}', '\u{0}', '\u{0}']), ('\u{10a}', ['\u{10b}', '\u{0}', '\u{0}']), + ('\u{10c}', ['\u{10d}', '\u{0}', '\u{0}']), ('\u{10e}', ['\u{10f}', '\u{0}', '\u{0}']), + ('\u{110}', ['\u{111}', '\u{0}', '\u{0}']), ('\u{112}', ['\u{113}', '\u{0}', '\u{0}']), + ('\u{114}', ['\u{115}', '\u{0}', '\u{0}']), ('\u{116}', ['\u{117}', '\u{0}', '\u{0}']), + ('\u{118}', ['\u{119}', '\u{0}', '\u{0}']), ('\u{11a}', ['\u{11b}', '\u{0}', '\u{0}']), + ('\u{11c}', ['\u{11d}', '\u{0}', '\u{0}']), ('\u{11e}', ['\u{11f}', '\u{0}', '\u{0}']), + ('\u{120}', ['\u{121}', '\u{0}', '\u{0}']), ('\u{122}', ['\u{123}', '\u{0}', '\u{0}']), + ('\u{124}', ['\u{125}', '\u{0}', '\u{0}']), ('\u{126}', ['\u{127}', '\u{0}', '\u{0}']), + ('\u{128}', ['\u{129}', '\u{0}', '\u{0}']), ('\u{12a}', ['\u{12b}', '\u{0}', '\u{0}']), + ('\u{12c}', ['\u{12d}', '\u{0}', '\u{0}']), ('\u{12e}', ['\u{12f}', '\u{0}', '\u{0}']), + ('\u{130}', ['\u{69}', '\u{307}', '\u{0}']), ('\u{132}', ['\u{133}', '\u{0}', '\u{0}']), + ('\u{134}', ['\u{135}', '\u{0}', '\u{0}']), ('\u{136}', ['\u{137}', '\u{0}', '\u{0}']), + ('\u{139}', ['\u{13a}', '\u{0}', '\u{0}']), ('\u{13b}', ['\u{13c}', '\u{0}', '\u{0}']), + ('\u{13d}', ['\u{13e}', '\u{0}', '\u{0}']), ('\u{13f}', ['\u{140}', '\u{0}', '\u{0}']), + ('\u{141}', ['\u{142}', '\u{0}', '\u{0}']), ('\u{143}', ['\u{144}', '\u{0}', '\u{0}']), + ('\u{145}', ['\u{146}', '\u{0}', '\u{0}']), ('\u{147}', ['\u{148}', '\u{0}', '\u{0}']), + ('\u{14a}', ['\u{14b}', '\u{0}', '\u{0}']), ('\u{14c}', ['\u{14d}', '\u{0}', '\u{0}']), + ('\u{14e}', ['\u{14f}', '\u{0}', '\u{0}']), ('\u{150}', ['\u{151}', '\u{0}', '\u{0}']), + ('\u{152}', ['\u{153}', '\u{0}', '\u{0}']), ('\u{154}', ['\u{155}', '\u{0}', '\u{0}']), + ('\u{156}', ['\u{157}', '\u{0}', '\u{0}']), ('\u{158}', ['\u{159}', '\u{0}', '\u{0}']), + ('\u{15a}', ['\u{15b}', '\u{0}', '\u{0}']), ('\u{15c}', ['\u{15d}', '\u{0}', '\u{0}']), + ('\u{15e}', ['\u{15f}', '\u{0}', '\u{0}']), ('\u{160}', ['\u{161}', '\u{0}', '\u{0}']), + ('\u{162}', ['\u{163}', '\u{0}', '\u{0}']), ('\u{164}', ['\u{165}', '\u{0}', '\u{0}']), + ('\u{166}', ['\u{167}', '\u{0}', '\u{0}']), ('\u{168}', ['\u{169}', '\u{0}', '\u{0}']), + ('\u{16a}', ['\u{16b}', '\u{0}', '\u{0}']), ('\u{16c}', ['\u{16d}', '\u{0}', '\u{0}']), + ('\u{16e}', ['\u{16f}', '\u{0}', '\u{0}']), ('\u{170}', ['\u{171}', '\u{0}', '\u{0}']), + ('\u{172}', ['\u{173}', '\u{0}', '\u{0}']), ('\u{174}', ['\u{175}', '\u{0}', '\u{0}']), + ('\u{176}', ['\u{177}', '\u{0}', '\u{0}']), ('\u{178}', ['\u{ff}', '\u{0}', '\u{0}']), + ('\u{179}', ['\u{17a}', '\u{0}', '\u{0}']), ('\u{17b}', ['\u{17c}', '\u{0}', '\u{0}']), + ('\u{17d}', ['\u{17e}', '\u{0}', '\u{0}']), ('\u{181}', ['\u{253}', '\u{0}', '\u{0}']), + ('\u{182}', ['\u{183}', '\u{0}', '\u{0}']), ('\u{184}', ['\u{185}', '\u{0}', '\u{0}']), + ('\u{186}', ['\u{254}', '\u{0}', '\u{0}']), ('\u{187}', ['\u{188}', '\u{0}', '\u{0}']), + ('\u{189}', ['\u{256}', '\u{0}', '\u{0}']), ('\u{18a}', ['\u{257}', '\u{0}', '\u{0}']), + ('\u{18b}', ['\u{18c}', '\u{0}', '\u{0}']), ('\u{18e}', ['\u{1dd}', '\u{0}', '\u{0}']), + ('\u{18f}', ['\u{259}', '\u{0}', '\u{0}']), ('\u{190}', ['\u{25b}', '\u{0}', '\u{0}']), + ('\u{191}', ['\u{192}', '\u{0}', '\u{0}']), ('\u{193}', ['\u{260}', '\u{0}', '\u{0}']), + ('\u{194}', ['\u{263}', '\u{0}', '\u{0}']), ('\u{196}', ['\u{269}', '\u{0}', '\u{0}']), + ('\u{197}', ['\u{268}', '\u{0}', '\u{0}']), ('\u{198}', ['\u{199}', '\u{0}', '\u{0}']), + ('\u{19c}', ['\u{26f}', '\u{0}', '\u{0}']), ('\u{19d}', ['\u{272}', '\u{0}', '\u{0}']), + ('\u{19f}', ['\u{275}', '\u{0}', '\u{0}']), ('\u{1a0}', ['\u{1a1}', '\u{0}', '\u{0}']), + ('\u{1a2}', ['\u{1a3}', '\u{0}', '\u{0}']), ('\u{1a4}', ['\u{1a5}', '\u{0}', '\u{0}']), + ('\u{1a6}', ['\u{280}', '\u{0}', '\u{0}']), ('\u{1a7}', ['\u{1a8}', '\u{0}', '\u{0}']), + ('\u{1a9}', ['\u{283}', '\u{0}', '\u{0}']), ('\u{1ac}', ['\u{1ad}', '\u{0}', '\u{0}']), + ('\u{1ae}', ['\u{288}', '\u{0}', '\u{0}']), ('\u{1af}', ['\u{1b0}', '\u{0}', '\u{0}']), + ('\u{1b1}', ['\u{28a}', '\u{0}', '\u{0}']), ('\u{1b2}', ['\u{28b}', '\u{0}', '\u{0}']), + ('\u{1b3}', ['\u{1b4}', '\u{0}', '\u{0}']), ('\u{1b5}', ['\u{1b6}', '\u{0}', '\u{0}']), + ('\u{1b7}', ['\u{292}', '\u{0}', '\u{0}']), ('\u{1b8}', ['\u{1b9}', '\u{0}', '\u{0}']), + ('\u{1bc}', ['\u{1bd}', '\u{0}', '\u{0}']), ('\u{1c4}', ['\u{1c6}', '\u{0}', '\u{0}']), + ('\u{1c5}', ['\u{1c6}', '\u{0}', '\u{0}']), ('\u{1c7}', ['\u{1c9}', '\u{0}', '\u{0}']), + ('\u{1c8}', ['\u{1c9}', '\u{0}', '\u{0}']), ('\u{1ca}', ['\u{1cc}', '\u{0}', '\u{0}']), + ('\u{1cb}', ['\u{1cc}', '\u{0}', '\u{0}']), ('\u{1cd}', ['\u{1ce}', '\u{0}', '\u{0}']), + ('\u{1cf}', ['\u{1d0}', '\u{0}', '\u{0}']), ('\u{1d1}', ['\u{1d2}', '\u{0}', '\u{0}']), + ('\u{1d3}', ['\u{1d4}', '\u{0}', '\u{0}']), ('\u{1d5}', ['\u{1d6}', '\u{0}', '\u{0}']), + ('\u{1d7}', ['\u{1d8}', '\u{0}', '\u{0}']), ('\u{1d9}', ['\u{1da}', '\u{0}', '\u{0}']), + ('\u{1db}', ['\u{1dc}', '\u{0}', '\u{0}']), ('\u{1de}', ['\u{1df}', '\u{0}', '\u{0}']), + ('\u{1e0}', ['\u{1e1}', '\u{0}', '\u{0}']), ('\u{1e2}', ['\u{1e3}', '\u{0}', '\u{0}']), + ('\u{1e4}', ['\u{1e5}', '\u{0}', '\u{0}']), ('\u{1e6}', ['\u{1e7}', '\u{0}', '\u{0}']), + ('\u{1e8}', ['\u{1e9}', '\u{0}', '\u{0}']), ('\u{1ea}', ['\u{1eb}', '\u{0}', '\u{0}']), + ('\u{1ec}', ['\u{1ed}', '\u{0}', '\u{0}']), ('\u{1ee}', ['\u{1ef}', '\u{0}', '\u{0}']), + ('\u{1f1}', ['\u{1f3}', '\u{0}', '\u{0}']), ('\u{1f2}', ['\u{1f3}', '\u{0}', '\u{0}']), + ('\u{1f4}', ['\u{1f5}', '\u{0}', '\u{0}']), ('\u{1f6}', ['\u{195}', '\u{0}', '\u{0}']), + ('\u{1f7}', ['\u{1bf}', '\u{0}', '\u{0}']), ('\u{1f8}', ['\u{1f9}', '\u{0}', '\u{0}']), + ('\u{1fa}', ['\u{1fb}', '\u{0}', '\u{0}']), ('\u{1fc}', ['\u{1fd}', '\u{0}', '\u{0}']), + ('\u{1fe}', ['\u{1ff}', '\u{0}', '\u{0}']), ('\u{200}', ['\u{201}', '\u{0}', '\u{0}']), + ('\u{202}', ['\u{203}', '\u{0}', '\u{0}']), ('\u{204}', ['\u{205}', '\u{0}', '\u{0}']), + ('\u{206}', ['\u{207}', '\u{0}', '\u{0}']), ('\u{208}', ['\u{209}', '\u{0}', '\u{0}']), + ('\u{20a}', ['\u{20b}', '\u{0}', '\u{0}']), ('\u{20c}', ['\u{20d}', '\u{0}', '\u{0}']), + ('\u{20e}', ['\u{20f}', '\u{0}', '\u{0}']), ('\u{210}', ['\u{211}', '\u{0}', '\u{0}']), + ('\u{212}', ['\u{213}', '\u{0}', '\u{0}']), ('\u{214}', ['\u{215}', '\u{0}', '\u{0}']), + ('\u{216}', ['\u{217}', '\u{0}', '\u{0}']), ('\u{218}', ['\u{219}', '\u{0}', '\u{0}']), + ('\u{21a}', ['\u{21b}', '\u{0}', '\u{0}']), ('\u{21c}', ['\u{21d}', '\u{0}', '\u{0}']), + ('\u{21e}', ['\u{21f}', '\u{0}', '\u{0}']), ('\u{220}', ['\u{19e}', '\u{0}', '\u{0}']), + ('\u{222}', ['\u{223}', '\u{0}', '\u{0}']), ('\u{224}', ['\u{225}', '\u{0}', '\u{0}']), + ('\u{226}', ['\u{227}', '\u{0}', '\u{0}']), ('\u{228}', ['\u{229}', '\u{0}', '\u{0}']), + ('\u{22a}', ['\u{22b}', '\u{0}', '\u{0}']), ('\u{22c}', ['\u{22d}', '\u{0}', '\u{0}']), + ('\u{22e}', ['\u{22f}', '\u{0}', '\u{0}']), ('\u{230}', ['\u{231}', '\u{0}', '\u{0}']), + ('\u{232}', ['\u{233}', '\u{0}', '\u{0}']), ('\u{23a}', ['\u{2c65}', '\u{0}', '\u{0}']), + ('\u{23b}', ['\u{23c}', '\u{0}', '\u{0}']), ('\u{23d}', ['\u{19a}', '\u{0}', '\u{0}']), + ('\u{23e}', ['\u{2c66}', '\u{0}', '\u{0}']), ('\u{241}', ['\u{242}', '\u{0}', '\u{0}']), + ('\u{243}', ['\u{180}', '\u{0}', '\u{0}']), ('\u{244}', ['\u{289}', '\u{0}', '\u{0}']), + ('\u{245}', ['\u{28c}', '\u{0}', '\u{0}']), ('\u{246}', ['\u{247}', '\u{0}', '\u{0}']), + ('\u{248}', ['\u{249}', '\u{0}', '\u{0}']), ('\u{24a}', ['\u{24b}', '\u{0}', '\u{0}']), + ('\u{24c}', ['\u{24d}', '\u{0}', '\u{0}']), ('\u{24e}', ['\u{24f}', '\u{0}', '\u{0}']), + ('\u{370}', ['\u{371}', '\u{0}', '\u{0}']), ('\u{372}', ['\u{373}', '\u{0}', '\u{0}']), + ('\u{376}', ['\u{377}', '\u{0}', '\u{0}']), ('\u{37f}', ['\u{3f3}', '\u{0}', '\u{0}']), + ('\u{386}', ['\u{3ac}', '\u{0}', '\u{0}']), ('\u{388}', ['\u{3ad}', '\u{0}', '\u{0}']), + ('\u{389}', ['\u{3ae}', '\u{0}', '\u{0}']), ('\u{38a}', ['\u{3af}', '\u{0}', '\u{0}']), + ('\u{38c}', ['\u{3cc}', '\u{0}', '\u{0}']), ('\u{38e}', ['\u{3cd}', '\u{0}', '\u{0}']), + ('\u{38f}', ['\u{3ce}', '\u{0}', '\u{0}']), ('\u{391}', ['\u{3b1}', '\u{0}', '\u{0}']), + ('\u{392}', ['\u{3b2}', '\u{0}', '\u{0}']), ('\u{393}', ['\u{3b3}', '\u{0}', '\u{0}']), + ('\u{394}', ['\u{3b4}', '\u{0}', '\u{0}']), ('\u{395}', ['\u{3b5}', '\u{0}', '\u{0}']), + ('\u{396}', ['\u{3b6}', '\u{0}', '\u{0}']), ('\u{397}', ['\u{3b7}', '\u{0}', '\u{0}']), + ('\u{398}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{399}', ['\u{3b9}', '\u{0}', '\u{0}']), + ('\u{39a}', ['\u{3ba}', '\u{0}', '\u{0}']), ('\u{39b}', ['\u{3bb}', '\u{0}', '\u{0}']), + ('\u{39c}', ['\u{3bc}', '\u{0}', '\u{0}']), ('\u{39d}', ['\u{3bd}', '\u{0}', '\u{0}']), + ('\u{39e}', ['\u{3be}', '\u{0}', '\u{0}']), ('\u{39f}', ['\u{3bf}', '\u{0}', '\u{0}']), + ('\u{3a0}', ['\u{3c0}', '\u{0}', '\u{0}']), ('\u{3a1}', ['\u{3c1}', '\u{0}', '\u{0}']), + ('\u{3a3}', ['\u{3c3}', '\u{0}', '\u{0}']), ('\u{3a4}', ['\u{3c4}', '\u{0}', '\u{0}']), + ('\u{3a5}', ['\u{3c5}', '\u{0}', '\u{0}']), ('\u{3a6}', ['\u{3c6}', '\u{0}', '\u{0}']), + ('\u{3a7}', ['\u{3c7}', '\u{0}', '\u{0}']), ('\u{3a8}', ['\u{3c8}', '\u{0}', '\u{0}']), + ('\u{3a9}', ['\u{3c9}', '\u{0}', '\u{0}']), ('\u{3aa}', ['\u{3ca}', '\u{0}', '\u{0}']), + ('\u{3ab}', ['\u{3cb}', '\u{0}', '\u{0}']), ('\u{3cf}', ['\u{3d7}', '\u{0}', '\u{0}']), + ('\u{3d8}', ['\u{3d9}', '\u{0}', '\u{0}']), ('\u{3da}', ['\u{3db}', '\u{0}', '\u{0}']), + ('\u{3dc}', ['\u{3dd}', '\u{0}', '\u{0}']), ('\u{3de}', ['\u{3df}', '\u{0}', '\u{0}']), + ('\u{3e0}', ['\u{3e1}', '\u{0}', '\u{0}']), ('\u{3e2}', ['\u{3e3}', '\u{0}', '\u{0}']), + ('\u{3e4}', ['\u{3e5}', '\u{0}', '\u{0}']), ('\u{3e6}', ['\u{3e7}', '\u{0}', '\u{0}']), + ('\u{3e8}', ['\u{3e9}', '\u{0}', '\u{0}']), ('\u{3ea}', ['\u{3eb}', '\u{0}', '\u{0}']), + ('\u{3ec}', ['\u{3ed}', '\u{0}', '\u{0}']), ('\u{3ee}', ['\u{3ef}', '\u{0}', '\u{0}']), + ('\u{3f4}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{3f7}', ['\u{3f8}', '\u{0}', '\u{0}']), + ('\u{3f9}', ['\u{3f2}', '\u{0}', '\u{0}']), ('\u{3fa}', ['\u{3fb}', '\u{0}', '\u{0}']), + ('\u{3fd}', ['\u{37b}', '\u{0}', '\u{0}']), ('\u{3fe}', ['\u{37c}', '\u{0}', '\u{0}']), + ('\u{3ff}', ['\u{37d}', '\u{0}', '\u{0}']), ('\u{400}', ['\u{450}', '\u{0}', '\u{0}']), + ('\u{401}', ['\u{451}', '\u{0}', '\u{0}']), ('\u{402}', ['\u{452}', '\u{0}', '\u{0}']), + ('\u{403}', ['\u{453}', '\u{0}', '\u{0}']), ('\u{404}', ['\u{454}', '\u{0}', '\u{0}']), + ('\u{405}', ['\u{455}', '\u{0}', '\u{0}']), ('\u{406}', ['\u{456}', '\u{0}', '\u{0}']), + ('\u{407}', ['\u{457}', '\u{0}', '\u{0}']), ('\u{408}', ['\u{458}', '\u{0}', '\u{0}']), + ('\u{409}', ['\u{459}', '\u{0}', '\u{0}']), ('\u{40a}', ['\u{45a}', '\u{0}', '\u{0}']), + ('\u{40b}', ['\u{45b}', '\u{0}', '\u{0}']), ('\u{40c}', ['\u{45c}', '\u{0}', '\u{0}']), + ('\u{40d}', ['\u{45d}', '\u{0}', '\u{0}']), ('\u{40e}', ['\u{45e}', '\u{0}', '\u{0}']), + ('\u{40f}', ['\u{45f}', '\u{0}', '\u{0}']), ('\u{410}', ['\u{430}', '\u{0}', '\u{0}']), + ('\u{411}', ['\u{431}', '\u{0}', '\u{0}']), ('\u{412}', ['\u{432}', '\u{0}', '\u{0}']), + ('\u{413}', ['\u{433}', '\u{0}', '\u{0}']), ('\u{414}', ['\u{434}', '\u{0}', '\u{0}']), + ('\u{415}', ['\u{435}', '\u{0}', '\u{0}']), ('\u{416}', ['\u{436}', '\u{0}', '\u{0}']), + ('\u{417}', ['\u{437}', '\u{0}', '\u{0}']), ('\u{418}', ['\u{438}', '\u{0}', '\u{0}']), + ('\u{419}', ['\u{439}', '\u{0}', '\u{0}']), ('\u{41a}', ['\u{43a}', '\u{0}', '\u{0}']), + ('\u{41b}', ['\u{43b}', '\u{0}', '\u{0}']), ('\u{41c}', ['\u{43c}', '\u{0}', '\u{0}']), + ('\u{41d}', ['\u{43d}', '\u{0}', '\u{0}']), ('\u{41e}', ['\u{43e}', '\u{0}', '\u{0}']), + ('\u{41f}', ['\u{43f}', '\u{0}', '\u{0}']), ('\u{420}', ['\u{440}', '\u{0}', '\u{0}']), + ('\u{421}', ['\u{441}', '\u{0}', '\u{0}']), ('\u{422}', ['\u{442}', '\u{0}', '\u{0}']), + ('\u{423}', ['\u{443}', '\u{0}', '\u{0}']), ('\u{424}', ['\u{444}', '\u{0}', '\u{0}']), + ('\u{425}', ['\u{445}', '\u{0}', '\u{0}']), ('\u{426}', ['\u{446}', '\u{0}', '\u{0}']), + ('\u{427}', ['\u{447}', '\u{0}', '\u{0}']), ('\u{428}', ['\u{448}', '\u{0}', '\u{0}']), + ('\u{429}', ['\u{449}', '\u{0}', '\u{0}']), ('\u{42a}', ['\u{44a}', '\u{0}', '\u{0}']), + ('\u{42b}', ['\u{44b}', '\u{0}', '\u{0}']), ('\u{42c}', ['\u{44c}', '\u{0}', '\u{0}']), + ('\u{42d}', ['\u{44d}', '\u{0}', '\u{0}']), ('\u{42e}', ['\u{44e}', '\u{0}', '\u{0}']), + ('\u{42f}', ['\u{44f}', '\u{0}', '\u{0}']), ('\u{460}', ['\u{461}', '\u{0}', '\u{0}']), + ('\u{462}', ['\u{463}', '\u{0}', '\u{0}']), ('\u{464}', ['\u{465}', '\u{0}', '\u{0}']), + ('\u{466}', ['\u{467}', '\u{0}', '\u{0}']), ('\u{468}', ['\u{469}', '\u{0}', '\u{0}']), + ('\u{46a}', ['\u{46b}', '\u{0}', '\u{0}']), ('\u{46c}', ['\u{46d}', '\u{0}', '\u{0}']), + ('\u{46e}', ['\u{46f}', '\u{0}', '\u{0}']), ('\u{470}', ['\u{471}', '\u{0}', '\u{0}']), + ('\u{472}', ['\u{473}', '\u{0}', '\u{0}']), ('\u{474}', ['\u{475}', '\u{0}', '\u{0}']), + ('\u{476}', ['\u{477}', '\u{0}', '\u{0}']), ('\u{478}', ['\u{479}', '\u{0}', '\u{0}']), + ('\u{47a}', ['\u{47b}', '\u{0}', '\u{0}']), ('\u{47c}', ['\u{47d}', '\u{0}', '\u{0}']), + ('\u{47e}', ['\u{47f}', '\u{0}', '\u{0}']), ('\u{480}', ['\u{481}', '\u{0}', '\u{0}']), + ('\u{48a}', ['\u{48b}', '\u{0}', '\u{0}']), ('\u{48c}', ['\u{48d}', '\u{0}', '\u{0}']), + ('\u{48e}', ['\u{48f}', '\u{0}', '\u{0}']), ('\u{490}', ['\u{491}', '\u{0}', '\u{0}']), + ('\u{492}', ['\u{493}', '\u{0}', '\u{0}']), ('\u{494}', ['\u{495}', '\u{0}', '\u{0}']), + ('\u{496}', ['\u{497}', '\u{0}', '\u{0}']), ('\u{498}', ['\u{499}', '\u{0}', '\u{0}']), + ('\u{49a}', ['\u{49b}', '\u{0}', '\u{0}']), ('\u{49c}', ['\u{49d}', '\u{0}', '\u{0}']), + ('\u{49e}', ['\u{49f}', '\u{0}', '\u{0}']), ('\u{4a0}', ['\u{4a1}', '\u{0}', '\u{0}']), + ('\u{4a2}', ['\u{4a3}', '\u{0}', '\u{0}']), ('\u{4a4}', ['\u{4a5}', '\u{0}', '\u{0}']), + ('\u{4a6}', ['\u{4a7}', '\u{0}', '\u{0}']), ('\u{4a8}', ['\u{4a9}', '\u{0}', '\u{0}']), + ('\u{4aa}', ['\u{4ab}', '\u{0}', '\u{0}']), ('\u{4ac}', ['\u{4ad}', '\u{0}', '\u{0}']), + ('\u{4ae}', ['\u{4af}', '\u{0}', '\u{0}']), ('\u{4b0}', ['\u{4b1}', '\u{0}', '\u{0}']), + ('\u{4b2}', ['\u{4b3}', '\u{0}', '\u{0}']), ('\u{4b4}', ['\u{4b5}', '\u{0}', '\u{0}']), + ('\u{4b6}', ['\u{4b7}', '\u{0}', '\u{0}']), ('\u{4b8}', ['\u{4b9}', '\u{0}', '\u{0}']), + ('\u{4ba}', ['\u{4bb}', '\u{0}', '\u{0}']), ('\u{4bc}', ['\u{4bd}', '\u{0}', '\u{0}']), + ('\u{4be}', ['\u{4bf}', '\u{0}', '\u{0}']), ('\u{4c0}', ['\u{4cf}', '\u{0}', '\u{0}']), + ('\u{4c1}', ['\u{4c2}', '\u{0}', '\u{0}']), ('\u{4c3}', ['\u{4c4}', '\u{0}', '\u{0}']), + ('\u{4c5}', ['\u{4c6}', '\u{0}', '\u{0}']), ('\u{4c7}', ['\u{4c8}', '\u{0}', '\u{0}']), + ('\u{4c9}', ['\u{4ca}', '\u{0}', '\u{0}']), ('\u{4cb}', ['\u{4cc}', '\u{0}', '\u{0}']), + ('\u{4cd}', ['\u{4ce}', '\u{0}', '\u{0}']), ('\u{4d0}', ['\u{4d1}', '\u{0}', '\u{0}']), + ('\u{4d2}', ['\u{4d3}', '\u{0}', '\u{0}']), ('\u{4d4}', ['\u{4d5}', '\u{0}', '\u{0}']), + ('\u{4d6}', ['\u{4d7}', '\u{0}', '\u{0}']), ('\u{4d8}', ['\u{4d9}', '\u{0}', '\u{0}']), + ('\u{4da}', ['\u{4db}', '\u{0}', '\u{0}']), ('\u{4dc}', ['\u{4dd}', '\u{0}', '\u{0}']), + ('\u{4de}', ['\u{4df}', '\u{0}', '\u{0}']), ('\u{4e0}', ['\u{4e1}', '\u{0}', '\u{0}']), + ('\u{4e2}', ['\u{4e3}', '\u{0}', '\u{0}']), ('\u{4e4}', ['\u{4e5}', '\u{0}', '\u{0}']), + ('\u{4e6}', ['\u{4e7}', '\u{0}', '\u{0}']), ('\u{4e8}', ['\u{4e9}', '\u{0}', '\u{0}']), + ('\u{4ea}', ['\u{4eb}', '\u{0}', '\u{0}']), ('\u{4ec}', ['\u{4ed}', '\u{0}', '\u{0}']), + ('\u{4ee}', ['\u{4ef}', '\u{0}', '\u{0}']), ('\u{4f0}', ['\u{4f1}', '\u{0}', '\u{0}']), + ('\u{4f2}', ['\u{4f3}', '\u{0}', '\u{0}']), ('\u{4f4}', ['\u{4f5}', '\u{0}', '\u{0}']), + ('\u{4f6}', ['\u{4f7}', '\u{0}', '\u{0}']), ('\u{4f8}', ['\u{4f9}', '\u{0}', '\u{0}']), + ('\u{4fa}', ['\u{4fb}', '\u{0}', '\u{0}']), ('\u{4fc}', ['\u{4fd}', '\u{0}', '\u{0}']), + ('\u{4fe}', ['\u{4ff}', '\u{0}', '\u{0}']), ('\u{500}', ['\u{501}', '\u{0}', '\u{0}']), + ('\u{502}', ['\u{503}', '\u{0}', '\u{0}']), ('\u{504}', ['\u{505}', '\u{0}', '\u{0}']), + ('\u{506}', ['\u{507}', '\u{0}', '\u{0}']), ('\u{508}', ['\u{509}', '\u{0}', '\u{0}']), + ('\u{50a}', ['\u{50b}', '\u{0}', '\u{0}']), ('\u{50c}', ['\u{50d}', '\u{0}', '\u{0}']), + ('\u{50e}', ['\u{50f}', '\u{0}', '\u{0}']), ('\u{510}', ['\u{511}', '\u{0}', '\u{0}']), + ('\u{512}', ['\u{513}', '\u{0}', '\u{0}']), ('\u{514}', ['\u{515}', '\u{0}', '\u{0}']), + ('\u{516}', ['\u{517}', '\u{0}', '\u{0}']), ('\u{518}', ['\u{519}', '\u{0}', '\u{0}']), + ('\u{51a}', ['\u{51b}', '\u{0}', '\u{0}']), ('\u{51c}', ['\u{51d}', '\u{0}', '\u{0}']), + ('\u{51e}', ['\u{51f}', '\u{0}', '\u{0}']), ('\u{520}', ['\u{521}', '\u{0}', '\u{0}']), + ('\u{522}', ['\u{523}', '\u{0}', '\u{0}']), ('\u{524}', ['\u{525}', '\u{0}', '\u{0}']), + ('\u{526}', ['\u{527}', '\u{0}', '\u{0}']), ('\u{528}', ['\u{529}', '\u{0}', '\u{0}']), + ('\u{52a}', ['\u{52b}', '\u{0}', '\u{0}']), ('\u{52c}', ['\u{52d}', '\u{0}', '\u{0}']), + ('\u{52e}', ['\u{52f}', '\u{0}', '\u{0}']), ('\u{531}', ['\u{561}', '\u{0}', '\u{0}']), + ('\u{532}', ['\u{562}', '\u{0}', '\u{0}']), ('\u{533}', ['\u{563}', '\u{0}', '\u{0}']), + ('\u{534}', ['\u{564}', '\u{0}', '\u{0}']), ('\u{535}', ['\u{565}', '\u{0}', '\u{0}']), + ('\u{536}', ['\u{566}', '\u{0}', '\u{0}']), ('\u{537}', ['\u{567}', '\u{0}', '\u{0}']), + ('\u{538}', ['\u{568}', '\u{0}', '\u{0}']), ('\u{539}', ['\u{569}', '\u{0}', '\u{0}']), + ('\u{53a}', ['\u{56a}', '\u{0}', '\u{0}']), ('\u{53b}', ['\u{56b}', '\u{0}', '\u{0}']), + ('\u{53c}', ['\u{56c}', '\u{0}', '\u{0}']), ('\u{53d}', ['\u{56d}', '\u{0}', '\u{0}']), + ('\u{53e}', ['\u{56e}', '\u{0}', '\u{0}']), ('\u{53f}', ['\u{56f}', '\u{0}', '\u{0}']), + ('\u{540}', ['\u{570}', '\u{0}', '\u{0}']), ('\u{541}', ['\u{571}', '\u{0}', '\u{0}']), + ('\u{542}', ['\u{572}', '\u{0}', '\u{0}']), ('\u{543}', ['\u{573}', '\u{0}', '\u{0}']), + ('\u{544}', ['\u{574}', '\u{0}', '\u{0}']), ('\u{545}', ['\u{575}', '\u{0}', '\u{0}']), + ('\u{546}', ['\u{576}', '\u{0}', '\u{0}']), ('\u{547}', ['\u{577}', '\u{0}', '\u{0}']), + ('\u{548}', ['\u{578}', '\u{0}', '\u{0}']), ('\u{549}', ['\u{579}', '\u{0}', '\u{0}']), + ('\u{54a}', ['\u{57a}', '\u{0}', '\u{0}']), ('\u{54b}', ['\u{57b}', '\u{0}', '\u{0}']), + ('\u{54c}', ['\u{57c}', '\u{0}', '\u{0}']), ('\u{54d}', ['\u{57d}', '\u{0}', '\u{0}']), + ('\u{54e}', ['\u{57e}', '\u{0}', '\u{0}']), ('\u{54f}', ['\u{57f}', '\u{0}', '\u{0}']), + ('\u{550}', ['\u{580}', '\u{0}', '\u{0}']), ('\u{551}', ['\u{581}', '\u{0}', '\u{0}']), + ('\u{552}', ['\u{582}', '\u{0}', '\u{0}']), ('\u{553}', ['\u{583}', '\u{0}', '\u{0}']), + ('\u{554}', ['\u{584}', '\u{0}', '\u{0}']), ('\u{555}', ['\u{585}', '\u{0}', '\u{0}']), + ('\u{556}', ['\u{586}', '\u{0}', '\u{0}']), ('\u{10a0}', ['\u{2d00}', '\u{0}', '\u{0}']), + ('\u{10a1}', ['\u{2d01}', '\u{0}', '\u{0}']), ('\u{10a2}', ['\u{2d02}', '\u{0}', '\u{0}']), + ('\u{10a3}', ['\u{2d03}', '\u{0}', '\u{0}']), ('\u{10a4}', ['\u{2d04}', '\u{0}', '\u{0}']), + ('\u{10a5}', ['\u{2d05}', '\u{0}', '\u{0}']), ('\u{10a6}', ['\u{2d06}', '\u{0}', '\u{0}']), + ('\u{10a7}', ['\u{2d07}', '\u{0}', '\u{0}']), ('\u{10a8}', ['\u{2d08}', '\u{0}', '\u{0}']), + ('\u{10a9}', ['\u{2d09}', '\u{0}', '\u{0}']), ('\u{10aa}', ['\u{2d0a}', '\u{0}', '\u{0}']), + ('\u{10ab}', ['\u{2d0b}', '\u{0}', '\u{0}']), ('\u{10ac}', ['\u{2d0c}', '\u{0}', '\u{0}']), + ('\u{10ad}', ['\u{2d0d}', '\u{0}', '\u{0}']), ('\u{10ae}', ['\u{2d0e}', '\u{0}', '\u{0}']), + ('\u{10af}', ['\u{2d0f}', '\u{0}', '\u{0}']), ('\u{10b0}', ['\u{2d10}', '\u{0}', '\u{0}']), + ('\u{10b1}', ['\u{2d11}', '\u{0}', '\u{0}']), ('\u{10b2}', ['\u{2d12}', '\u{0}', '\u{0}']), + ('\u{10b3}', ['\u{2d13}', '\u{0}', '\u{0}']), ('\u{10b4}', ['\u{2d14}', '\u{0}', '\u{0}']), + ('\u{10b5}', ['\u{2d15}', '\u{0}', '\u{0}']), ('\u{10b6}', ['\u{2d16}', '\u{0}', '\u{0}']), + ('\u{10b7}', ['\u{2d17}', '\u{0}', '\u{0}']), ('\u{10b8}', ['\u{2d18}', '\u{0}', '\u{0}']), + ('\u{10b9}', ['\u{2d19}', '\u{0}', '\u{0}']), ('\u{10ba}', ['\u{2d1a}', '\u{0}', '\u{0}']), + ('\u{10bb}', ['\u{2d1b}', '\u{0}', '\u{0}']), ('\u{10bc}', ['\u{2d1c}', '\u{0}', '\u{0}']), + ('\u{10bd}', ['\u{2d1d}', '\u{0}', '\u{0}']), ('\u{10be}', ['\u{2d1e}', '\u{0}', '\u{0}']), + ('\u{10bf}', ['\u{2d1f}', '\u{0}', '\u{0}']), ('\u{10c0}', ['\u{2d20}', '\u{0}', '\u{0}']), + ('\u{10c1}', ['\u{2d21}', '\u{0}', '\u{0}']), ('\u{10c2}', ['\u{2d22}', '\u{0}', '\u{0}']), + ('\u{10c3}', ['\u{2d23}', '\u{0}', '\u{0}']), ('\u{10c4}', ['\u{2d24}', '\u{0}', '\u{0}']), + ('\u{10c5}', ['\u{2d25}', '\u{0}', '\u{0}']), ('\u{10c7}', ['\u{2d27}', '\u{0}', '\u{0}']), + ('\u{10cd}', ['\u{2d2d}', '\u{0}', '\u{0}']), ('\u{13a0}', ['\u{ab70}', '\u{0}', '\u{0}']), + ('\u{13a1}', ['\u{ab71}', '\u{0}', '\u{0}']), ('\u{13a2}', ['\u{ab72}', '\u{0}', '\u{0}']), + ('\u{13a3}', ['\u{ab73}', '\u{0}', '\u{0}']), ('\u{13a4}', ['\u{ab74}', '\u{0}', '\u{0}']), + ('\u{13a5}', ['\u{ab75}', '\u{0}', '\u{0}']), ('\u{13a6}', ['\u{ab76}', '\u{0}', '\u{0}']), + ('\u{13a7}', ['\u{ab77}', '\u{0}', '\u{0}']), ('\u{13a8}', ['\u{ab78}', '\u{0}', '\u{0}']), + ('\u{13a9}', ['\u{ab79}', '\u{0}', '\u{0}']), ('\u{13aa}', ['\u{ab7a}', '\u{0}', '\u{0}']), + ('\u{13ab}', ['\u{ab7b}', '\u{0}', '\u{0}']), ('\u{13ac}', ['\u{ab7c}', '\u{0}', '\u{0}']), + ('\u{13ad}', ['\u{ab7d}', '\u{0}', '\u{0}']), ('\u{13ae}', ['\u{ab7e}', '\u{0}', '\u{0}']), + ('\u{13af}', ['\u{ab7f}', '\u{0}', '\u{0}']), ('\u{13b0}', ['\u{ab80}', '\u{0}', '\u{0}']), + ('\u{13b1}', ['\u{ab81}', '\u{0}', '\u{0}']), ('\u{13b2}', ['\u{ab82}', '\u{0}', '\u{0}']), + ('\u{13b3}', ['\u{ab83}', '\u{0}', '\u{0}']), ('\u{13b4}', ['\u{ab84}', '\u{0}', '\u{0}']), + ('\u{13b5}', ['\u{ab85}', '\u{0}', '\u{0}']), ('\u{13b6}', ['\u{ab86}', '\u{0}', '\u{0}']), + ('\u{13b7}', ['\u{ab87}', '\u{0}', '\u{0}']), ('\u{13b8}', ['\u{ab88}', '\u{0}', '\u{0}']), + ('\u{13b9}', ['\u{ab89}', '\u{0}', '\u{0}']), ('\u{13ba}', ['\u{ab8a}', '\u{0}', '\u{0}']), + ('\u{13bb}', ['\u{ab8b}', '\u{0}', '\u{0}']), ('\u{13bc}', ['\u{ab8c}', '\u{0}', '\u{0}']), + ('\u{13bd}', ['\u{ab8d}', '\u{0}', '\u{0}']), ('\u{13be}', ['\u{ab8e}', '\u{0}', '\u{0}']), + ('\u{13bf}', ['\u{ab8f}', '\u{0}', '\u{0}']), ('\u{13c0}', ['\u{ab90}', '\u{0}', '\u{0}']), + ('\u{13c1}', ['\u{ab91}', '\u{0}', '\u{0}']), ('\u{13c2}', ['\u{ab92}', '\u{0}', '\u{0}']), + ('\u{13c3}', ['\u{ab93}', '\u{0}', '\u{0}']), ('\u{13c4}', ['\u{ab94}', '\u{0}', '\u{0}']), + ('\u{13c5}', ['\u{ab95}', '\u{0}', '\u{0}']), ('\u{13c6}', ['\u{ab96}', '\u{0}', '\u{0}']), + ('\u{13c7}', ['\u{ab97}', '\u{0}', '\u{0}']), ('\u{13c8}', ['\u{ab98}', '\u{0}', '\u{0}']), + ('\u{13c9}', ['\u{ab99}', '\u{0}', '\u{0}']), ('\u{13ca}', ['\u{ab9a}', '\u{0}', '\u{0}']), + ('\u{13cb}', ['\u{ab9b}', '\u{0}', '\u{0}']), ('\u{13cc}', ['\u{ab9c}', '\u{0}', '\u{0}']), + ('\u{13cd}', ['\u{ab9d}', '\u{0}', '\u{0}']), ('\u{13ce}', ['\u{ab9e}', '\u{0}', '\u{0}']), + ('\u{13cf}', ['\u{ab9f}', '\u{0}', '\u{0}']), ('\u{13d0}', ['\u{aba0}', '\u{0}', '\u{0}']), + ('\u{13d1}', ['\u{aba1}', '\u{0}', '\u{0}']), ('\u{13d2}', ['\u{aba2}', '\u{0}', '\u{0}']), + ('\u{13d3}', ['\u{aba3}', '\u{0}', '\u{0}']), ('\u{13d4}', ['\u{aba4}', '\u{0}', '\u{0}']), + ('\u{13d5}', ['\u{aba5}', '\u{0}', '\u{0}']), ('\u{13d6}', ['\u{aba6}', '\u{0}', '\u{0}']), + ('\u{13d7}', ['\u{aba7}', '\u{0}', '\u{0}']), ('\u{13d8}', ['\u{aba8}', '\u{0}', '\u{0}']), + ('\u{13d9}', ['\u{aba9}', '\u{0}', '\u{0}']), ('\u{13da}', ['\u{abaa}', '\u{0}', '\u{0}']), + ('\u{13db}', ['\u{abab}', '\u{0}', '\u{0}']), ('\u{13dc}', ['\u{abac}', '\u{0}', '\u{0}']), + ('\u{13dd}', ['\u{abad}', '\u{0}', '\u{0}']), ('\u{13de}', ['\u{abae}', '\u{0}', '\u{0}']), + ('\u{13df}', ['\u{abaf}', '\u{0}', '\u{0}']), ('\u{13e0}', ['\u{abb0}', '\u{0}', '\u{0}']), + ('\u{13e1}', ['\u{abb1}', '\u{0}', '\u{0}']), ('\u{13e2}', ['\u{abb2}', '\u{0}', '\u{0}']), + ('\u{13e3}', ['\u{abb3}', '\u{0}', '\u{0}']), ('\u{13e4}', ['\u{abb4}', '\u{0}', '\u{0}']), + ('\u{13e5}', ['\u{abb5}', '\u{0}', '\u{0}']), ('\u{13e6}', ['\u{abb6}', '\u{0}', '\u{0}']), + ('\u{13e7}', ['\u{abb7}', '\u{0}', '\u{0}']), ('\u{13e8}', ['\u{abb8}', '\u{0}', '\u{0}']), + ('\u{13e9}', ['\u{abb9}', '\u{0}', '\u{0}']), ('\u{13ea}', ['\u{abba}', '\u{0}', '\u{0}']), + ('\u{13eb}', ['\u{abbb}', '\u{0}', '\u{0}']), ('\u{13ec}', ['\u{abbc}', '\u{0}', '\u{0}']), + ('\u{13ed}', ['\u{abbd}', '\u{0}', '\u{0}']), ('\u{13ee}', ['\u{abbe}', '\u{0}', '\u{0}']), + ('\u{13ef}', ['\u{abbf}', '\u{0}', '\u{0}']), ('\u{13f0}', ['\u{13f8}', '\u{0}', '\u{0}']), + ('\u{13f1}', ['\u{13f9}', '\u{0}', '\u{0}']), ('\u{13f2}', ['\u{13fa}', '\u{0}', '\u{0}']), + ('\u{13f3}', ['\u{13fb}', '\u{0}', '\u{0}']), ('\u{13f4}', ['\u{13fc}', '\u{0}', '\u{0}']), + ('\u{13f5}', ['\u{13fd}', '\u{0}', '\u{0}']), ('\u{1c89}', ['\u{1c8a}', '\u{0}', '\u{0}']), + ('\u{1c90}', ['\u{10d0}', '\u{0}', '\u{0}']), ('\u{1c91}', ['\u{10d1}', '\u{0}', '\u{0}']), + ('\u{1c92}', ['\u{10d2}', '\u{0}', '\u{0}']), ('\u{1c93}', ['\u{10d3}', '\u{0}', '\u{0}']), + ('\u{1c94}', ['\u{10d4}', '\u{0}', '\u{0}']), ('\u{1c95}', ['\u{10d5}', '\u{0}', '\u{0}']), + ('\u{1c96}', ['\u{10d6}', '\u{0}', '\u{0}']), ('\u{1c97}', ['\u{10d7}', '\u{0}', '\u{0}']), + ('\u{1c98}', ['\u{10d8}', '\u{0}', '\u{0}']), ('\u{1c99}', ['\u{10d9}', '\u{0}', '\u{0}']), + ('\u{1c9a}', ['\u{10da}', '\u{0}', '\u{0}']), ('\u{1c9b}', ['\u{10db}', '\u{0}', '\u{0}']), + ('\u{1c9c}', ['\u{10dc}', '\u{0}', '\u{0}']), ('\u{1c9d}', ['\u{10dd}', '\u{0}', '\u{0}']), + ('\u{1c9e}', ['\u{10de}', '\u{0}', '\u{0}']), ('\u{1c9f}', ['\u{10df}', '\u{0}', '\u{0}']), + ('\u{1ca0}', ['\u{10e0}', '\u{0}', '\u{0}']), ('\u{1ca1}', ['\u{10e1}', '\u{0}', '\u{0}']), + ('\u{1ca2}', ['\u{10e2}', '\u{0}', '\u{0}']), ('\u{1ca3}', ['\u{10e3}', '\u{0}', '\u{0}']), + ('\u{1ca4}', ['\u{10e4}', '\u{0}', '\u{0}']), ('\u{1ca5}', ['\u{10e5}', '\u{0}', '\u{0}']), + ('\u{1ca6}', ['\u{10e6}', '\u{0}', '\u{0}']), ('\u{1ca7}', ['\u{10e7}', '\u{0}', '\u{0}']), + ('\u{1ca8}', ['\u{10e8}', '\u{0}', '\u{0}']), ('\u{1ca9}', ['\u{10e9}', '\u{0}', '\u{0}']), + ('\u{1caa}', ['\u{10ea}', '\u{0}', '\u{0}']), ('\u{1cab}', ['\u{10eb}', '\u{0}', '\u{0}']), + ('\u{1cac}', ['\u{10ec}', '\u{0}', '\u{0}']), ('\u{1cad}', ['\u{10ed}', '\u{0}', '\u{0}']), + ('\u{1cae}', ['\u{10ee}', '\u{0}', '\u{0}']), ('\u{1caf}', ['\u{10ef}', '\u{0}', '\u{0}']), + ('\u{1cb0}', ['\u{10f0}', '\u{0}', '\u{0}']), ('\u{1cb1}', ['\u{10f1}', '\u{0}', '\u{0}']), + ('\u{1cb2}', ['\u{10f2}', '\u{0}', '\u{0}']), ('\u{1cb3}', ['\u{10f3}', '\u{0}', '\u{0}']), + ('\u{1cb4}', ['\u{10f4}', '\u{0}', '\u{0}']), ('\u{1cb5}', ['\u{10f5}', '\u{0}', '\u{0}']), + ('\u{1cb6}', ['\u{10f6}', '\u{0}', '\u{0}']), ('\u{1cb7}', ['\u{10f7}', '\u{0}', '\u{0}']), + ('\u{1cb8}', ['\u{10f8}', '\u{0}', '\u{0}']), ('\u{1cb9}', ['\u{10f9}', '\u{0}', '\u{0}']), + ('\u{1cba}', ['\u{10fa}', '\u{0}', '\u{0}']), ('\u{1cbd}', ['\u{10fd}', '\u{0}', '\u{0}']), + ('\u{1cbe}', ['\u{10fe}', '\u{0}', '\u{0}']), ('\u{1cbf}', ['\u{10ff}', '\u{0}', '\u{0}']), + ('\u{1e00}', ['\u{1e01}', '\u{0}', '\u{0}']), ('\u{1e02}', ['\u{1e03}', '\u{0}', '\u{0}']), + ('\u{1e04}', ['\u{1e05}', '\u{0}', '\u{0}']), ('\u{1e06}', ['\u{1e07}', '\u{0}', '\u{0}']), + ('\u{1e08}', ['\u{1e09}', '\u{0}', '\u{0}']), ('\u{1e0a}', ['\u{1e0b}', '\u{0}', '\u{0}']), + ('\u{1e0c}', ['\u{1e0d}', '\u{0}', '\u{0}']), ('\u{1e0e}', ['\u{1e0f}', '\u{0}', '\u{0}']), + ('\u{1e10}', ['\u{1e11}', '\u{0}', '\u{0}']), ('\u{1e12}', ['\u{1e13}', '\u{0}', '\u{0}']), + ('\u{1e14}', ['\u{1e15}', '\u{0}', '\u{0}']), ('\u{1e16}', ['\u{1e17}', '\u{0}', '\u{0}']), + ('\u{1e18}', ['\u{1e19}', '\u{0}', '\u{0}']), ('\u{1e1a}', ['\u{1e1b}', '\u{0}', '\u{0}']), + ('\u{1e1c}', ['\u{1e1d}', '\u{0}', '\u{0}']), ('\u{1e1e}', ['\u{1e1f}', '\u{0}', '\u{0}']), + ('\u{1e20}', ['\u{1e21}', '\u{0}', '\u{0}']), ('\u{1e22}', ['\u{1e23}', '\u{0}', '\u{0}']), + ('\u{1e24}', ['\u{1e25}', '\u{0}', '\u{0}']), ('\u{1e26}', ['\u{1e27}', '\u{0}', '\u{0}']), + ('\u{1e28}', ['\u{1e29}', '\u{0}', '\u{0}']), ('\u{1e2a}', ['\u{1e2b}', '\u{0}', '\u{0}']), + ('\u{1e2c}', ['\u{1e2d}', '\u{0}', '\u{0}']), ('\u{1e2e}', ['\u{1e2f}', '\u{0}', '\u{0}']), + ('\u{1e30}', ['\u{1e31}', '\u{0}', '\u{0}']), ('\u{1e32}', ['\u{1e33}', '\u{0}', '\u{0}']), + ('\u{1e34}', ['\u{1e35}', '\u{0}', '\u{0}']), ('\u{1e36}', ['\u{1e37}', '\u{0}', '\u{0}']), + ('\u{1e38}', ['\u{1e39}', '\u{0}', '\u{0}']), ('\u{1e3a}', ['\u{1e3b}', '\u{0}', '\u{0}']), + ('\u{1e3c}', ['\u{1e3d}', '\u{0}', '\u{0}']), ('\u{1e3e}', ['\u{1e3f}', '\u{0}', '\u{0}']), + ('\u{1e40}', ['\u{1e41}', '\u{0}', '\u{0}']), ('\u{1e42}', ['\u{1e43}', '\u{0}', '\u{0}']), + ('\u{1e44}', ['\u{1e45}', '\u{0}', '\u{0}']), ('\u{1e46}', ['\u{1e47}', '\u{0}', '\u{0}']), + ('\u{1e48}', ['\u{1e49}', '\u{0}', '\u{0}']), ('\u{1e4a}', ['\u{1e4b}', '\u{0}', '\u{0}']), + ('\u{1e4c}', ['\u{1e4d}', '\u{0}', '\u{0}']), ('\u{1e4e}', ['\u{1e4f}', '\u{0}', '\u{0}']), + ('\u{1e50}', ['\u{1e51}', '\u{0}', '\u{0}']), ('\u{1e52}', ['\u{1e53}', '\u{0}', '\u{0}']), + ('\u{1e54}', ['\u{1e55}', '\u{0}', '\u{0}']), ('\u{1e56}', ['\u{1e57}', '\u{0}', '\u{0}']), + ('\u{1e58}', ['\u{1e59}', '\u{0}', '\u{0}']), ('\u{1e5a}', ['\u{1e5b}', '\u{0}', '\u{0}']), + ('\u{1e5c}', ['\u{1e5d}', '\u{0}', '\u{0}']), ('\u{1e5e}', ['\u{1e5f}', '\u{0}', '\u{0}']), + ('\u{1e60}', ['\u{1e61}', '\u{0}', '\u{0}']), ('\u{1e62}', ['\u{1e63}', '\u{0}', '\u{0}']), + ('\u{1e64}', ['\u{1e65}', '\u{0}', '\u{0}']), ('\u{1e66}', ['\u{1e67}', '\u{0}', '\u{0}']), + ('\u{1e68}', ['\u{1e69}', '\u{0}', '\u{0}']), ('\u{1e6a}', ['\u{1e6b}', '\u{0}', '\u{0}']), + ('\u{1e6c}', ['\u{1e6d}', '\u{0}', '\u{0}']), ('\u{1e6e}', ['\u{1e6f}', '\u{0}', '\u{0}']), + ('\u{1e70}', ['\u{1e71}', '\u{0}', '\u{0}']), ('\u{1e72}', ['\u{1e73}', '\u{0}', '\u{0}']), + ('\u{1e74}', ['\u{1e75}', '\u{0}', '\u{0}']), ('\u{1e76}', ['\u{1e77}', '\u{0}', '\u{0}']), + ('\u{1e78}', ['\u{1e79}', '\u{0}', '\u{0}']), ('\u{1e7a}', ['\u{1e7b}', '\u{0}', '\u{0}']), + ('\u{1e7c}', ['\u{1e7d}', '\u{0}', '\u{0}']), ('\u{1e7e}', ['\u{1e7f}', '\u{0}', '\u{0}']), + ('\u{1e80}', ['\u{1e81}', '\u{0}', '\u{0}']), ('\u{1e82}', ['\u{1e83}', '\u{0}', '\u{0}']), + ('\u{1e84}', ['\u{1e85}', '\u{0}', '\u{0}']), ('\u{1e86}', ['\u{1e87}', '\u{0}', '\u{0}']), + ('\u{1e88}', ['\u{1e89}', '\u{0}', '\u{0}']), ('\u{1e8a}', ['\u{1e8b}', '\u{0}', '\u{0}']), + ('\u{1e8c}', ['\u{1e8d}', '\u{0}', '\u{0}']), ('\u{1e8e}', ['\u{1e8f}', '\u{0}', '\u{0}']), + ('\u{1e90}', ['\u{1e91}', '\u{0}', '\u{0}']), ('\u{1e92}', ['\u{1e93}', '\u{0}', '\u{0}']), + ('\u{1e94}', ['\u{1e95}', '\u{0}', '\u{0}']), ('\u{1e9e}', ['\u{df}', '\u{0}', '\u{0}']), + ('\u{1ea0}', ['\u{1ea1}', '\u{0}', '\u{0}']), ('\u{1ea2}', ['\u{1ea3}', '\u{0}', '\u{0}']), + ('\u{1ea4}', ['\u{1ea5}', '\u{0}', '\u{0}']), ('\u{1ea6}', ['\u{1ea7}', '\u{0}', '\u{0}']), + ('\u{1ea8}', ['\u{1ea9}', '\u{0}', '\u{0}']), ('\u{1eaa}', ['\u{1eab}', '\u{0}', '\u{0}']), + ('\u{1eac}', ['\u{1ead}', '\u{0}', '\u{0}']), ('\u{1eae}', ['\u{1eaf}', '\u{0}', '\u{0}']), + ('\u{1eb0}', ['\u{1eb1}', '\u{0}', '\u{0}']), ('\u{1eb2}', ['\u{1eb3}', '\u{0}', '\u{0}']), + ('\u{1eb4}', ['\u{1eb5}', '\u{0}', '\u{0}']), ('\u{1eb6}', ['\u{1eb7}', '\u{0}', '\u{0}']), + ('\u{1eb8}', ['\u{1eb9}', '\u{0}', '\u{0}']), ('\u{1eba}', ['\u{1ebb}', '\u{0}', '\u{0}']), + ('\u{1ebc}', ['\u{1ebd}', '\u{0}', '\u{0}']), ('\u{1ebe}', ['\u{1ebf}', '\u{0}', '\u{0}']), + ('\u{1ec0}', ['\u{1ec1}', '\u{0}', '\u{0}']), ('\u{1ec2}', ['\u{1ec3}', '\u{0}', '\u{0}']), + ('\u{1ec4}', ['\u{1ec5}', '\u{0}', '\u{0}']), ('\u{1ec6}', ['\u{1ec7}', '\u{0}', '\u{0}']), + ('\u{1ec8}', ['\u{1ec9}', '\u{0}', '\u{0}']), ('\u{1eca}', ['\u{1ecb}', '\u{0}', '\u{0}']), + ('\u{1ecc}', ['\u{1ecd}', '\u{0}', '\u{0}']), ('\u{1ece}', ['\u{1ecf}', '\u{0}', '\u{0}']), + ('\u{1ed0}', ['\u{1ed1}', '\u{0}', '\u{0}']), ('\u{1ed2}', ['\u{1ed3}', '\u{0}', '\u{0}']), + ('\u{1ed4}', ['\u{1ed5}', '\u{0}', '\u{0}']), ('\u{1ed6}', ['\u{1ed7}', '\u{0}', '\u{0}']), + ('\u{1ed8}', ['\u{1ed9}', '\u{0}', '\u{0}']), ('\u{1eda}', ['\u{1edb}', '\u{0}', '\u{0}']), + ('\u{1edc}', ['\u{1edd}', '\u{0}', '\u{0}']), ('\u{1ede}', ['\u{1edf}', '\u{0}', '\u{0}']), + ('\u{1ee0}', ['\u{1ee1}', '\u{0}', '\u{0}']), ('\u{1ee2}', ['\u{1ee3}', '\u{0}', '\u{0}']), + ('\u{1ee4}', ['\u{1ee5}', '\u{0}', '\u{0}']), ('\u{1ee6}', ['\u{1ee7}', '\u{0}', '\u{0}']), + ('\u{1ee8}', ['\u{1ee9}', '\u{0}', '\u{0}']), ('\u{1eea}', ['\u{1eeb}', '\u{0}', '\u{0}']), + ('\u{1eec}', ['\u{1eed}', '\u{0}', '\u{0}']), ('\u{1eee}', ['\u{1eef}', '\u{0}', '\u{0}']), + ('\u{1ef0}', ['\u{1ef1}', '\u{0}', '\u{0}']), ('\u{1ef2}', ['\u{1ef3}', '\u{0}', '\u{0}']), + ('\u{1ef4}', ['\u{1ef5}', '\u{0}', '\u{0}']), ('\u{1ef6}', ['\u{1ef7}', '\u{0}', '\u{0}']), + ('\u{1ef8}', ['\u{1ef9}', '\u{0}', '\u{0}']), ('\u{1efa}', ['\u{1efb}', '\u{0}', '\u{0}']), + ('\u{1efc}', ['\u{1efd}', '\u{0}', '\u{0}']), ('\u{1efe}', ['\u{1eff}', '\u{0}', '\u{0}']), + ('\u{1f08}', ['\u{1f00}', '\u{0}', '\u{0}']), ('\u{1f09}', ['\u{1f01}', '\u{0}', '\u{0}']), + ('\u{1f0a}', ['\u{1f02}', '\u{0}', '\u{0}']), ('\u{1f0b}', ['\u{1f03}', '\u{0}', '\u{0}']), + ('\u{1f0c}', ['\u{1f04}', '\u{0}', '\u{0}']), ('\u{1f0d}', ['\u{1f05}', '\u{0}', '\u{0}']), + ('\u{1f0e}', ['\u{1f06}', '\u{0}', '\u{0}']), ('\u{1f0f}', ['\u{1f07}', '\u{0}', '\u{0}']), + ('\u{1f18}', ['\u{1f10}', '\u{0}', '\u{0}']), ('\u{1f19}', ['\u{1f11}', '\u{0}', '\u{0}']), + ('\u{1f1a}', ['\u{1f12}', '\u{0}', '\u{0}']), ('\u{1f1b}', ['\u{1f13}', '\u{0}', '\u{0}']), + ('\u{1f1c}', ['\u{1f14}', '\u{0}', '\u{0}']), ('\u{1f1d}', ['\u{1f15}', '\u{0}', '\u{0}']), + ('\u{1f28}', ['\u{1f20}', '\u{0}', '\u{0}']), ('\u{1f29}', ['\u{1f21}', '\u{0}', '\u{0}']), + ('\u{1f2a}', ['\u{1f22}', '\u{0}', '\u{0}']), ('\u{1f2b}', ['\u{1f23}', '\u{0}', '\u{0}']), + ('\u{1f2c}', ['\u{1f24}', '\u{0}', '\u{0}']), ('\u{1f2d}', ['\u{1f25}', '\u{0}', '\u{0}']), + ('\u{1f2e}', ['\u{1f26}', '\u{0}', '\u{0}']), ('\u{1f2f}', ['\u{1f27}', '\u{0}', '\u{0}']), + ('\u{1f38}', ['\u{1f30}', '\u{0}', '\u{0}']), ('\u{1f39}', ['\u{1f31}', '\u{0}', '\u{0}']), + ('\u{1f3a}', ['\u{1f32}', '\u{0}', '\u{0}']), ('\u{1f3b}', ['\u{1f33}', '\u{0}', '\u{0}']), + ('\u{1f3c}', ['\u{1f34}', '\u{0}', '\u{0}']), ('\u{1f3d}', ['\u{1f35}', '\u{0}', '\u{0}']), + ('\u{1f3e}', ['\u{1f36}', '\u{0}', '\u{0}']), ('\u{1f3f}', ['\u{1f37}', '\u{0}', '\u{0}']), + ('\u{1f48}', ['\u{1f40}', '\u{0}', '\u{0}']), ('\u{1f49}', ['\u{1f41}', '\u{0}', '\u{0}']), + ('\u{1f4a}', ['\u{1f42}', '\u{0}', '\u{0}']), ('\u{1f4b}', ['\u{1f43}', '\u{0}', '\u{0}']), + ('\u{1f4c}', ['\u{1f44}', '\u{0}', '\u{0}']), ('\u{1f4d}', ['\u{1f45}', '\u{0}', '\u{0}']), + ('\u{1f59}', ['\u{1f51}', '\u{0}', '\u{0}']), ('\u{1f5b}', ['\u{1f53}', '\u{0}', '\u{0}']), + ('\u{1f5d}', ['\u{1f55}', '\u{0}', '\u{0}']), ('\u{1f5f}', ['\u{1f57}', '\u{0}', '\u{0}']), + ('\u{1f68}', ['\u{1f60}', '\u{0}', '\u{0}']), ('\u{1f69}', ['\u{1f61}', '\u{0}', '\u{0}']), + ('\u{1f6a}', ['\u{1f62}', '\u{0}', '\u{0}']), ('\u{1f6b}', ['\u{1f63}', '\u{0}', '\u{0}']), + ('\u{1f6c}', ['\u{1f64}', '\u{0}', '\u{0}']), ('\u{1f6d}', ['\u{1f65}', '\u{0}', '\u{0}']), + ('\u{1f6e}', ['\u{1f66}', '\u{0}', '\u{0}']), ('\u{1f6f}', ['\u{1f67}', '\u{0}', '\u{0}']), + ('\u{1f88}', ['\u{1f80}', '\u{0}', '\u{0}']), ('\u{1f89}', ['\u{1f81}', '\u{0}', '\u{0}']), + ('\u{1f8a}', ['\u{1f82}', '\u{0}', '\u{0}']), ('\u{1f8b}', ['\u{1f83}', '\u{0}', '\u{0}']), + ('\u{1f8c}', ['\u{1f84}', '\u{0}', '\u{0}']), ('\u{1f8d}', ['\u{1f85}', '\u{0}', '\u{0}']), + ('\u{1f8e}', ['\u{1f86}', '\u{0}', '\u{0}']), ('\u{1f8f}', ['\u{1f87}', '\u{0}', '\u{0}']), + ('\u{1f98}', ['\u{1f90}', '\u{0}', '\u{0}']), ('\u{1f99}', ['\u{1f91}', '\u{0}', '\u{0}']), + ('\u{1f9a}', ['\u{1f92}', '\u{0}', '\u{0}']), ('\u{1f9b}', ['\u{1f93}', '\u{0}', '\u{0}']), + ('\u{1f9c}', ['\u{1f94}', '\u{0}', '\u{0}']), ('\u{1f9d}', ['\u{1f95}', '\u{0}', '\u{0}']), + ('\u{1f9e}', ['\u{1f96}', '\u{0}', '\u{0}']), ('\u{1f9f}', ['\u{1f97}', '\u{0}', '\u{0}']), + ('\u{1fa8}', ['\u{1fa0}', '\u{0}', '\u{0}']), ('\u{1fa9}', ['\u{1fa1}', '\u{0}', '\u{0}']), + ('\u{1faa}', ['\u{1fa2}', '\u{0}', '\u{0}']), ('\u{1fab}', ['\u{1fa3}', '\u{0}', '\u{0}']), + ('\u{1fac}', ['\u{1fa4}', '\u{0}', '\u{0}']), ('\u{1fad}', ['\u{1fa5}', '\u{0}', '\u{0}']), + ('\u{1fae}', ['\u{1fa6}', '\u{0}', '\u{0}']), ('\u{1faf}', ['\u{1fa7}', '\u{0}', '\u{0}']), + ('\u{1fb8}', ['\u{1fb0}', '\u{0}', '\u{0}']), ('\u{1fb9}', ['\u{1fb1}', '\u{0}', '\u{0}']), + ('\u{1fba}', ['\u{1f70}', '\u{0}', '\u{0}']), ('\u{1fbb}', ['\u{1f71}', '\u{0}', '\u{0}']), + ('\u{1fbc}', ['\u{1fb3}', '\u{0}', '\u{0}']), ('\u{1fc8}', ['\u{1f72}', '\u{0}', '\u{0}']), + ('\u{1fc9}', ['\u{1f73}', '\u{0}', '\u{0}']), ('\u{1fca}', ['\u{1f74}', '\u{0}', '\u{0}']), + ('\u{1fcb}', ['\u{1f75}', '\u{0}', '\u{0}']), ('\u{1fcc}', ['\u{1fc3}', '\u{0}', '\u{0}']), + ('\u{1fd8}', ['\u{1fd0}', '\u{0}', '\u{0}']), ('\u{1fd9}', ['\u{1fd1}', '\u{0}', '\u{0}']), + ('\u{1fda}', ['\u{1f76}', '\u{0}', '\u{0}']), ('\u{1fdb}', ['\u{1f77}', '\u{0}', '\u{0}']), + ('\u{1fe8}', ['\u{1fe0}', '\u{0}', '\u{0}']), ('\u{1fe9}', ['\u{1fe1}', '\u{0}', '\u{0}']), + ('\u{1fea}', ['\u{1f7a}', '\u{0}', '\u{0}']), ('\u{1feb}', ['\u{1f7b}', '\u{0}', '\u{0}']), + ('\u{1fec}', ['\u{1fe5}', '\u{0}', '\u{0}']), ('\u{1ff8}', ['\u{1f78}', '\u{0}', '\u{0}']), + ('\u{1ff9}', ['\u{1f79}', '\u{0}', '\u{0}']), ('\u{1ffa}', ['\u{1f7c}', '\u{0}', '\u{0}']), + ('\u{1ffb}', ['\u{1f7d}', '\u{0}', '\u{0}']), ('\u{1ffc}', ['\u{1ff3}', '\u{0}', '\u{0}']), + ('\u{2126}', ['\u{3c9}', '\u{0}', '\u{0}']), ('\u{212a}', ['\u{6b}', '\u{0}', '\u{0}']), + ('\u{212b}', ['\u{e5}', '\u{0}', '\u{0}']), ('\u{2132}', ['\u{214e}', '\u{0}', '\u{0}']), + ('\u{2160}', ['\u{2170}', '\u{0}', '\u{0}']), ('\u{2161}', ['\u{2171}', '\u{0}', '\u{0}']), + ('\u{2162}', ['\u{2172}', '\u{0}', '\u{0}']), ('\u{2163}', ['\u{2173}', '\u{0}', '\u{0}']), + ('\u{2164}', ['\u{2174}', '\u{0}', '\u{0}']), ('\u{2165}', ['\u{2175}', '\u{0}', '\u{0}']), + ('\u{2166}', ['\u{2176}', '\u{0}', '\u{0}']), ('\u{2167}', ['\u{2177}', '\u{0}', '\u{0}']), + ('\u{2168}', ['\u{2178}', '\u{0}', '\u{0}']), ('\u{2169}', ['\u{2179}', '\u{0}', '\u{0}']), + ('\u{216a}', ['\u{217a}', '\u{0}', '\u{0}']), ('\u{216b}', ['\u{217b}', '\u{0}', '\u{0}']), + ('\u{216c}', ['\u{217c}', '\u{0}', '\u{0}']), ('\u{216d}', ['\u{217d}', '\u{0}', '\u{0}']), + ('\u{216e}', ['\u{217e}', '\u{0}', '\u{0}']), ('\u{216f}', ['\u{217f}', '\u{0}', '\u{0}']), + ('\u{2183}', ['\u{2184}', '\u{0}', '\u{0}']), ('\u{24b6}', ['\u{24d0}', '\u{0}', '\u{0}']), + ('\u{24b7}', ['\u{24d1}', '\u{0}', '\u{0}']), ('\u{24b8}', ['\u{24d2}', '\u{0}', '\u{0}']), + ('\u{24b9}', ['\u{24d3}', '\u{0}', '\u{0}']), ('\u{24ba}', ['\u{24d4}', '\u{0}', '\u{0}']), + ('\u{24bb}', ['\u{24d5}', '\u{0}', '\u{0}']), ('\u{24bc}', ['\u{24d6}', '\u{0}', '\u{0}']), + ('\u{24bd}', ['\u{24d7}', '\u{0}', '\u{0}']), ('\u{24be}', ['\u{24d8}', '\u{0}', '\u{0}']), + ('\u{24bf}', ['\u{24d9}', '\u{0}', '\u{0}']), ('\u{24c0}', ['\u{24da}', '\u{0}', '\u{0}']), + ('\u{24c1}', ['\u{24db}', '\u{0}', '\u{0}']), ('\u{24c2}', ['\u{24dc}', '\u{0}', '\u{0}']), + ('\u{24c3}', ['\u{24dd}', '\u{0}', '\u{0}']), ('\u{24c4}', ['\u{24de}', '\u{0}', '\u{0}']), + ('\u{24c5}', ['\u{24df}', '\u{0}', '\u{0}']), ('\u{24c6}', ['\u{24e0}', '\u{0}', '\u{0}']), + ('\u{24c7}', ['\u{24e1}', '\u{0}', '\u{0}']), ('\u{24c8}', ['\u{24e2}', '\u{0}', '\u{0}']), + ('\u{24c9}', ['\u{24e3}', '\u{0}', '\u{0}']), ('\u{24ca}', ['\u{24e4}', '\u{0}', '\u{0}']), + ('\u{24cb}', ['\u{24e5}', '\u{0}', '\u{0}']), ('\u{24cc}', ['\u{24e6}', '\u{0}', '\u{0}']), + ('\u{24cd}', ['\u{24e7}', '\u{0}', '\u{0}']), ('\u{24ce}', ['\u{24e8}', '\u{0}', '\u{0}']), + ('\u{24cf}', ['\u{24e9}', '\u{0}', '\u{0}']), ('\u{2c00}', ['\u{2c30}', '\u{0}', '\u{0}']), + ('\u{2c01}', ['\u{2c31}', '\u{0}', '\u{0}']), ('\u{2c02}', ['\u{2c32}', '\u{0}', '\u{0}']), + ('\u{2c03}', ['\u{2c33}', '\u{0}', '\u{0}']), ('\u{2c04}', ['\u{2c34}', '\u{0}', '\u{0}']), + ('\u{2c05}', ['\u{2c35}', '\u{0}', '\u{0}']), ('\u{2c06}', ['\u{2c36}', '\u{0}', '\u{0}']), + ('\u{2c07}', ['\u{2c37}', '\u{0}', '\u{0}']), ('\u{2c08}', ['\u{2c38}', '\u{0}', '\u{0}']), + ('\u{2c09}', ['\u{2c39}', '\u{0}', '\u{0}']), ('\u{2c0a}', ['\u{2c3a}', '\u{0}', '\u{0}']), + ('\u{2c0b}', ['\u{2c3b}', '\u{0}', '\u{0}']), ('\u{2c0c}', ['\u{2c3c}', '\u{0}', '\u{0}']), + ('\u{2c0d}', ['\u{2c3d}', '\u{0}', '\u{0}']), ('\u{2c0e}', ['\u{2c3e}', '\u{0}', '\u{0}']), + ('\u{2c0f}', ['\u{2c3f}', '\u{0}', '\u{0}']), ('\u{2c10}', ['\u{2c40}', '\u{0}', '\u{0}']), + ('\u{2c11}', ['\u{2c41}', '\u{0}', '\u{0}']), ('\u{2c12}', ['\u{2c42}', '\u{0}', '\u{0}']), + ('\u{2c13}', ['\u{2c43}', '\u{0}', '\u{0}']), ('\u{2c14}', ['\u{2c44}', '\u{0}', '\u{0}']), + ('\u{2c15}', ['\u{2c45}', '\u{0}', '\u{0}']), ('\u{2c16}', ['\u{2c46}', '\u{0}', '\u{0}']), + ('\u{2c17}', ['\u{2c47}', '\u{0}', '\u{0}']), ('\u{2c18}', ['\u{2c48}', '\u{0}', '\u{0}']), + ('\u{2c19}', ['\u{2c49}', '\u{0}', '\u{0}']), ('\u{2c1a}', ['\u{2c4a}', '\u{0}', '\u{0}']), + ('\u{2c1b}', ['\u{2c4b}', '\u{0}', '\u{0}']), ('\u{2c1c}', ['\u{2c4c}', '\u{0}', '\u{0}']), + ('\u{2c1d}', ['\u{2c4d}', '\u{0}', '\u{0}']), ('\u{2c1e}', ['\u{2c4e}', '\u{0}', '\u{0}']), + ('\u{2c1f}', ['\u{2c4f}', '\u{0}', '\u{0}']), ('\u{2c20}', ['\u{2c50}', '\u{0}', '\u{0}']), + ('\u{2c21}', ['\u{2c51}', '\u{0}', '\u{0}']), ('\u{2c22}', ['\u{2c52}', '\u{0}', '\u{0}']), + ('\u{2c23}', ['\u{2c53}', '\u{0}', '\u{0}']), ('\u{2c24}', ['\u{2c54}', '\u{0}', '\u{0}']), + ('\u{2c25}', ['\u{2c55}', '\u{0}', '\u{0}']), ('\u{2c26}', ['\u{2c56}', '\u{0}', '\u{0}']), + ('\u{2c27}', ['\u{2c57}', '\u{0}', '\u{0}']), ('\u{2c28}', ['\u{2c58}', '\u{0}', '\u{0}']), + ('\u{2c29}', ['\u{2c59}', '\u{0}', '\u{0}']), ('\u{2c2a}', ['\u{2c5a}', '\u{0}', '\u{0}']), + ('\u{2c2b}', ['\u{2c5b}', '\u{0}', '\u{0}']), ('\u{2c2c}', ['\u{2c5c}', '\u{0}', '\u{0}']), + ('\u{2c2d}', ['\u{2c5d}', '\u{0}', '\u{0}']), ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), + ('\u{2c2f}', ['\u{2c5f}', '\u{0}', '\u{0}']), ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']), + ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']), ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']), + ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']), ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']), + ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']), ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']), + ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']), ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']), + ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']), ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']), + ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']), ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']), + ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']), ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']), + ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']), ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']), + ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']), ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']), + ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']), ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']), + ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']), ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']), + ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']), ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']), + ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']), ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']), + ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']), ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']), + ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']), ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']), + ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']), ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']), + ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']), ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']), + ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']), ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']), + ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']), ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']), + ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']), ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']), + ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']), ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']), + ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']), ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']), + ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']), ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']), + ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']), ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']), + ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']), ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']), + ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']), ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']), + ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']), ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']), + ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']), ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']), + ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']), ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']), + ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']), ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']), + ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']), ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']), + ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']), ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']), + ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']), ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']), + ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']), ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']), + ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']), ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']), + ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']), ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']), + ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']), ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']), + ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']), ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']), + ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']), ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']), + ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']), ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']), + ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']), ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']), + ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']), ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']), + ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']), ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']), + ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']), ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']), + ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']), ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']), + ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']), ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']), + ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']), ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']), + ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']), ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']), + ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']), ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']), + ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']), ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']), + ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']), ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']), + ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']), ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']), + ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']), ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']), + ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']), ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']), + ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']), ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']), + ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']), ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']), + ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']), ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']), + ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']), ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']), + ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']), ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']), + ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']), ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']), + ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']), ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']), + ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']), ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']), + ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']), ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']), + ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']), ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']), + ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']), ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']), + ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']), ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']), + ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']), ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']), + ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']), ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']), + ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']), ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']), + ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']), ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']), + ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']), ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']), + ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']), ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']), + ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']), ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']), + ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']), ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']), + ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']), ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']), + ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']), ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']), + ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']), ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']), + ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']), ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']), + ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']), ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']), + ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']), ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']), + ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']), ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']), + ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']), ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']), + ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']), ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']), + ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']), ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']), + ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']), ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']), + ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']), ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']), + ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']), ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']), + ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']), ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']), + ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']), ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']), + ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']), ('\u{a7c0}', ['\u{a7c1}', '\u{0}', '\u{0}']), + ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']), ('\u{a7c4}', ['\u{a794}', '\u{0}', '\u{0}']), + ('\u{a7c5}', ['\u{282}', '\u{0}', '\u{0}']), ('\u{a7c6}', ['\u{1d8e}', '\u{0}', '\u{0}']), + ('\u{a7c7}', ['\u{a7c8}', '\u{0}', '\u{0}']), ('\u{a7c9}', ['\u{a7ca}', '\u{0}', '\u{0}']), + ('\u{a7cb}', ['\u{264}', '\u{0}', '\u{0}']), ('\u{a7cc}', ['\u{a7cd}', '\u{0}', '\u{0}']), + ('\u{a7ce}', ['\u{a7cf}', '\u{0}', '\u{0}']), ('\u{a7d0}', ['\u{a7d1}', '\u{0}', '\u{0}']), + ('\u{a7d2}', ['\u{a7d3}', '\u{0}', '\u{0}']), ('\u{a7d4}', ['\u{a7d5}', '\u{0}', '\u{0}']), + ('\u{a7d6}', ['\u{a7d7}', '\u{0}', '\u{0}']), ('\u{a7d8}', ['\u{a7d9}', '\u{0}', '\u{0}']), + ('\u{a7da}', ['\u{a7db}', '\u{0}', '\u{0}']), ('\u{a7dc}', ['\u{19b}', '\u{0}', '\u{0}']), + ('\u{a7f5}', ['\u{a7f6}', '\u{0}', '\u{0}']), ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']), + ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']), ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']), + ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']), ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']), + ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']), ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']), + ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']), ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']), + ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']), ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']), + ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']), ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']), + ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']), ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']), + ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']), ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']), + ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']), ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']), + ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']), ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']), + ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']), ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']), + ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']), ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']), + ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']), + ('\u{10400}', ['\u{10428}', '\u{0}', '\u{0}']), + ('\u{10401}', ['\u{10429}', '\u{0}', '\u{0}']), + ('\u{10402}', ['\u{1042a}', '\u{0}', '\u{0}']), + ('\u{10403}', ['\u{1042b}', '\u{0}', '\u{0}']), + ('\u{10404}', ['\u{1042c}', '\u{0}', '\u{0}']), + ('\u{10405}', ['\u{1042d}', '\u{0}', '\u{0}']), + ('\u{10406}', ['\u{1042e}', '\u{0}', '\u{0}']), + ('\u{10407}', ['\u{1042f}', '\u{0}', '\u{0}']), + ('\u{10408}', ['\u{10430}', '\u{0}', '\u{0}']), + ('\u{10409}', ['\u{10431}', '\u{0}', '\u{0}']), + ('\u{1040a}', ['\u{10432}', '\u{0}', '\u{0}']), + ('\u{1040b}', ['\u{10433}', '\u{0}', '\u{0}']), + ('\u{1040c}', ['\u{10434}', '\u{0}', '\u{0}']), + ('\u{1040d}', ['\u{10435}', '\u{0}', '\u{0}']), + ('\u{1040e}', ['\u{10436}', '\u{0}', '\u{0}']), + ('\u{1040f}', ['\u{10437}', '\u{0}', '\u{0}']), + ('\u{10410}', ['\u{10438}', '\u{0}', '\u{0}']), + ('\u{10411}', ['\u{10439}', '\u{0}', '\u{0}']), + ('\u{10412}', ['\u{1043a}', '\u{0}', '\u{0}']), + ('\u{10413}', ['\u{1043b}', '\u{0}', '\u{0}']), + ('\u{10414}', ['\u{1043c}', '\u{0}', '\u{0}']), + ('\u{10415}', ['\u{1043d}', '\u{0}', '\u{0}']), + ('\u{10416}', ['\u{1043e}', '\u{0}', '\u{0}']), + ('\u{10417}', ['\u{1043f}', '\u{0}', '\u{0}']), + ('\u{10418}', ['\u{10440}', '\u{0}', '\u{0}']), + ('\u{10419}', ['\u{10441}', '\u{0}', '\u{0}']), + ('\u{1041a}', ['\u{10442}', '\u{0}', '\u{0}']), + ('\u{1041b}', ['\u{10443}', '\u{0}', '\u{0}']), + ('\u{1041c}', ['\u{10444}', '\u{0}', '\u{0}']), + ('\u{1041d}', ['\u{10445}', '\u{0}', '\u{0}']), + ('\u{1041e}', ['\u{10446}', '\u{0}', '\u{0}']), + ('\u{1041f}', ['\u{10447}', '\u{0}', '\u{0}']), + ('\u{10420}', ['\u{10448}', '\u{0}', '\u{0}']), + ('\u{10421}', ['\u{10449}', '\u{0}', '\u{0}']), + ('\u{10422}', ['\u{1044a}', '\u{0}', '\u{0}']), + ('\u{10423}', ['\u{1044b}', '\u{0}', '\u{0}']), + ('\u{10424}', ['\u{1044c}', '\u{0}', '\u{0}']), + ('\u{10425}', ['\u{1044d}', '\u{0}', '\u{0}']), + ('\u{10426}', ['\u{1044e}', '\u{0}', '\u{0}']), + ('\u{10427}', ['\u{1044f}', '\u{0}', '\u{0}']), + ('\u{104b0}', ['\u{104d8}', '\u{0}', '\u{0}']), + ('\u{104b1}', ['\u{104d9}', '\u{0}', '\u{0}']), + ('\u{104b2}', ['\u{104da}', '\u{0}', '\u{0}']), + ('\u{104b3}', ['\u{104db}', '\u{0}', '\u{0}']), + ('\u{104b4}', ['\u{104dc}', '\u{0}', '\u{0}']), + ('\u{104b5}', ['\u{104dd}', '\u{0}', '\u{0}']), + ('\u{104b6}', ['\u{104de}', '\u{0}', '\u{0}']), + ('\u{104b7}', ['\u{104df}', '\u{0}', '\u{0}']), + ('\u{104b8}', ['\u{104e0}', '\u{0}', '\u{0}']), + ('\u{104b9}', ['\u{104e1}', '\u{0}', '\u{0}']), + ('\u{104ba}', ['\u{104e2}', '\u{0}', '\u{0}']), + ('\u{104bb}', ['\u{104e3}', '\u{0}', '\u{0}']), + ('\u{104bc}', ['\u{104e4}', '\u{0}', '\u{0}']), + ('\u{104bd}', ['\u{104e5}', '\u{0}', '\u{0}']), + ('\u{104be}', ['\u{104e6}', '\u{0}', '\u{0}']), + ('\u{104bf}', ['\u{104e7}', '\u{0}', '\u{0}']), + ('\u{104c0}', ['\u{104e8}', '\u{0}', '\u{0}']), + ('\u{104c1}', ['\u{104e9}', '\u{0}', '\u{0}']), + ('\u{104c2}', ['\u{104ea}', '\u{0}', '\u{0}']), + ('\u{104c3}', ['\u{104eb}', '\u{0}', '\u{0}']), + ('\u{104c4}', ['\u{104ec}', '\u{0}', '\u{0}']), + ('\u{104c5}', ['\u{104ed}', '\u{0}', '\u{0}']), + ('\u{104c6}', ['\u{104ee}', '\u{0}', '\u{0}']), + ('\u{104c7}', ['\u{104ef}', '\u{0}', '\u{0}']), + ('\u{104c8}', ['\u{104f0}', '\u{0}', '\u{0}']), + ('\u{104c9}', ['\u{104f1}', '\u{0}', '\u{0}']), + ('\u{104ca}', ['\u{104f2}', '\u{0}', '\u{0}']), + ('\u{104cb}', ['\u{104f3}', '\u{0}', '\u{0}']), + ('\u{104cc}', ['\u{104f4}', '\u{0}', '\u{0}']), + ('\u{104cd}', ['\u{104f5}', '\u{0}', '\u{0}']), + ('\u{104ce}', ['\u{104f6}', '\u{0}', '\u{0}']), + ('\u{104cf}', ['\u{104f7}', '\u{0}', '\u{0}']), + ('\u{104d0}', ['\u{104f8}', '\u{0}', '\u{0}']), + ('\u{104d1}', ['\u{104f9}', '\u{0}', '\u{0}']), + ('\u{104d2}', ['\u{104fa}', '\u{0}', '\u{0}']), + ('\u{104d3}', ['\u{104fb}', '\u{0}', '\u{0}']), + ('\u{10570}', ['\u{10597}', '\u{0}', '\u{0}']), + ('\u{10571}', ['\u{10598}', '\u{0}', '\u{0}']), + ('\u{10572}', ['\u{10599}', '\u{0}', '\u{0}']), + ('\u{10573}', ['\u{1059a}', '\u{0}', '\u{0}']), + ('\u{10574}', ['\u{1059b}', '\u{0}', '\u{0}']), + ('\u{10575}', ['\u{1059c}', '\u{0}', '\u{0}']), + ('\u{10576}', ['\u{1059d}', '\u{0}', '\u{0}']), + ('\u{10577}', ['\u{1059e}', '\u{0}', '\u{0}']), + ('\u{10578}', ['\u{1059f}', '\u{0}', '\u{0}']), + ('\u{10579}', ['\u{105a0}', '\u{0}', '\u{0}']), + ('\u{1057a}', ['\u{105a1}', '\u{0}', '\u{0}']), + ('\u{1057c}', ['\u{105a3}', '\u{0}', '\u{0}']), + ('\u{1057d}', ['\u{105a4}', '\u{0}', '\u{0}']), + ('\u{1057e}', ['\u{105a5}', '\u{0}', '\u{0}']), + ('\u{1057f}', ['\u{105a6}', '\u{0}', '\u{0}']), + ('\u{10580}', ['\u{105a7}', '\u{0}', '\u{0}']), + ('\u{10581}', ['\u{105a8}', '\u{0}', '\u{0}']), + ('\u{10582}', ['\u{105a9}', '\u{0}', '\u{0}']), + ('\u{10583}', ['\u{105aa}', '\u{0}', '\u{0}']), + ('\u{10584}', ['\u{105ab}', '\u{0}', '\u{0}']), + ('\u{10585}', ['\u{105ac}', '\u{0}', '\u{0}']), + ('\u{10586}', ['\u{105ad}', '\u{0}', '\u{0}']), + ('\u{10587}', ['\u{105ae}', '\u{0}', '\u{0}']), + ('\u{10588}', ['\u{105af}', '\u{0}', '\u{0}']), + ('\u{10589}', ['\u{105b0}', '\u{0}', '\u{0}']), + ('\u{1058a}', ['\u{105b1}', '\u{0}', '\u{0}']), + ('\u{1058c}', ['\u{105b3}', '\u{0}', '\u{0}']), + ('\u{1058d}', ['\u{105b4}', '\u{0}', '\u{0}']), + ('\u{1058e}', ['\u{105b5}', '\u{0}', '\u{0}']), + ('\u{1058f}', ['\u{105b6}', '\u{0}', '\u{0}']), + ('\u{10590}', ['\u{105b7}', '\u{0}', '\u{0}']), + ('\u{10591}', ['\u{105b8}', '\u{0}', '\u{0}']), + ('\u{10592}', ['\u{105b9}', '\u{0}', '\u{0}']), + ('\u{10594}', ['\u{105bb}', '\u{0}', '\u{0}']), + ('\u{10595}', ['\u{105bc}', '\u{0}', '\u{0}']), + ('\u{10c80}', ['\u{10cc0}', '\u{0}', '\u{0}']), + ('\u{10c81}', ['\u{10cc1}', '\u{0}', '\u{0}']), + ('\u{10c82}', ['\u{10cc2}', '\u{0}', '\u{0}']), + ('\u{10c83}', ['\u{10cc3}', '\u{0}', '\u{0}']), + ('\u{10c84}', ['\u{10cc4}', '\u{0}', '\u{0}']), + ('\u{10c85}', ['\u{10cc5}', '\u{0}', '\u{0}']), + ('\u{10c86}', ['\u{10cc6}', '\u{0}', '\u{0}']), + ('\u{10c87}', ['\u{10cc7}', '\u{0}', '\u{0}']), + ('\u{10c88}', ['\u{10cc8}', '\u{0}', '\u{0}']), + ('\u{10c89}', ['\u{10cc9}', '\u{0}', '\u{0}']), + ('\u{10c8a}', ['\u{10cca}', '\u{0}', '\u{0}']), + ('\u{10c8b}', ['\u{10ccb}', '\u{0}', '\u{0}']), + ('\u{10c8c}', ['\u{10ccc}', '\u{0}', '\u{0}']), + ('\u{10c8d}', ['\u{10ccd}', '\u{0}', '\u{0}']), + ('\u{10c8e}', ['\u{10cce}', '\u{0}', '\u{0}']), + ('\u{10c8f}', ['\u{10ccf}', '\u{0}', '\u{0}']), + ('\u{10c90}', ['\u{10cd0}', '\u{0}', '\u{0}']), + ('\u{10c91}', ['\u{10cd1}', '\u{0}', '\u{0}']), + ('\u{10c92}', ['\u{10cd2}', '\u{0}', '\u{0}']), + ('\u{10c93}', ['\u{10cd3}', '\u{0}', '\u{0}']), + ('\u{10c94}', ['\u{10cd4}', '\u{0}', '\u{0}']), + ('\u{10c95}', ['\u{10cd5}', '\u{0}', '\u{0}']), + ('\u{10c96}', ['\u{10cd6}', '\u{0}', '\u{0}']), + ('\u{10c97}', ['\u{10cd7}', '\u{0}', '\u{0}']), + ('\u{10c98}', ['\u{10cd8}', '\u{0}', '\u{0}']), + ('\u{10c99}', ['\u{10cd9}', '\u{0}', '\u{0}']), + ('\u{10c9a}', ['\u{10cda}', '\u{0}', '\u{0}']), + ('\u{10c9b}', ['\u{10cdb}', '\u{0}', '\u{0}']), + ('\u{10c9c}', ['\u{10cdc}', '\u{0}', '\u{0}']), + ('\u{10c9d}', ['\u{10cdd}', '\u{0}', '\u{0}']), + ('\u{10c9e}', ['\u{10cde}', '\u{0}', '\u{0}']), + ('\u{10c9f}', ['\u{10cdf}', '\u{0}', '\u{0}']), + ('\u{10ca0}', ['\u{10ce0}', '\u{0}', '\u{0}']), + ('\u{10ca1}', ['\u{10ce1}', '\u{0}', '\u{0}']), + ('\u{10ca2}', ['\u{10ce2}', '\u{0}', '\u{0}']), + ('\u{10ca3}', ['\u{10ce3}', '\u{0}', '\u{0}']), + ('\u{10ca4}', ['\u{10ce4}', '\u{0}', '\u{0}']), + ('\u{10ca5}', ['\u{10ce5}', '\u{0}', '\u{0}']), + ('\u{10ca6}', ['\u{10ce6}', '\u{0}', '\u{0}']), + ('\u{10ca7}', ['\u{10ce7}', '\u{0}', '\u{0}']), + ('\u{10ca8}', ['\u{10ce8}', '\u{0}', '\u{0}']), + ('\u{10ca9}', ['\u{10ce9}', '\u{0}', '\u{0}']), + ('\u{10caa}', ['\u{10cea}', '\u{0}', '\u{0}']), + ('\u{10cab}', ['\u{10ceb}', '\u{0}', '\u{0}']), + ('\u{10cac}', ['\u{10cec}', '\u{0}', '\u{0}']), + ('\u{10cad}', ['\u{10ced}', '\u{0}', '\u{0}']), + ('\u{10cae}', ['\u{10cee}', '\u{0}', '\u{0}']), + ('\u{10caf}', ['\u{10cef}', '\u{0}', '\u{0}']), + ('\u{10cb0}', ['\u{10cf0}', '\u{0}', '\u{0}']), + ('\u{10cb1}', ['\u{10cf1}', '\u{0}', '\u{0}']), + ('\u{10cb2}', ['\u{10cf2}', '\u{0}', '\u{0}']), + ('\u{10d50}', ['\u{10d70}', '\u{0}', '\u{0}']), + ('\u{10d51}', ['\u{10d71}', '\u{0}', '\u{0}']), + ('\u{10d52}', ['\u{10d72}', '\u{0}', '\u{0}']), + ('\u{10d53}', ['\u{10d73}', '\u{0}', '\u{0}']), + ('\u{10d54}', ['\u{10d74}', '\u{0}', '\u{0}']), + ('\u{10d55}', ['\u{10d75}', '\u{0}', '\u{0}']), + ('\u{10d56}', ['\u{10d76}', '\u{0}', '\u{0}']), + ('\u{10d57}', ['\u{10d77}', '\u{0}', '\u{0}']), + ('\u{10d58}', ['\u{10d78}', '\u{0}', '\u{0}']), + ('\u{10d59}', ['\u{10d79}', '\u{0}', '\u{0}']), + ('\u{10d5a}', ['\u{10d7a}', '\u{0}', '\u{0}']), + ('\u{10d5b}', ['\u{10d7b}', '\u{0}', '\u{0}']), + ('\u{10d5c}', ['\u{10d7c}', '\u{0}', '\u{0}']), + ('\u{10d5d}', ['\u{10d7d}', '\u{0}', '\u{0}']), + ('\u{10d5e}', ['\u{10d7e}', '\u{0}', '\u{0}']), + ('\u{10d5f}', ['\u{10d7f}', '\u{0}', '\u{0}']), + ('\u{10d60}', ['\u{10d80}', '\u{0}', '\u{0}']), + ('\u{10d61}', ['\u{10d81}', '\u{0}', '\u{0}']), + ('\u{10d62}', ['\u{10d82}', '\u{0}', '\u{0}']), + ('\u{10d63}', ['\u{10d83}', '\u{0}', '\u{0}']), + ('\u{10d64}', ['\u{10d84}', '\u{0}', '\u{0}']), + ('\u{10d65}', ['\u{10d85}', '\u{0}', '\u{0}']), + ('\u{118a0}', ['\u{118c0}', '\u{0}', '\u{0}']), + ('\u{118a1}', ['\u{118c1}', '\u{0}', '\u{0}']), + ('\u{118a2}', ['\u{118c2}', '\u{0}', '\u{0}']), + ('\u{118a3}', ['\u{118c3}', '\u{0}', '\u{0}']), + ('\u{118a4}', ['\u{118c4}', '\u{0}', '\u{0}']), + ('\u{118a5}', ['\u{118c5}', '\u{0}', '\u{0}']), + ('\u{118a6}', ['\u{118c6}', '\u{0}', '\u{0}']), + ('\u{118a7}', ['\u{118c7}', '\u{0}', '\u{0}']), + ('\u{118a8}', ['\u{118c8}', '\u{0}', '\u{0}']), + ('\u{118a9}', ['\u{118c9}', '\u{0}', '\u{0}']), + ('\u{118aa}', ['\u{118ca}', '\u{0}', '\u{0}']), + ('\u{118ab}', ['\u{118cb}', '\u{0}', '\u{0}']), + ('\u{118ac}', ['\u{118cc}', '\u{0}', '\u{0}']), + ('\u{118ad}', ['\u{118cd}', '\u{0}', '\u{0}']), + ('\u{118ae}', ['\u{118ce}', '\u{0}', '\u{0}']), + ('\u{118af}', ['\u{118cf}', '\u{0}', '\u{0}']), + ('\u{118b0}', ['\u{118d0}', '\u{0}', '\u{0}']), + ('\u{118b1}', ['\u{118d1}', '\u{0}', '\u{0}']), + ('\u{118b2}', ['\u{118d2}', '\u{0}', '\u{0}']), + ('\u{118b3}', ['\u{118d3}', '\u{0}', '\u{0}']), + ('\u{118b4}', ['\u{118d4}', '\u{0}', '\u{0}']), + ('\u{118b5}', ['\u{118d5}', '\u{0}', '\u{0}']), + ('\u{118b6}', ['\u{118d6}', '\u{0}', '\u{0}']), + ('\u{118b7}', ['\u{118d7}', '\u{0}', '\u{0}']), + ('\u{118b8}', ['\u{118d8}', '\u{0}', '\u{0}']), + ('\u{118b9}', ['\u{118d9}', '\u{0}', '\u{0}']), + ('\u{118ba}', ['\u{118da}', '\u{0}', '\u{0}']), + ('\u{118bb}', ['\u{118db}', '\u{0}', '\u{0}']), + ('\u{118bc}', ['\u{118dc}', '\u{0}', '\u{0}']), + ('\u{118bd}', ['\u{118dd}', '\u{0}', '\u{0}']), + ('\u{118be}', ['\u{118de}', '\u{0}', '\u{0}']), + ('\u{118bf}', ['\u{118df}', '\u{0}', '\u{0}']), + ('\u{16e40}', ['\u{16e60}', '\u{0}', '\u{0}']), + ('\u{16e41}', ['\u{16e61}', '\u{0}', '\u{0}']), + ('\u{16e42}', ['\u{16e62}', '\u{0}', '\u{0}']), + ('\u{16e43}', ['\u{16e63}', '\u{0}', '\u{0}']), + ('\u{16e44}', ['\u{16e64}', '\u{0}', '\u{0}']), + ('\u{16e45}', ['\u{16e65}', '\u{0}', '\u{0}']), + ('\u{16e46}', ['\u{16e66}', '\u{0}', '\u{0}']), + ('\u{16e47}', ['\u{16e67}', '\u{0}', '\u{0}']), + ('\u{16e48}', ['\u{16e68}', '\u{0}', '\u{0}']), + ('\u{16e49}', ['\u{16e69}', '\u{0}', '\u{0}']), + ('\u{16e4a}', ['\u{16e6a}', '\u{0}', '\u{0}']), + ('\u{16e4b}', ['\u{16e6b}', '\u{0}', '\u{0}']), + ('\u{16e4c}', ['\u{16e6c}', '\u{0}', '\u{0}']), + ('\u{16e4d}', ['\u{16e6d}', '\u{0}', '\u{0}']), + ('\u{16e4e}', ['\u{16e6e}', '\u{0}', '\u{0}']), + ('\u{16e4f}', ['\u{16e6f}', '\u{0}', '\u{0}']), + ('\u{16e50}', ['\u{16e70}', '\u{0}', '\u{0}']), + ('\u{16e51}', ['\u{16e71}', '\u{0}', '\u{0}']), + ('\u{16e52}', ['\u{16e72}', '\u{0}', '\u{0}']), + ('\u{16e53}', ['\u{16e73}', '\u{0}', '\u{0}']), + ('\u{16e54}', ['\u{16e74}', '\u{0}', '\u{0}']), + ('\u{16e55}', ['\u{16e75}', '\u{0}', '\u{0}']), + ('\u{16e56}', ['\u{16e76}', '\u{0}', '\u{0}']), + ('\u{16e57}', ['\u{16e77}', '\u{0}', '\u{0}']), + ('\u{16e58}', ['\u{16e78}', '\u{0}', '\u{0}']), + ('\u{16e59}', ['\u{16e79}', '\u{0}', '\u{0}']), + ('\u{16e5a}', ['\u{16e7a}', '\u{0}', '\u{0}']), + ('\u{16e5b}', ['\u{16e7b}', '\u{0}', '\u{0}']), + ('\u{16e5c}', ['\u{16e7c}', '\u{0}', '\u{0}']), + ('\u{16e5d}', ['\u{16e7d}', '\u{0}', '\u{0}']), + ('\u{16e5e}', ['\u{16e7e}', '\u{0}', '\u{0}']), + ('\u{16e5f}', ['\u{16e7f}', '\u{0}', '\u{0}']), + ('\u{16ea0}', ['\u{16ebb}', '\u{0}', '\u{0}']), + ('\u{16ea1}', ['\u{16ebc}', '\u{0}', '\u{0}']), + ('\u{16ea2}', ['\u{16ebd}', '\u{0}', '\u{0}']), + ('\u{16ea3}', ['\u{16ebe}', '\u{0}', '\u{0}']), + ('\u{16ea4}', ['\u{16ebf}', '\u{0}', '\u{0}']), + ('\u{16ea5}', ['\u{16ec0}', '\u{0}', '\u{0}']), + ('\u{16ea6}', ['\u{16ec1}', '\u{0}', '\u{0}']), + ('\u{16ea7}', ['\u{16ec2}', '\u{0}', '\u{0}']), + ('\u{16ea8}', ['\u{16ec3}', '\u{0}', '\u{0}']), + ('\u{16ea9}', ['\u{16ec4}', '\u{0}', '\u{0}']), + ('\u{16eaa}', ['\u{16ec5}', '\u{0}', '\u{0}']), + ('\u{16eab}', ['\u{16ec6}', '\u{0}', '\u{0}']), + ('\u{16eac}', ['\u{16ec7}', '\u{0}', '\u{0}']), + ('\u{16ead}', ['\u{16ec8}', '\u{0}', '\u{0}']), + ('\u{16eae}', ['\u{16ec9}', '\u{0}', '\u{0}']), + ('\u{16eaf}', ['\u{16eca}', '\u{0}', '\u{0}']), + ('\u{16eb0}', ['\u{16ecb}', '\u{0}', '\u{0}']), + ('\u{16eb1}', ['\u{16ecc}', '\u{0}', '\u{0}']), + ('\u{16eb2}', ['\u{16ecd}', '\u{0}', '\u{0}']), + ('\u{16eb3}', ['\u{16ece}', '\u{0}', '\u{0}']), + ('\u{16eb4}', ['\u{16ecf}', '\u{0}', '\u{0}']), + ('\u{16eb5}', ['\u{16ed0}', '\u{0}', '\u{0}']), + ('\u{16eb6}', ['\u{16ed1}', '\u{0}', '\u{0}']), + ('\u{16eb7}', ['\u{16ed2}', '\u{0}', '\u{0}']), + ('\u{16eb8}', ['\u{16ed3}', '\u{0}', '\u{0}']), + ('\u{1e900}', ['\u{1e922}', '\u{0}', '\u{0}']), + ('\u{1e901}', ['\u{1e923}', '\u{0}', '\u{0}']), + ('\u{1e902}', ['\u{1e924}', '\u{0}', '\u{0}']), + ('\u{1e903}', ['\u{1e925}', '\u{0}', '\u{0}']), + ('\u{1e904}', ['\u{1e926}', '\u{0}', '\u{0}']), + ('\u{1e905}', ['\u{1e927}', '\u{0}', '\u{0}']), + ('\u{1e906}', ['\u{1e928}', '\u{0}', '\u{0}']), + ('\u{1e907}', ['\u{1e929}', '\u{0}', '\u{0}']), + ('\u{1e908}', ['\u{1e92a}', '\u{0}', '\u{0}']), + ('\u{1e909}', ['\u{1e92b}', '\u{0}', '\u{0}']), + ('\u{1e90a}', ['\u{1e92c}', '\u{0}', '\u{0}']), + ('\u{1e90b}', ['\u{1e92d}', '\u{0}', '\u{0}']), + ('\u{1e90c}', ['\u{1e92e}', '\u{0}', '\u{0}']), + ('\u{1e90d}', ['\u{1e92f}', '\u{0}', '\u{0}']), + ('\u{1e90e}', ['\u{1e930}', '\u{0}', '\u{0}']), + ('\u{1e90f}', ['\u{1e931}', '\u{0}', '\u{0}']), + ('\u{1e910}', ['\u{1e932}', '\u{0}', '\u{0}']), + ('\u{1e911}', ['\u{1e933}', '\u{0}', '\u{0}']), + ('\u{1e912}', ['\u{1e934}', '\u{0}', '\u{0}']), + ('\u{1e913}', ['\u{1e935}', '\u{0}', '\u{0}']), + ('\u{1e914}', ['\u{1e936}', '\u{0}', '\u{0}']), + ('\u{1e915}', ['\u{1e937}', '\u{0}', '\u{0}']), + ('\u{1e916}', ['\u{1e938}', '\u{0}', '\u{0}']), + ('\u{1e917}', ['\u{1e939}', '\u{0}', '\u{0}']), + ('\u{1e918}', ['\u{1e93a}', '\u{0}', '\u{0}']), + ('\u{1e919}', ['\u{1e93b}', '\u{0}', '\u{0}']), + ('\u{1e91a}', ['\u{1e93c}', '\u{0}', '\u{0}']), + ('\u{1e91b}', ['\u{1e93d}', '\u{0}', '\u{0}']), + ('\u{1e91c}', ['\u{1e93e}', '\u{0}', '\u{0}']), + ('\u{1e91d}', ['\u{1e93f}', '\u{0}', '\u{0}']), + ('\u{1e91e}', ['\u{1e940}', '\u{0}', '\u{0}']), + ('\u{1e91f}', ['\u{1e941}', '\u{0}', '\u{0}']), + ('\u{1e920}', ['\u{1e942}', '\u{0}', '\u{0}']), + ('\u{1e921}', ['\u{1e943}', '\u{0}', '\u{0}']), +]; + +#[rustfmt::skip] +pub(super) static TO_UPPER: &[(char, [char; 3]); 1580] = &[ + ('\u{61}', ['\u{41}', '\u{0}', '\u{0}']), ('\u{62}', ['\u{42}', '\u{0}', '\u{0}']), + ('\u{63}', ['\u{43}', '\u{0}', '\u{0}']), ('\u{64}', ['\u{44}', '\u{0}', '\u{0}']), + ('\u{65}', ['\u{45}', '\u{0}', '\u{0}']), ('\u{66}', ['\u{46}', '\u{0}', '\u{0}']), + ('\u{67}', ['\u{47}', '\u{0}', '\u{0}']), ('\u{68}', ['\u{48}', '\u{0}', '\u{0}']), + ('\u{69}', ['\u{49}', '\u{0}', '\u{0}']), ('\u{6a}', ['\u{4a}', '\u{0}', '\u{0}']), + ('\u{6b}', ['\u{4b}', '\u{0}', '\u{0}']), ('\u{6c}', ['\u{4c}', '\u{0}', '\u{0}']), + ('\u{6d}', ['\u{4d}', '\u{0}', '\u{0}']), ('\u{6e}', ['\u{4e}', '\u{0}', '\u{0}']), + ('\u{6f}', ['\u{4f}', '\u{0}', '\u{0}']), ('\u{70}', ['\u{50}', '\u{0}', '\u{0}']), + ('\u{71}', ['\u{51}', '\u{0}', '\u{0}']), ('\u{72}', ['\u{52}', '\u{0}', '\u{0}']), + ('\u{73}', ['\u{53}', '\u{0}', '\u{0}']), ('\u{74}', ['\u{54}', '\u{0}', '\u{0}']), + ('\u{75}', ['\u{55}', '\u{0}', '\u{0}']), ('\u{76}', ['\u{56}', '\u{0}', '\u{0}']), + ('\u{77}', ['\u{57}', '\u{0}', '\u{0}']), ('\u{78}', ['\u{58}', '\u{0}', '\u{0}']), + ('\u{79}', ['\u{59}', '\u{0}', '\u{0}']), ('\u{7a}', ['\u{5a}', '\u{0}', '\u{0}']), + ('\u{b5}', ['\u{39c}', '\u{0}', '\u{0}']), ('\u{df}', ['\u{53}', '\u{53}', '\u{0}']), + ('\u{e0}', ['\u{c0}', '\u{0}', '\u{0}']), ('\u{e1}', ['\u{c1}', '\u{0}', '\u{0}']), + ('\u{e2}', ['\u{c2}', '\u{0}', '\u{0}']), ('\u{e3}', ['\u{c3}', '\u{0}', '\u{0}']), + ('\u{e4}', ['\u{c4}', '\u{0}', '\u{0}']), ('\u{e5}', ['\u{c5}', '\u{0}', '\u{0}']), + ('\u{e6}', ['\u{c6}', '\u{0}', '\u{0}']), ('\u{e7}', ['\u{c7}', '\u{0}', '\u{0}']), + ('\u{e8}', ['\u{c8}', '\u{0}', '\u{0}']), ('\u{e9}', ['\u{c9}', '\u{0}', '\u{0}']), + ('\u{ea}', ['\u{ca}', '\u{0}', '\u{0}']), ('\u{eb}', ['\u{cb}', '\u{0}', '\u{0}']), + ('\u{ec}', ['\u{cc}', '\u{0}', '\u{0}']), ('\u{ed}', ['\u{cd}', '\u{0}', '\u{0}']), + ('\u{ee}', ['\u{ce}', '\u{0}', '\u{0}']), ('\u{ef}', ['\u{cf}', '\u{0}', '\u{0}']), + ('\u{f0}', ['\u{d0}', '\u{0}', '\u{0}']), ('\u{f1}', ['\u{d1}', '\u{0}', '\u{0}']), + ('\u{f2}', ['\u{d2}', '\u{0}', '\u{0}']), ('\u{f3}', ['\u{d3}', '\u{0}', '\u{0}']), + ('\u{f4}', ['\u{d4}', '\u{0}', '\u{0}']), ('\u{f5}', ['\u{d5}', '\u{0}', '\u{0}']), + ('\u{f6}', ['\u{d6}', '\u{0}', '\u{0}']), ('\u{f8}', ['\u{d8}', '\u{0}', '\u{0}']), + ('\u{f9}', ['\u{d9}', '\u{0}', '\u{0}']), ('\u{fa}', ['\u{da}', '\u{0}', '\u{0}']), + ('\u{fb}', ['\u{db}', '\u{0}', '\u{0}']), ('\u{fc}', ['\u{dc}', '\u{0}', '\u{0}']), + ('\u{fd}', ['\u{dd}', '\u{0}', '\u{0}']), ('\u{fe}', ['\u{de}', '\u{0}', '\u{0}']), + ('\u{ff}', ['\u{178}', '\u{0}', '\u{0}']), ('\u{101}', ['\u{100}', '\u{0}', '\u{0}']), + ('\u{103}', ['\u{102}', '\u{0}', '\u{0}']), ('\u{105}', ['\u{104}', '\u{0}', '\u{0}']), + ('\u{107}', ['\u{106}', '\u{0}', '\u{0}']), ('\u{109}', ['\u{108}', '\u{0}', '\u{0}']), + ('\u{10b}', ['\u{10a}', '\u{0}', '\u{0}']), ('\u{10d}', ['\u{10c}', '\u{0}', '\u{0}']), + ('\u{10f}', ['\u{10e}', '\u{0}', '\u{0}']), ('\u{111}', ['\u{110}', '\u{0}', '\u{0}']), + ('\u{113}', ['\u{112}', '\u{0}', '\u{0}']), ('\u{115}', ['\u{114}', '\u{0}', '\u{0}']), + ('\u{117}', ['\u{116}', '\u{0}', '\u{0}']), ('\u{119}', ['\u{118}', '\u{0}', '\u{0}']), + ('\u{11b}', ['\u{11a}', '\u{0}', '\u{0}']), ('\u{11d}', ['\u{11c}', '\u{0}', '\u{0}']), + ('\u{11f}', ['\u{11e}', '\u{0}', '\u{0}']), ('\u{121}', ['\u{120}', '\u{0}', '\u{0}']), + ('\u{123}', ['\u{122}', '\u{0}', '\u{0}']), ('\u{125}', ['\u{124}', '\u{0}', '\u{0}']), + ('\u{127}', ['\u{126}', '\u{0}', '\u{0}']), ('\u{129}', ['\u{128}', '\u{0}', '\u{0}']), + ('\u{12b}', ['\u{12a}', '\u{0}', '\u{0}']), ('\u{12d}', ['\u{12c}', '\u{0}', '\u{0}']), + ('\u{12f}', ['\u{12e}', '\u{0}', '\u{0}']), ('\u{131}', ['\u{49}', '\u{0}', '\u{0}']), + ('\u{133}', ['\u{132}', '\u{0}', '\u{0}']), ('\u{135}', ['\u{134}', '\u{0}', '\u{0}']), + ('\u{137}', ['\u{136}', '\u{0}', '\u{0}']), ('\u{13a}', ['\u{139}', '\u{0}', '\u{0}']), + ('\u{13c}', ['\u{13b}', '\u{0}', '\u{0}']), ('\u{13e}', ['\u{13d}', '\u{0}', '\u{0}']), + ('\u{140}', ['\u{13f}', '\u{0}', '\u{0}']), ('\u{142}', ['\u{141}', '\u{0}', '\u{0}']), + ('\u{144}', ['\u{143}', '\u{0}', '\u{0}']), ('\u{146}', ['\u{145}', '\u{0}', '\u{0}']), + ('\u{148}', ['\u{147}', '\u{0}', '\u{0}']), ('\u{149}', ['\u{2bc}', '\u{4e}', '\u{0}']), + ('\u{14b}', ['\u{14a}', '\u{0}', '\u{0}']), ('\u{14d}', ['\u{14c}', '\u{0}', '\u{0}']), + ('\u{14f}', ['\u{14e}', '\u{0}', '\u{0}']), ('\u{151}', ['\u{150}', '\u{0}', '\u{0}']), + ('\u{153}', ['\u{152}', '\u{0}', '\u{0}']), ('\u{155}', ['\u{154}', '\u{0}', '\u{0}']), + ('\u{157}', ['\u{156}', '\u{0}', '\u{0}']), ('\u{159}', ['\u{158}', '\u{0}', '\u{0}']), + ('\u{15b}', ['\u{15a}', '\u{0}', '\u{0}']), ('\u{15d}', ['\u{15c}', '\u{0}', '\u{0}']), + ('\u{15f}', ['\u{15e}', '\u{0}', '\u{0}']), ('\u{161}', ['\u{160}', '\u{0}', '\u{0}']), + ('\u{163}', ['\u{162}', '\u{0}', '\u{0}']), ('\u{165}', ['\u{164}', '\u{0}', '\u{0}']), + ('\u{167}', ['\u{166}', '\u{0}', '\u{0}']), ('\u{169}', ['\u{168}', '\u{0}', '\u{0}']), + ('\u{16b}', ['\u{16a}', '\u{0}', '\u{0}']), ('\u{16d}', ['\u{16c}', '\u{0}', '\u{0}']), + ('\u{16f}', ['\u{16e}', '\u{0}', '\u{0}']), ('\u{171}', ['\u{170}', '\u{0}', '\u{0}']), + ('\u{173}', ['\u{172}', '\u{0}', '\u{0}']), ('\u{175}', ['\u{174}', '\u{0}', '\u{0}']), + ('\u{177}', ['\u{176}', '\u{0}', '\u{0}']), ('\u{17a}', ['\u{179}', '\u{0}', '\u{0}']), + ('\u{17c}', ['\u{17b}', '\u{0}', '\u{0}']), ('\u{17e}', ['\u{17d}', '\u{0}', '\u{0}']), + ('\u{17f}', ['\u{53}', '\u{0}', '\u{0}']), ('\u{180}', ['\u{243}', '\u{0}', '\u{0}']), + ('\u{183}', ['\u{182}', '\u{0}', '\u{0}']), ('\u{185}', ['\u{184}', '\u{0}', '\u{0}']), + ('\u{188}', ['\u{187}', '\u{0}', '\u{0}']), ('\u{18c}', ['\u{18b}', '\u{0}', '\u{0}']), + ('\u{192}', ['\u{191}', '\u{0}', '\u{0}']), ('\u{195}', ['\u{1f6}', '\u{0}', '\u{0}']), + ('\u{199}', ['\u{198}', '\u{0}', '\u{0}']), ('\u{19a}', ['\u{23d}', '\u{0}', '\u{0}']), + ('\u{19b}', ['\u{a7dc}', '\u{0}', '\u{0}']), ('\u{19e}', ['\u{220}', '\u{0}', '\u{0}']), + ('\u{1a1}', ['\u{1a0}', '\u{0}', '\u{0}']), ('\u{1a3}', ['\u{1a2}', '\u{0}', '\u{0}']), + ('\u{1a5}', ['\u{1a4}', '\u{0}', '\u{0}']), ('\u{1a8}', ['\u{1a7}', '\u{0}', '\u{0}']), + ('\u{1ad}', ['\u{1ac}', '\u{0}', '\u{0}']), ('\u{1b0}', ['\u{1af}', '\u{0}', '\u{0}']), + ('\u{1b4}', ['\u{1b3}', '\u{0}', '\u{0}']), ('\u{1b6}', ['\u{1b5}', '\u{0}', '\u{0}']), + ('\u{1b9}', ['\u{1b8}', '\u{0}', '\u{0}']), ('\u{1bd}', ['\u{1bc}', '\u{0}', '\u{0}']), + ('\u{1bf}', ['\u{1f7}', '\u{0}', '\u{0}']), ('\u{1c5}', ['\u{1c4}', '\u{0}', '\u{0}']), + ('\u{1c6}', ['\u{1c4}', '\u{0}', '\u{0}']), ('\u{1c8}', ['\u{1c7}', '\u{0}', '\u{0}']), + ('\u{1c9}', ['\u{1c7}', '\u{0}', '\u{0}']), ('\u{1cb}', ['\u{1ca}', '\u{0}', '\u{0}']), + ('\u{1cc}', ['\u{1ca}', '\u{0}', '\u{0}']), ('\u{1ce}', ['\u{1cd}', '\u{0}', '\u{0}']), + ('\u{1d0}', ['\u{1cf}', '\u{0}', '\u{0}']), ('\u{1d2}', ['\u{1d1}', '\u{0}', '\u{0}']), + ('\u{1d4}', ['\u{1d3}', '\u{0}', '\u{0}']), ('\u{1d6}', ['\u{1d5}', '\u{0}', '\u{0}']), + ('\u{1d8}', ['\u{1d7}', '\u{0}', '\u{0}']), ('\u{1da}', ['\u{1d9}', '\u{0}', '\u{0}']), + ('\u{1dc}', ['\u{1db}', '\u{0}', '\u{0}']), ('\u{1dd}', ['\u{18e}', '\u{0}', '\u{0}']), + ('\u{1df}', ['\u{1de}', '\u{0}', '\u{0}']), ('\u{1e1}', ['\u{1e0}', '\u{0}', '\u{0}']), + ('\u{1e3}', ['\u{1e2}', '\u{0}', '\u{0}']), ('\u{1e5}', ['\u{1e4}', '\u{0}', '\u{0}']), + ('\u{1e7}', ['\u{1e6}', '\u{0}', '\u{0}']), ('\u{1e9}', ['\u{1e8}', '\u{0}', '\u{0}']), + ('\u{1eb}', ['\u{1ea}', '\u{0}', '\u{0}']), ('\u{1ed}', ['\u{1ec}', '\u{0}', '\u{0}']), + ('\u{1ef}', ['\u{1ee}', '\u{0}', '\u{0}']), ('\u{1f0}', ['\u{4a}', '\u{30c}', '\u{0}']), + ('\u{1f2}', ['\u{1f1}', '\u{0}', '\u{0}']), ('\u{1f3}', ['\u{1f1}', '\u{0}', '\u{0}']), + ('\u{1f5}', ['\u{1f4}', '\u{0}', '\u{0}']), ('\u{1f9}', ['\u{1f8}', '\u{0}', '\u{0}']), + ('\u{1fb}', ['\u{1fa}', '\u{0}', '\u{0}']), ('\u{1fd}', ['\u{1fc}', '\u{0}', '\u{0}']), + ('\u{1ff}', ['\u{1fe}', '\u{0}', '\u{0}']), ('\u{201}', ['\u{200}', '\u{0}', '\u{0}']), + ('\u{203}', ['\u{202}', '\u{0}', '\u{0}']), ('\u{205}', ['\u{204}', '\u{0}', '\u{0}']), + ('\u{207}', ['\u{206}', '\u{0}', '\u{0}']), ('\u{209}', ['\u{208}', '\u{0}', '\u{0}']), + ('\u{20b}', ['\u{20a}', '\u{0}', '\u{0}']), ('\u{20d}', ['\u{20c}', '\u{0}', '\u{0}']), + ('\u{20f}', ['\u{20e}', '\u{0}', '\u{0}']), ('\u{211}', ['\u{210}', '\u{0}', '\u{0}']), + ('\u{213}', ['\u{212}', '\u{0}', '\u{0}']), ('\u{215}', ['\u{214}', '\u{0}', '\u{0}']), + ('\u{217}', ['\u{216}', '\u{0}', '\u{0}']), ('\u{219}', ['\u{218}', '\u{0}', '\u{0}']), + ('\u{21b}', ['\u{21a}', '\u{0}', '\u{0}']), ('\u{21d}', ['\u{21c}', '\u{0}', '\u{0}']), + ('\u{21f}', ['\u{21e}', '\u{0}', '\u{0}']), ('\u{223}', ['\u{222}', '\u{0}', '\u{0}']), + ('\u{225}', ['\u{224}', '\u{0}', '\u{0}']), ('\u{227}', ['\u{226}', '\u{0}', '\u{0}']), + ('\u{229}', ['\u{228}', '\u{0}', '\u{0}']), ('\u{22b}', ['\u{22a}', '\u{0}', '\u{0}']), + ('\u{22d}', ['\u{22c}', '\u{0}', '\u{0}']), ('\u{22f}', ['\u{22e}', '\u{0}', '\u{0}']), + ('\u{231}', ['\u{230}', '\u{0}', '\u{0}']), ('\u{233}', ['\u{232}', '\u{0}', '\u{0}']), + ('\u{23c}', ['\u{23b}', '\u{0}', '\u{0}']), ('\u{23f}', ['\u{2c7e}', '\u{0}', '\u{0}']), + ('\u{240}', ['\u{2c7f}', '\u{0}', '\u{0}']), ('\u{242}', ['\u{241}', '\u{0}', '\u{0}']), + ('\u{247}', ['\u{246}', '\u{0}', '\u{0}']), ('\u{249}', ['\u{248}', '\u{0}', '\u{0}']), + ('\u{24b}', ['\u{24a}', '\u{0}', '\u{0}']), ('\u{24d}', ['\u{24c}', '\u{0}', '\u{0}']), + ('\u{24f}', ['\u{24e}', '\u{0}', '\u{0}']), ('\u{250}', ['\u{2c6f}', '\u{0}', '\u{0}']), + ('\u{251}', ['\u{2c6d}', '\u{0}', '\u{0}']), ('\u{252}', ['\u{2c70}', '\u{0}', '\u{0}']), + ('\u{253}', ['\u{181}', '\u{0}', '\u{0}']), ('\u{254}', ['\u{186}', '\u{0}', '\u{0}']), + ('\u{256}', ['\u{189}', '\u{0}', '\u{0}']), ('\u{257}', ['\u{18a}', '\u{0}', '\u{0}']), + ('\u{259}', ['\u{18f}', '\u{0}', '\u{0}']), ('\u{25b}', ['\u{190}', '\u{0}', '\u{0}']), + ('\u{25c}', ['\u{a7ab}', '\u{0}', '\u{0}']), ('\u{260}', ['\u{193}', '\u{0}', '\u{0}']), + ('\u{261}', ['\u{a7ac}', '\u{0}', '\u{0}']), ('\u{263}', ['\u{194}', '\u{0}', '\u{0}']), + ('\u{264}', ['\u{a7cb}', '\u{0}', '\u{0}']), ('\u{265}', ['\u{a78d}', '\u{0}', '\u{0}']), + ('\u{266}', ['\u{a7aa}', '\u{0}', '\u{0}']), ('\u{268}', ['\u{197}', '\u{0}', '\u{0}']), + ('\u{269}', ['\u{196}', '\u{0}', '\u{0}']), ('\u{26a}', ['\u{a7ae}', '\u{0}', '\u{0}']), + ('\u{26b}', ['\u{2c62}', '\u{0}', '\u{0}']), ('\u{26c}', ['\u{a7ad}', '\u{0}', '\u{0}']), + ('\u{26f}', ['\u{19c}', '\u{0}', '\u{0}']), ('\u{271}', ['\u{2c6e}', '\u{0}', '\u{0}']), + ('\u{272}', ['\u{19d}', '\u{0}', '\u{0}']), ('\u{275}', ['\u{19f}', '\u{0}', '\u{0}']), + ('\u{27d}', ['\u{2c64}', '\u{0}', '\u{0}']), ('\u{280}', ['\u{1a6}', '\u{0}', '\u{0}']), + ('\u{282}', ['\u{a7c5}', '\u{0}', '\u{0}']), ('\u{283}', ['\u{1a9}', '\u{0}', '\u{0}']), + ('\u{287}', ['\u{a7b1}', '\u{0}', '\u{0}']), ('\u{288}', ['\u{1ae}', '\u{0}', '\u{0}']), + ('\u{289}', ['\u{244}', '\u{0}', '\u{0}']), ('\u{28a}', ['\u{1b1}', '\u{0}', '\u{0}']), + ('\u{28b}', ['\u{1b2}', '\u{0}', '\u{0}']), ('\u{28c}', ['\u{245}', '\u{0}', '\u{0}']), + ('\u{292}', ['\u{1b7}', '\u{0}', '\u{0}']), ('\u{29d}', ['\u{a7b2}', '\u{0}', '\u{0}']), + ('\u{29e}', ['\u{a7b0}', '\u{0}', '\u{0}']), ('\u{345}', ['\u{399}', '\u{0}', '\u{0}']), + ('\u{371}', ['\u{370}', '\u{0}', '\u{0}']), ('\u{373}', ['\u{372}', '\u{0}', '\u{0}']), + ('\u{377}', ['\u{376}', '\u{0}', '\u{0}']), ('\u{37b}', ['\u{3fd}', '\u{0}', '\u{0}']), + ('\u{37c}', ['\u{3fe}', '\u{0}', '\u{0}']), ('\u{37d}', ['\u{3ff}', '\u{0}', '\u{0}']), + ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}', ['\u{386}', '\u{0}', '\u{0}']), + ('\u{3ad}', ['\u{388}', '\u{0}', '\u{0}']), ('\u{3ae}', ['\u{389}', '\u{0}', '\u{0}']), + ('\u{3af}', ['\u{38a}', '\u{0}', '\u{0}']), ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), + ('\u{3b1}', ['\u{391}', '\u{0}', '\u{0}']), ('\u{3b2}', ['\u{392}', '\u{0}', '\u{0}']), + ('\u{3b3}', ['\u{393}', '\u{0}', '\u{0}']), ('\u{3b4}', ['\u{394}', '\u{0}', '\u{0}']), + ('\u{3b5}', ['\u{395}', '\u{0}', '\u{0}']), ('\u{3b6}', ['\u{396}', '\u{0}', '\u{0}']), + ('\u{3b7}', ['\u{397}', '\u{0}', '\u{0}']), ('\u{3b8}', ['\u{398}', '\u{0}', '\u{0}']), + ('\u{3b9}', ['\u{399}', '\u{0}', '\u{0}']), ('\u{3ba}', ['\u{39a}', '\u{0}', '\u{0}']), + ('\u{3bb}', ['\u{39b}', '\u{0}', '\u{0}']), ('\u{3bc}', ['\u{39c}', '\u{0}', '\u{0}']), + ('\u{3bd}', ['\u{39d}', '\u{0}', '\u{0}']), ('\u{3be}', ['\u{39e}', '\u{0}', '\u{0}']), + ('\u{3bf}', ['\u{39f}', '\u{0}', '\u{0}']), ('\u{3c0}', ['\u{3a0}', '\u{0}', '\u{0}']), + ('\u{3c1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3c2}', ['\u{3a3}', '\u{0}', '\u{0}']), + ('\u{3c3}', ['\u{3a3}', '\u{0}', '\u{0}']), ('\u{3c4}', ['\u{3a4}', '\u{0}', '\u{0}']), + ('\u{3c5}', ['\u{3a5}', '\u{0}', '\u{0}']), ('\u{3c6}', ['\u{3a6}', '\u{0}', '\u{0}']), + ('\u{3c7}', ['\u{3a7}', '\u{0}', '\u{0}']), ('\u{3c8}', ['\u{3a8}', '\u{0}', '\u{0}']), + ('\u{3c9}', ['\u{3a9}', '\u{0}', '\u{0}']), ('\u{3ca}', ['\u{3aa}', '\u{0}', '\u{0}']), + ('\u{3cb}', ['\u{3ab}', '\u{0}', '\u{0}']), ('\u{3cc}', ['\u{38c}', '\u{0}', '\u{0}']), + ('\u{3cd}', ['\u{38e}', '\u{0}', '\u{0}']), ('\u{3ce}', ['\u{38f}', '\u{0}', '\u{0}']), + ('\u{3d0}', ['\u{392}', '\u{0}', '\u{0}']), ('\u{3d1}', ['\u{398}', '\u{0}', '\u{0}']), + ('\u{3d5}', ['\u{3a6}', '\u{0}', '\u{0}']), ('\u{3d6}', ['\u{3a0}', '\u{0}', '\u{0}']), + ('\u{3d7}', ['\u{3cf}', '\u{0}', '\u{0}']), ('\u{3d9}', ['\u{3d8}', '\u{0}', '\u{0}']), + ('\u{3db}', ['\u{3da}', '\u{0}', '\u{0}']), ('\u{3dd}', ['\u{3dc}', '\u{0}', '\u{0}']), + ('\u{3df}', ['\u{3de}', '\u{0}', '\u{0}']), ('\u{3e1}', ['\u{3e0}', '\u{0}', '\u{0}']), + ('\u{3e3}', ['\u{3e2}', '\u{0}', '\u{0}']), ('\u{3e5}', ['\u{3e4}', '\u{0}', '\u{0}']), + ('\u{3e7}', ['\u{3e6}', '\u{0}', '\u{0}']), ('\u{3e9}', ['\u{3e8}', '\u{0}', '\u{0}']), + ('\u{3eb}', ['\u{3ea}', '\u{0}', '\u{0}']), ('\u{3ed}', ['\u{3ec}', '\u{0}', '\u{0}']), + ('\u{3ef}', ['\u{3ee}', '\u{0}', '\u{0}']), ('\u{3f0}', ['\u{39a}', '\u{0}', '\u{0}']), + ('\u{3f1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3f2}', ['\u{3f9}', '\u{0}', '\u{0}']), + ('\u{3f3}', ['\u{37f}', '\u{0}', '\u{0}']), ('\u{3f5}', ['\u{395}', '\u{0}', '\u{0}']), + ('\u{3f8}', ['\u{3f7}', '\u{0}', '\u{0}']), ('\u{3fb}', ['\u{3fa}', '\u{0}', '\u{0}']), + ('\u{430}', ['\u{410}', '\u{0}', '\u{0}']), ('\u{431}', ['\u{411}', '\u{0}', '\u{0}']), + ('\u{432}', ['\u{412}', '\u{0}', '\u{0}']), ('\u{433}', ['\u{413}', '\u{0}', '\u{0}']), + ('\u{434}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{435}', ['\u{415}', '\u{0}', '\u{0}']), + ('\u{436}', ['\u{416}', '\u{0}', '\u{0}']), ('\u{437}', ['\u{417}', '\u{0}', '\u{0}']), + ('\u{438}', ['\u{418}', '\u{0}', '\u{0}']), ('\u{439}', ['\u{419}', '\u{0}', '\u{0}']), + ('\u{43a}', ['\u{41a}', '\u{0}', '\u{0}']), ('\u{43b}', ['\u{41b}', '\u{0}', '\u{0}']), + ('\u{43c}', ['\u{41c}', '\u{0}', '\u{0}']), ('\u{43d}', ['\u{41d}', '\u{0}', '\u{0}']), + ('\u{43e}', ['\u{41e}', '\u{0}', '\u{0}']), ('\u{43f}', ['\u{41f}', '\u{0}', '\u{0}']), + ('\u{440}', ['\u{420}', '\u{0}', '\u{0}']), ('\u{441}', ['\u{421}', '\u{0}', '\u{0}']), + ('\u{442}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{443}', ['\u{423}', '\u{0}', '\u{0}']), + ('\u{444}', ['\u{424}', '\u{0}', '\u{0}']), ('\u{445}', ['\u{425}', '\u{0}', '\u{0}']), + ('\u{446}', ['\u{426}', '\u{0}', '\u{0}']), ('\u{447}', ['\u{427}', '\u{0}', '\u{0}']), + ('\u{448}', ['\u{428}', '\u{0}', '\u{0}']), ('\u{449}', ['\u{429}', '\u{0}', '\u{0}']), + ('\u{44a}', ['\u{42a}', '\u{0}', '\u{0}']), ('\u{44b}', ['\u{42b}', '\u{0}', '\u{0}']), + ('\u{44c}', ['\u{42c}', '\u{0}', '\u{0}']), ('\u{44d}', ['\u{42d}', '\u{0}', '\u{0}']), + ('\u{44e}', ['\u{42e}', '\u{0}', '\u{0}']), ('\u{44f}', ['\u{42f}', '\u{0}', '\u{0}']), + ('\u{450}', ['\u{400}', '\u{0}', '\u{0}']), ('\u{451}', ['\u{401}', '\u{0}', '\u{0}']), + ('\u{452}', ['\u{402}', '\u{0}', '\u{0}']), ('\u{453}', ['\u{403}', '\u{0}', '\u{0}']), + ('\u{454}', ['\u{404}', '\u{0}', '\u{0}']), ('\u{455}', ['\u{405}', '\u{0}', '\u{0}']), + ('\u{456}', ['\u{406}', '\u{0}', '\u{0}']), ('\u{457}', ['\u{407}', '\u{0}', '\u{0}']), + ('\u{458}', ['\u{408}', '\u{0}', '\u{0}']), ('\u{459}', ['\u{409}', '\u{0}', '\u{0}']), + ('\u{45a}', ['\u{40a}', '\u{0}', '\u{0}']), ('\u{45b}', ['\u{40b}', '\u{0}', '\u{0}']), + ('\u{45c}', ['\u{40c}', '\u{0}', '\u{0}']), ('\u{45d}', ['\u{40d}', '\u{0}', '\u{0}']), + ('\u{45e}', ['\u{40e}', '\u{0}', '\u{0}']), ('\u{45f}', ['\u{40f}', '\u{0}', '\u{0}']), + ('\u{461}', ['\u{460}', '\u{0}', '\u{0}']), ('\u{463}', ['\u{462}', '\u{0}', '\u{0}']), + ('\u{465}', ['\u{464}', '\u{0}', '\u{0}']), ('\u{467}', ['\u{466}', '\u{0}', '\u{0}']), + ('\u{469}', ['\u{468}', '\u{0}', '\u{0}']), ('\u{46b}', ['\u{46a}', '\u{0}', '\u{0}']), + ('\u{46d}', ['\u{46c}', '\u{0}', '\u{0}']), ('\u{46f}', ['\u{46e}', '\u{0}', '\u{0}']), + ('\u{471}', ['\u{470}', '\u{0}', '\u{0}']), ('\u{473}', ['\u{472}', '\u{0}', '\u{0}']), + ('\u{475}', ['\u{474}', '\u{0}', '\u{0}']), ('\u{477}', ['\u{476}', '\u{0}', '\u{0}']), + ('\u{479}', ['\u{478}', '\u{0}', '\u{0}']), ('\u{47b}', ['\u{47a}', '\u{0}', '\u{0}']), + ('\u{47d}', ['\u{47c}', '\u{0}', '\u{0}']), ('\u{47f}', ['\u{47e}', '\u{0}', '\u{0}']), + ('\u{481}', ['\u{480}', '\u{0}', '\u{0}']), ('\u{48b}', ['\u{48a}', '\u{0}', '\u{0}']), + ('\u{48d}', ['\u{48c}', '\u{0}', '\u{0}']), ('\u{48f}', ['\u{48e}', '\u{0}', '\u{0}']), + ('\u{491}', ['\u{490}', '\u{0}', '\u{0}']), ('\u{493}', ['\u{492}', '\u{0}', '\u{0}']), + ('\u{495}', ['\u{494}', '\u{0}', '\u{0}']), ('\u{497}', ['\u{496}', '\u{0}', '\u{0}']), + ('\u{499}', ['\u{498}', '\u{0}', '\u{0}']), ('\u{49b}', ['\u{49a}', '\u{0}', '\u{0}']), + ('\u{49d}', ['\u{49c}', '\u{0}', '\u{0}']), ('\u{49f}', ['\u{49e}', '\u{0}', '\u{0}']), + ('\u{4a1}', ['\u{4a0}', '\u{0}', '\u{0}']), ('\u{4a3}', ['\u{4a2}', '\u{0}', '\u{0}']), + ('\u{4a5}', ['\u{4a4}', '\u{0}', '\u{0}']), ('\u{4a7}', ['\u{4a6}', '\u{0}', '\u{0}']), + ('\u{4a9}', ['\u{4a8}', '\u{0}', '\u{0}']), ('\u{4ab}', ['\u{4aa}', '\u{0}', '\u{0}']), + ('\u{4ad}', ['\u{4ac}', '\u{0}', '\u{0}']), ('\u{4af}', ['\u{4ae}', '\u{0}', '\u{0}']), + ('\u{4b1}', ['\u{4b0}', '\u{0}', '\u{0}']), ('\u{4b3}', ['\u{4b2}', '\u{0}', '\u{0}']), + ('\u{4b5}', ['\u{4b4}', '\u{0}', '\u{0}']), ('\u{4b7}', ['\u{4b6}', '\u{0}', '\u{0}']), + ('\u{4b9}', ['\u{4b8}', '\u{0}', '\u{0}']), ('\u{4bb}', ['\u{4ba}', '\u{0}', '\u{0}']), + ('\u{4bd}', ['\u{4bc}', '\u{0}', '\u{0}']), ('\u{4bf}', ['\u{4be}', '\u{0}', '\u{0}']), + ('\u{4c2}', ['\u{4c1}', '\u{0}', '\u{0}']), ('\u{4c4}', ['\u{4c3}', '\u{0}', '\u{0}']), + ('\u{4c6}', ['\u{4c5}', '\u{0}', '\u{0}']), ('\u{4c8}', ['\u{4c7}', '\u{0}', '\u{0}']), + ('\u{4ca}', ['\u{4c9}', '\u{0}', '\u{0}']), ('\u{4cc}', ['\u{4cb}', '\u{0}', '\u{0}']), + ('\u{4ce}', ['\u{4cd}', '\u{0}', '\u{0}']), ('\u{4cf}', ['\u{4c0}', '\u{0}', '\u{0}']), + ('\u{4d1}', ['\u{4d0}', '\u{0}', '\u{0}']), ('\u{4d3}', ['\u{4d2}', '\u{0}', '\u{0}']), + ('\u{4d5}', ['\u{4d4}', '\u{0}', '\u{0}']), ('\u{4d7}', ['\u{4d6}', '\u{0}', '\u{0}']), + ('\u{4d9}', ['\u{4d8}', '\u{0}', '\u{0}']), ('\u{4db}', ['\u{4da}', '\u{0}', '\u{0}']), + ('\u{4dd}', ['\u{4dc}', '\u{0}', '\u{0}']), ('\u{4df}', ['\u{4de}', '\u{0}', '\u{0}']), + ('\u{4e1}', ['\u{4e0}', '\u{0}', '\u{0}']), ('\u{4e3}', ['\u{4e2}', '\u{0}', '\u{0}']), + ('\u{4e5}', ['\u{4e4}', '\u{0}', '\u{0}']), ('\u{4e7}', ['\u{4e6}', '\u{0}', '\u{0}']), + ('\u{4e9}', ['\u{4e8}', '\u{0}', '\u{0}']), ('\u{4eb}', ['\u{4ea}', '\u{0}', '\u{0}']), + ('\u{4ed}', ['\u{4ec}', '\u{0}', '\u{0}']), ('\u{4ef}', ['\u{4ee}', '\u{0}', '\u{0}']), + ('\u{4f1}', ['\u{4f0}', '\u{0}', '\u{0}']), ('\u{4f3}', ['\u{4f2}', '\u{0}', '\u{0}']), + ('\u{4f5}', ['\u{4f4}', '\u{0}', '\u{0}']), ('\u{4f7}', ['\u{4f6}', '\u{0}', '\u{0}']), + ('\u{4f9}', ['\u{4f8}', '\u{0}', '\u{0}']), ('\u{4fb}', ['\u{4fa}', '\u{0}', '\u{0}']), + ('\u{4fd}', ['\u{4fc}', '\u{0}', '\u{0}']), ('\u{4ff}', ['\u{4fe}', '\u{0}', '\u{0}']), + ('\u{501}', ['\u{500}', '\u{0}', '\u{0}']), ('\u{503}', ['\u{502}', '\u{0}', '\u{0}']), + ('\u{505}', ['\u{504}', '\u{0}', '\u{0}']), ('\u{507}', ['\u{506}', '\u{0}', '\u{0}']), + ('\u{509}', ['\u{508}', '\u{0}', '\u{0}']), ('\u{50b}', ['\u{50a}', '\u{0}', '\u{0}']), + ('\u{50d}', ['\u{50c}', '\u{0}', '\u{0}']), ('\u{50f}', ['\u{50e}', '\u{0}', '\u{0}']), + ('\u{511}', ['\u{510}', '\u{0}', '\u{0}']), ('\u{513}', ['\u{512}', '\u{0}', '\u{0}']), + ('\u{515}', ['\u{514}', '\u{0}', '\u{0}']), ('\u{517}', ['\u{516}', '\u{0}', '\u{0}']), + ('\u{519}', ['\u{518}', '\u{0}', '\u{0}']), ('\u{51b}', ['\u{51a}', '\u{0}', '\u{0}']), + ('\u{51d}', ['\u{51c}', '\u{0}', '\u{0}']), ('\u{51f}', ['\u{51e}', '\u{0}', '\u{0}']), + ('\u{521}', ['\u{520}', '\u{0}', '\u{0}']), ('\u{523}', ['\u{522}', '\u{0}', '\u{0}']), + ('\u{525}', ['\u{524}', '\u{0}', '\u{0}']), ('\u{527}', ['\u{526}', '\u{0}', '\u{0}']), + ('\u{529}', ['\u{528}', '\u{0}', '\u{0}']), ('\u{52b}', ['\u{52a}', '\u{0}', '\u{0}']), + ('\u{52d}', ['\u{52c}', '\u{0}', '\u{0}']), ('\u{52f}', ['\u{52e}', '\u{0}', '\u{0}']), + ('\u{561}', ['\u{531}', '\u{0}', '\u{0}']), ('\u{562}', ['\u{532}', '\u{0}', '\u{0}']), + ('\u{563}', ['\u{533}', '\u{0}', '\u{0}']), ('\u{564}', ['\u{534}', '\u{0}', '\u{0}']), + ('\u{565}', ['\u{535}', '\u{0}', '\u{0}']), ('\u{566}', ['\u{536}', '\u{0}', '\u{0}']), + ('\u{567}', ['\u{537}', '\u{0}', '\u{0}']), ('\u{568}', ['\u{538}', '\u{0}', '\u{0}']), + ('\u{569}', ['\u{539}', '\u{0}', '\u{0}']), ('\u{56a}', ['\u{53a}', '\u{0}', '\u{0}']), + ('\u{56b}', ['\u{53b}', '\u{0}', '\u{0}']), ('\u{56c}', ['\u{53c}', '\u{0}', '\u{0}']), + ('\u{56d}', ['\u{53d}', '\u{0}', '\u{0}']), ('\u{56e}', ['\u{53e}', '\u{0}', '\u{0}']), + ('\u{56f}', ['\u{53f}', '\u{0}', '\u{0}']), ('\u{570}', ['\u{540}', '\u{0}', '\u{0}']), + ('\u{571}', ['\u{541}', '\u{0}', '\u{0}']), ('\u{572}', ['\u{542}', '\u{0}', '\u{0}']), + ('\u{573}', ['\u{543}', '\u{0}', '\u{0}']), ('\u{574}', ['\u{544}', '\u{0}', '\u{0}']), + ('\u{575}', ['\u{545}', '\u{0}', '\u{0}']), ('\u{576}', ['\u{546}', '\u{0}', '\u{0}']), + ('\u{577}', ['\u{547}', '\u{0}', '\u{0}']), ('\u{578}', ['\u{548}', '\u{0}', '\u{0}']), + ('\u{579}', ['\u{549}', '\u{0}', '\u{0}']), ('\u{57a}', ['\u{54a}', '\u{0}', '\u{0}']), + ('\u{57b}', ['\u{54b}', '\u{0}', '\u{0}']), ('\u{57c}', ['\u{54c}', '\u{0}', '\u{0}']), + ('\u{57d}', ['\u{54d}', '\u{0}', '\u{0}']), ('\u{57e}', ['\u{54e}', '\u{0}', '\u{0}']), + ('\u{57f}', ['\u{54f}', '\u{0}', '\u{0}']), ('\u{580}', ['\u{550}', '\u{0}', '\u{0}']), + ('\u{581}', ['\u{551}', '\u{0}', '\u{0}']), ('\u{582}', ['\u{552}', '\u{0}', '\u{0}']), + ('\u{583}', ['\u{553}', '\u{0}', '\u{0}']), ('\u{584}', ['\u{554}', '\u{0}', '\u{0}']), + ('\u{585}', ['\u{555}', '\u{0}', '\u{0}']), ('\u{586}', ['\u{556}', '\u{0}', '\u{0}']), + ('\u{587}', ['\u{535}', '\u{552}', '\u{0}']), ('\u{10d0}', ['\u{1c90}', '\u{0}', '\u{0}']), + ('\u{10d1}', ['\u{1c91}', '\u{0}', '\u{0}']), ('\u{10d2}', ['\u{1c92}', '\u{0}', '\u{0}']), + ('\u{10d3}', ['\u{1c93}', '\u{0}', '\u{0}']), ('\u{10d4}', ['\u{1c94}', '\u{0}', '\u{0}']), + ('\u{10d5}', ['\u{1c95}', '\u{0}', '\u{0}']), ('\u{10d6}', ['\u{1c96}', '\u{0}', '\u{0}']), + ('\u{10d7}', ['\u{1c97}', '\u{0}', '\u{0}']), ('\u{10d8}', ['\u{1c98}', '\u{0}', '\u{0}']), + ('\u{10d9}', ['\u{1c99}', '\u{0}', '\u{0}']), ('\u{10da}', ['\u{1c9a}', '\u{0}', '\u{0}']), + ('\u{10db}', ['\u{1c9b}', '\u{0}', '\u{0}']), ('\u{10dc}', ['\u{1c9c}', '\u{0}', '\u{0}']), + ('\u{10dd}', ['\u{1c9d}', '\u{0}', '\u{0}']), ('\u{10de}', ['\u{1c9e}', '\u{0}', '\u{0}']), + ('\u{10df}', ['\u{1c9f}', '\u{0}', '\u{0}']), ('\u{10e0}', ['\u{1ca0}', '\u{0}', '\u{0}']), + ('\u{10e1}', ['\u{1ca1}', '\u{0}', '\u{0}']), ('\u{10e2}', ['\u{1ca2}', '\u{0}', '\u{0}']), + ('\u{10e3}', ['\u{1ca3}', '\u{0}', '\u{0}']), ('\u{10e4}', ['\u{1ca4}', '\u{0}', '\u{0}']), + ('\u{10e5}', ['\u{1ca5}', '\u{0}', '\u{0}']), ('\u{10e6}', ['\u{1ca6}', '\u{0}', '\u{0}']), + ('\u{10e7}', ['\u{1ca7}', '\u{0}', '\u{0}']), ('\u{10e8}', ['\u{1ca8}', '\u{0}', '\u{0}']), + ('\u{10e9}', ['\u{1ca9}', '\u{0}', '\u{0}']), ('\u{10ea}', ['\u{1caa}', '\u{0}', '\u{0}']), + ('\u{10eb}', ['\u{1cab}', '\u{0}', '\u{0}']), ('\u{10ec}', ['\u{1cac}', '\u{0}', '\u{0}']), + ('\u{10ed}', ['\u{1cad}', '\u{0}', '\u{0}']), ('\u{10ee}', ['\u{1cae}', '\u{0}', '\u{0}']), + ('\u{10ef}', ['\u{1caf}', '\u{0}', '\u{0}']), ('\u{10f0}', ['\u{1cb0}', '\u{0}', '\u{0}']), + ('\u{10f1}', ['\u{1cb1}', '\u{0}', '\u{0}']), ('\u{10f2}', ['\u{1cb2}', '\u{0}', '\u{0}']), + ('\u{10f3}', ['\u{1cb3}', '\u{0}', '\u{0}']), ('\u{10f4}', ['\u{1cb4}', '\u{0}', '\u{0}']), + ('\u{10f5}', ['\u{1cb5}', '\u{0}', '\u{0}']), ('\u{10f6}', ['\u{1cb6}', '\u{0}', '\u{0}']), + ('\u{10f7}', ['\u{1cb7}', '\u{0}', '\u{0}']), ('\u{10f8}', ['\u{1cb8}', '\u{0}', '\u{0}']), + ('\u{10f9}', ['\u{1cb9}', '\u{0}', '\u{0}']), ('\u{10fa}', ['\u{1cba}', '\u{0}', '\u{0}']), + ('\u{10fd}', ['\u{1cbd}', '\u{0}', '\u{0}']), ('\u{10fe}', ['\u{1cbe}', '\u{0}', '\u{0}']), + ('\u{10ff}', ['\u{1cbf}', '\u{0}', '\u{0}']), ('\u{13f8}', ['\u{13f0}', '\u{0}', '\u{0}']), + ('\u{13f9}', ['\u{13f1}', '\u{0}', '\u{0}']), ('\u{13fa}', ['\u{13f2}', '\u{0}', '\u{0}']), + ('\u{13fb}', ['\u{13f3}', '\u{0}', '\u{0}']), ('\u{13fc}', ['\u{13f4}', '\u{0}', '\u{0}']), + ('\u{13fd}', ['\u{13f5}', '\u{0}', '\u{0}']), ('\u{1c80}', ['\u{412}', '\u{0}', '\u{0}']), + ('\u{1c81}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{1c82}', ['\u{41e}', '\u{0}', '\u{0}']), + ('\u{1c83}', ['\u{421}', '\u{0}', '\u{0}']), ('\u{1c84}', ['\u{422}', '\u{0}', '\u{0}']), + ('\u{1c85}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{1c86}', ['\u{42a}', '\u{0}', '\u{0}']), + ('\u{1c87}', ['\u{462}', '\u{0}', '\u{0}']), ('\u{1c88}', ['\u{a64a}', '\u{0}', '\u{0}']), + ('\u{1c8a}', ['\u{1c89}', '\u{0}', '\u{0}']), ('\u{1d79}', ['\u{a77d}', '\u{0}', '\u{0}']), + ('\u{1d7d}', ['\u{2c63}', '\u{0}', '\u{0}']), ('\u{1d8e}', ['\u{a7c6}', '\u{0}', '\u{0}']), + ('\u{1e01}', ['\u{1e00}', '\u{0}', '\u{0}']), ('\u{1e03}', ['\u{1e02}', '\u{0}', '\u{0}']), + ('\u{1e05}', ['\u{1e04}', '\u{0}', '\u{0}']), ('\u{1e07}', ['\u{1e06}', '\u{0}', '\u{0}']), + ('\u{1e09}', ['\u{1e08}', '\u{0}', '\u{0}']), ('\u{1e0b}', ['\u{1e0a}', '\u{0}', '\u{0}']), + ('\u{1e0d}', ['\u{1e0c}', '\u{0}', '\u{0}']), ('\u{1e0f}', ['\u{1e0e}', '\u{0}', '\u{0}']), + ('\u{1e11}', ['\u{1e10}', '\u{0}', '\u{0}']), ('\u{1e13}', ['\u{1e12}', '\u{0}', '\u{0}']), + ('\u{1e15}', ['\u{1e14}', '\u{0}', '\u{0}']), ('\u{1e17}', ['\u{1e16}', '\u{0}', '\u{0}']), + ('\u{1e19}', ['\u{1e18}', '\u{0}', '\u{0}']), ('\u{1e1b}', ['\u{1e1a}', '\u{0}', '\u{0}']), + ('\u{1e1d}', ['\u{1e1c}', '\u{0}', '\u{0}']), ('\u{1e1f}', ['\u{1e1e}', '\u{0}', '\u{0}']), + ('\u{1e21}', ['\u{1e20}', '\u{0}', '\u{0}']), ('\u{1e23}', ['\u{1e22}', '\u{0}', '\u{0}']), + ('\u{1e25}', ['\u{1e24}', '\u{0}', '\u{0}']), ('\u{1e27}', ['\u{1e26}', '\u{0}', '\u{0}']), + ('\u{1e29}', ['\u{1e28}', '\u{0}', '\u{0}']), ('\u{1e2b}', ['\u{1e2a}', '\u{0}', '\u{0}']), + ('\u{1e2d}', ['\u{1e2c}', '\u{0}', '\u{0}']), ('\u{1e2f}', ['\u{1e2e}', '\u{0}', '\u{0}']), + ('\u{1e31}', ['\u{1e30}', '\u{0}', '\u{0}']), ('\u{1e33}', ['\u{1e32}', '\u{0}', '\u{0}']), + ('\u{1e35}', ['\u{1e34}', '\u{0}', '\u{0}']), ('\u{1e37}', ['\u{1e36}', '\u{0}', '\u{0}']), + ('\u{1e39}', ['\u{1e38}', '\u{0}', '\u{0}']), ('\u{1e3b}', ['\u{1e3a}', '\u{0}', '\u{0}']), + ('\u{1e3d}', ['\u{1e3c}', '\u{0}', '\u{0}']), ('\u{1e3f}', ['\u{1e3e}', '\u{0}', '\u{0}']), + ('\u{1e41}', ['\u{1e40}', '\u{0}', '\u{0}']), ('\u{1e43}', ['\u{1e42}', '\u{0}', '\u{0}']), + ('\u{1e45}', ['\u{1e44}', '\u{0}', '\u{0}']), ('\u{1e47}', ['\u{1e46}', '\u{0}', '\u{0}']), + ('\u{1e49}', ['\u{1e48}', '\u{0}', '\u{0}']), ('\u{1e4b}', ['\u{1e4a}', '\u{0}', '\u{0}']), + ('\u{1e4d}', ['\u{1e4c}', '\u{0}', '\u{0}']), ('\u{1e4f}', ['\u{1e4e}', '\u{0}', '\u{0}']), + ('\u{1e51}', ['\u{1e50}', '\u{0}', '\u{0}']), ('\u{1e53}', ['\u{1e52}', '\u{0}', '\u{0}']), + ('\u{1e55}', ['\u{1e54}', '\u{0}', '\u{0}']), ('\u{1e57}', ['\u{1e56}', '\u{0}', '\u{0}']), + ('\u{1e59}', ['\u{1e58}', '\u{0}', '\u{0}']), ('\u{1e5b}', ['\u{1e5a}', '\u{0}', '\u{0}']), + ('\u{1e5d}', ['\u{1e5c}', '\u{0}', '\u{0}']), ('\u{1e5f}', ['\u{1e5e}', '\u{0}', '\u{0}']), + ('\u{1e61}', ['\u{1e60}', '\u{0}', '\u{0}']), ('\u{1e63}', ['\u{1e62}', '\u{0}', '\u{0}']), + ('\u{1e65}', ['\u{1e64}', '\u{0}', '\u{0}']), ('\u{1e67}', ['\u{1e66}', '\u{0}', '\u{0}']), + ('\u{1e69}', ['\u{1e68}', '\u{0}', '\u{0}']), ('\u{1e6b}', ['\u{1e6a}', '\u{0}', '\u{0}']), + ('\u{1e6d}', ['\u{1e6c}', '\u{0}', '\u{0}']), ('\u{1e6f}', ['\u{1e6e}', '\u{0}', '\u{0}']), + ('\u{1e71}', ['\u{1e70}', '\u{0}', '\u{0}']), ('\u{1e73}', ['\u{1e72}', '\u{0}', '\u{0}']), + ('\u{1e75}', ['\u{1e74}', '\u{0}', '\u{0}']), ('\u{1e77}', ['\u{1e76}', '\u{0}', '\u{0}']), + ('\u{1e79}', ['\u{1e78}', '\u{0}', '\u{0}']), ('\u{1e7b}', ['\u{1e7a}', '\u{0}', '\u{0}']), + ('\u{1e7d}', ['\u{1e7c}', '\u{0}', '\u{0}']), ('\u{1e7f}', ['\u{1e7e}', '\u{0}', '\u{0}']), + ('\u{1e81}', ['\u{1e80}', '\u{0}', '\u{0}']), ('\u{1e83}', ['\u{1e82}', '\u{0}', '\u{0}']), + ('\u{1e85}', ['\u{1e84}', '\u{0}', '\u{0}']), ('\u{1e87}', ['\u{1e86}', '\u{0}', '\u{0}']), + ('\u{1e89}', ['\u{1e88}', '\u{0}', '\u{0}']), ('\u{1e8b}', ['\u{1e8a}', '\u{0}', '\u{0}']), + ('\u{1e8d}', ['\u{1e8c}', '\u{0}', '\u{0}']), ('\u{1e8f}', ['\u{1e8e}', '\u{0}', '\u{0}']), + ('\u{1e91}', ['\u{1e90}', '\u{0}', '\u{0}']), ('\u{1e93}', ['\u{1e92}', '\u{0}', '\u{0}']), + ('\u{1e95}', ['\u{1e94}', '\u{0}', '\u{0}']), ('\u{1e96}', ['\u{48}', '\u{331}', '\u{0}']), + ('\u{1e97}', ['\u{54}', '\u{308}', '\u{0}']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\u{0}']), + ('\u{1e99}', ['\u{59}', '\u{30a}', '\u{0}']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\u{0}']), + ('\u{1e9b}', ['\u{1e60}', '\u{0}', '\u{0}']), ('\u{1ea1}', ['\u{1ea0}', '\u{0}', '\u{0}']), + ('\u{1ea3}', ['\u{1ea2}', '\u{0}', '\u{0}']), ('\u{1ea5}', ['\u{1ea4}', '\u{0}', '\u{0}']), + ('\u{1ea7}', ['\u{1ea6}', '\u{0}', '\u{0}']), ('\u{1ea9}', ['\u{1ea8}', '\u{0}', '\u{0}']), + ('\u{1eab}', ['\u{1eaa}', '\u{0}', '\u{0}']), ('\u{1ead}', ['\u{1eac}', '\u{0}', '\u{0}']), + ('\u{1eaf}', ['\u{1eae}', '\u{0}', '\u{0}']), ('\u{1eb1}', ['\u{1eb0}', '\u{0}', '\u{0}']), + ('\u{1eb3}', ['\u{1eb2}', '\u{0}', '\u{0}']), ('\u{1eb5}', ['\u{1eb4}', '\u{0}', '\u{0}']), + ('\u{1eb7}', ['\u{1eb6}', '\u{0}', '\u{0}']), ('\u{1eb9}', ['\u{1eb8}', '\u{0}', '\u{0}']), + ('\u{1ebb}', ['\u{1eba}', '\u{0}', '\u{0}']), ('\u{1ebd}', ['\u{1ebc}', '\u{0}', '\u{0}']), + ('\u{1ebf}', ['\u{1ebe}', '\u{0}', '\u{0}']), ('\u{1ec1}', ['\u{1ec0}', '\u{0}', '\u{0}']), + ('\u{1ec3}', ['\u{1ec2}', '\u{0}', '\u{0}']), ('\u{1ec5}', ['\u{1ec4}', '\u{0}', '\u{0}']), + ('\u{1ec7}', ['\u{1ec6}', '\u{0}', '\u{0}']), ('\u{1ec9}', ['\u{1ec8}', '\u{0}', '\u{0}']), + ('\u{1ecb}', ['\u{1eca}', '\u{0}', '\u{0}']), ('\u{1ecd}', ['\u{1ecc}', '\u{0}', '\u{0}']), + ('\u{1ecf}', ['\u{1ece}', '\u{0}', '\u{0}']), ('\u{1ed1}', ['\u{1ed0}', '\u{0}', '\u{0}']), + ('\u{1ed3}', ['\u{1ed2}', '\u{0}', '\u{0}']), ('\u{1ed5}', ['\u{1ed4}', '\u{0}', '\u{0}']), + ('\u{1ed7}', ['\u{1ed6}', '\u{0}', '\u{0}']), ('\u{1ed9}', ['\u{1ed8}', '\u{0}', '\u{0}']), + ('\u{1edb}', ['\u{1eda}', '\u{0}', '\u{0}']), ('\u{1edd}', ['\u{1edc}', '\u{0}', '\u{0}']), + ('\u{1edf}', ['\u{1ede}', '\u{0}', '\u{0}']), ('\u{1ee1}', ['\u{1ee0}', '\u{0}', '\u{0}']), + ('\u{1ee3}', ['\u{1ee2}', '\u{0}', '\u{0}']), ('\u{1ee5}', ['\u{1ee4}', '\u{0}', '\u{0}']), + ('\u{1ee7}', ['\u{1ee6}', '\u{0}', '\u{0}']), ('\u{1ee9}', ['\u{1ee8}', '\u{0}', '\u{0}']), + ('\u{1eeb}', ['\u{1eea}', '\u{0}', '\u{0}']), ('\u{1eed}', ['\u{1eec}', '\u{0}', '\u{0}']), + ('\u{1eef}', ['\u{1eee}', '\u{0}', '\u{0}']), ('\u{1ef1}', ['\u{1ef0}', '\u{0}', '\u{0}']), + ('\u{1ef3}', ['\u{1ef2}', '\u{0}', '\u{0}']), ('\u{1ef5}', ['\u{1ef4}', '\u{0}', '\u{0}']), + ('\u{1ef7}', ['\u{1ef6}', '\u{0}', '\u{0}']), ('\u{1ef9}', ['\u{1ef8}', '\u{0}', '\u{0}']), + ('\u{1efb}', ['\u{1efa}', '\u{0}', '\u{0}']), ('\u{1efd}', ['\u{1efc}', '\u{0}', '\u{0}']), + ('\u{1eff}', ['\u{1efe}', '\u{0}', '\u{0}']), ('\u{1f00}', ['\u{1f08}', '\u{0}', '\u{0}']), + ('\u{1f01}', ['\u{1f09}', '\u{0}', '\u{0}']), ('\u{1f02}', ['\u{1f0a}', '\u{0}', '\u{0}']), + ('\u{1f03}', ['\u{1f0b}', '\u{0}', '\u{0}']), ('\u{1f04}', ['\u{1f0c}', '\u{0}', '\u{0}']), + ('\u{1f05}', ['\u{1f0d}', '\u{0}', '\u{0}']), ('\u{1f06}', ['\u{1f0e}', '\u{0}', '\u{0}']), + ('\u{1f07}', ['\u{1f0f}', '\u{0}', '\u{0}']), ('\u{1f10}', ['\u{1f18}', '\u{0}', '\u{0}']), + ('\u{1f11}', ['\u{1f19}', '\u{0}', '\u{0}']), ('\u{1f12}', ['\u{1f1a}', '\u{0}', '\u{0}']), + ('\u{1f13}', ['\u{1f1b}', '\u{0}', '\u{0}']), ('\u{1f14}', ['\u{1f1c}', '\u{0}', '\u{0}']), + ('\u{1f15}', ['\u{1f1d}', '\u{0}', '\u{0}']), ('\u{1f20}', ['\u{1f28}', '\u{0}', '\u{0}']), + ('\u{1f21}', ['\u{1f29}', '\u{0}', '\u{0}']), ('\u{1f22}', ['\u{1f2a}', '\u{0}', '\u{0}']), + ('\u{1f23}', ['\u{1f2b}', '\u{0}', '\u{0}']), ('\u{1f24}', ['\u{1f2c}', '\u{0}', '\u{0}']), + ('\u{1f25}', ['\u{1f2d}', '\u{0}', '\u{0}']), ('\u{1f26}', ['\u{1f2e}', '\u{0}', '\u{0}']), + ('\u{1f27}', ['\u{1f2f}', '\u{0}', '\u{0}']), ('\u{1f30}', ['\u{1f38}', '\u{0}', '\u{0}']), + ('\u{1f31}', ['\u{1f39}', '\u{0}', '\u{0}']), ('\u{1f32}', ['\u{1f3a}', '\u{0}', '\u{0}']), + ('\u{1f33}', ['\u{1f3b}', '\u{0}', '\u{0}']), ('\u{1f34}', ['\u{1f3c}', '\u{0}', '\u{0}']), + ('\u{1f35}', ['\u{1f3d}', '\u{0}', '\u{0}']), ('\u{1f36}', ['\u{1f3e}', '\u{0}', '\u{0}']), + ('\u{1f37}', ['\u{1f3f}', '\u{0}', '\u{0}']), ('\u{1f40}', ['\u{1f48}', '\u{0}', '\u{0}']), + ('\u{1f41}', ['\u{1f49}', '\u{0}', '\u{0}']), ('\u{1f42}', ['\u{1f4a}', '\u{0}', '\u{0}']), + ('\u{1f43}', ['\u{1f4b}', '\u{0}', '\u{0}']), ('\u{1f44}', ['\u{1f4c}', '\u{0}', '\u{0}']), + ('\u{1f45}', ['\u{1f4d}', '\u{0}', '\u{0}']), ('\u{1f50}', ['\u{3a5}', '\u{313}', '\u{0}']), + ('\u{1f51}', ['\u{1f59}', '\u{0}', '\u{0}']), + ('\u{1f52}', ['\u{3a5}', '\u{313}', '\u{300}']), + ('\u{1f53}', ['\u{1f5b}', '\u{0}', '\u{0}']), + ('\u{1f54}', ['\u{3a5}', '\u{313}', '\u{301}']), + ('\u{1f55}', ['\u{1f5d}', '\u{0}', '\u{0}']), + ('\u{1f56}', ['\u{3a5}', '\u{313}', '\u{342}']), + ('\u{1f57}', ['\u{1f5f}', '\u{0}', '\u{0}']), ('\u{1f60}', ['\u{1f68}', '\u{0}', '\u{0}']), + ('\u{1f61}', ['\u{1f69}', '\u{0}', '\u{0}']), ('\u{1f62}', ['\u{1f6a}', '\u{0}', '\u{0}']), + ('\u{1f63}', ['\u{1f6b}', '\u{0}', '\u{0}']), ('\u{1f64}', ['\u{1f6c}', '\u{0}', '\u{0}']), + ('\u{1f65}', ['\u{1f6d}', '\u{0}', '\u{0}']), ('\u{1f66}', ['\u{1f6e}', '\u{0}', '\u{0}']), + ('\u{1f67}', ['\u{1f6f}', '\u{0}', '\u{0}']), ('\u{1f70}', ['\u{1fba}', '\u{0}', '\u{0}']), + ('\u{1f71}', ['\u{1fbb}', '\u{0}', '\u{0}']), ('\u{1f72}', ['\u{1fc8}', '\u{0}', '\u{0}']), + ('\u{1f73}', ['\u{1fc9}', '\u{0}', '\u{0}']), ('\u{1f74}', ['\u{1fca}', '\u{0}', '\u{0}']), + ('\u{1f75}', ['\u{1fcb}', '\u{0}', '\u{0}']), ('\u{1f76}', ['\u{1fda}', '\u{0}', '\u{0}']), + ('\u{1f77}', ['\u{1fdb}', '\u{0}', '\u{0}']), ('\u{1f78}', ['\u{1ff8}', '\u{0}', '\u{0}']), + ('\u{1f79}', ['\u{1ff9}', '\u{0}', '\u{0}']), ('\u{1f7a}', ['\u{1fea}', '\u{0}', '\u{0}']), + ('\u{1f7b}', ['\u{1feb}', '\u{0}', '\u{0}']), ('\u{1f7c}', ['\u{1ffa}', '\u{0}', '\u{0}']), + ('\u{1f7d}', ['\u{1ffb}', '\u{0}', '\u{0}']), + ('\u{1f80}', ['\u{1f08}', '\u{399}', '\u{0}']), + ('\u{1f81}', ['\u{1f09}', '\u{399}', '\u{0}']), + ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\u{0}']), + ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\u{0}']), + ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\u{0}']), + ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\u{0}']), + ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\u{0}']), + ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\u{0}']), + ('\u{1f88}', ['\u{1f08}', '\u{399}', '\u{0}']), + ('\u{1f89}', ['\u{1f09}', '\u{399}', '\u{0}']), + ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\u{0}']), + ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\u{0}']), + ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\u{0}']), + ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\u{0}']), + ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\u{0}']), + ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\u{0}']), + ('\u{1f90}', ['\u{1f28}', '\u{399}', '\u{0}']), + ('\u{1f91}', ['\u{1f29}', '\u{399}', '\u{0}']), + ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\u{0}']), + ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\u{0}']), + ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\u{0}']), + ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\u{0}']), + ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\u{0}']), + ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\u{0}']), + ('\u{1f98}', ['\u{1f28}', '\u{399}', '\u{0}']), + ('\u{1f99}', ['\u{1f29}', '\u{399}', '\u{0}']), + ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\u{0}']), + ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\u{0}']), + ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\u{0}']), + ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\u{0}']), + ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\u{0}']), + ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\u{0}']), + ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\u{0}']), + ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\u{0}']), + ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\u{0}']), + ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\u{0}']), + ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\u{0}']), + ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\u{0}']), + ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\u{0}']), + ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\u{0}']), + ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\u{0}']), + ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\u{0}']), + ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\u{0}']), + ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\u{0}']), + ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\u{0}']), + ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\u{0}']), + ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\u{0}']), + ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\u{0}']), + ('\u{1fb0}', ['\u{1fb8}', '\u{0}', '\u{0}']), ('\u{1fb1}', ['\u{1fb9}', '\u{0}', '\u{0}']), + ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\u{0}']), + ('\u{1fb3}', ['\u{391}', '\u{399}', '\u{0}']), + ('\u{1fb4}', ['\u{386}', '\u{399}', '\u{0}']), + ('\u{1fb6}', ['\u{391}', '\u{342}', '\u{0}']), + ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), + ('\u{1fbc}', ['\u{391}', '\u{399}', '\u{0}']), ('\u{1fbe}', ['\u{399}', '\u{0}', '\u{0}']), + ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\u{0}']), + ('\u{1fc3}', ['\u{397}', '\u{399}', '\u{0}']), + ('\u{1fc4}', ['\u{389}', '\u{399}', '\u{0}']), + ('\u{1fc6}', ['\u{397}', '\u{342}', '\u{0}']), + ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), + ('\u{1fcc}', ['\u{397}', '\u{399}', '\u{0}']), ('\u{1fd0}', ['\u{1fd8}', '\u{0}', '\u{0}']), + ('\u{1fd1}', ['\u{1fd9}', '\u{0}', '\u{0}']), + ('\u{1fd2}', ['\u{399}', '\u{308}', '\u{300}']), + ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']), + ('\u{1fd6}', ['\u{399}', '\u{342}', '\u{0}']), + ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']), + ('\u{1fe0}', ['\u{1fe8}', '\u{0}', '\u{0}']), ('\u{1fe1}', ['\u{1fe9}', '\u{0}', '\u{0}']), + ('\u{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']), + ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), + ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\u{0}']), ('\u{1fe5}', ['\u{1fec}', '\u{0}', '\u{0}']), + ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\u{0}']), + ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']), + ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\u{0}']), + ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\u{0}']), + ('\u{1ff4}', ['\u{38f}', '\u{399}', '\u{0}']), + ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\u{0}']), + ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), + ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\u{0}']), ('\u{214e}', ['\u{2132}', '\u{0}', '\u{0}']), + ('\u{2170}', ['\u{2160}', '\u{0}', '\u{0}']), ('\u{2171}', ['\u{2161}', '\u{0}', '\u{0}']), + ('\u{2172}', ['\u{2162}', '\u{0}', '\u{0}']), ('\u{2173}', ['\u{2163}', '\u{0}', '\u{0}']), + ('\u{2174}', ['\u{2164}', '\u{0}', '\u{0}']), ('\u{2175}', ['\u{2165}', '\u{0}', '\u{0}']), + ('\u{2176}', ['\u{2166}', '\u{0}', '\u{0}']), ('\u{2177}', ['\u{2167}', '\u{0}', '\u{0}']), + ('\u{2178}', ['\u{2168}', '\u{0}', '\u{0}']), ('\u{2179}', ['\u{2169}', '\u{0}', '\u{0}']), + ('\u{217a}', ['\u{216a}', '\u{0}', '\u{0}']), ('\u{217b}', ['\u{216b}', '\u{0}', '\u{0}']), + ('\u{217c}', ['\u{216c}', '\u{0}', '\u{0}']), ('\u{217d}', ['\u{216d}', '\u{0}', '\u{0}']), + ('\u{217e}', ['\u{216e}', '\u{0}', '\u{0}']), ('\u{217f}', ['\u{216f}', '\u{0}', '\u{0}']), + ('\u{2184}', ['\u{2183}', '\u{0}', '\u{0}']), ('\u{24d0}', ['\u{24b6}', '\u{0}', '\u{0}']), + ('\u{24d1}', ['\u{24b7}', '\u{0}', '\u{0}']), ('\u{24d2}', ['\u{24b8}', '\u{0}', '\u{0}']), + ('\u{24d3}', ['\u{24b9}', '\u{0}', '\u{0}']), ('\u{24d4}', ['\u{24ba}', '\u{0}', '\u{0}']), + ('\u{24d5}', ['\u{24bb}', '\u{0}', '\u{0}']), ('\u{24d6}', ['\u{24bc}', '\u{0}', '\u{0}']), + ('\u{24d7}', ['\u{24bd}', '\u{0}', '\u{0}']), ('\u{24d8}', ['\u{24be}', '\u{0}', '\u{0}']), + ('\u{24d9}', ['\u{24bf}', '\u{0}', '\u{0}']), ('\u{24da}', ['\u{24c0}', '\u{0}', '\u{0}']), + ('\u{24db}', ['\u{24c1}', '\u{0}', '\u{0}']), ('\u{24dc}', ['\u{24c2}', '\u{0}', '\u{0}']), + ('\u{24dd}', ['\u{24c3}', '\u{0}', '\u{0}']), ('\u{24de}', ['\u{24c4}', '\u{0}', '\u{0}']), + ('\u{24df}', ['\u{24c5}', '\u{0}', '\u{0}']), ('\u{24e0}', ['\u{24c6}', '\u{0}', '\u{0}']), + ('\u{24e1}', ['\u{24c7}', '\u{0}', '\u{0}']), ('\u{24e2}', ['\u{24c8}', '\u{0}', '\u{0}']), + ('\u{24e3}', ['\u{24c9}', '\u{0}', '\u{0}']), ('\u{24e4}', ['\u{24ca}', '\u{0}', '\u{0}']), + ('\u{24e5}', ['\u{24cb}', '\u{0}', '\u{0}']), ('\u{24e6}', ['\u{24cc}', '\u{0}', '\u{0}']), + ('\u{24e7}', ['\u{24cd}', '\u{0}', '\u{0}']), ('\u{24e8}', ['\u{24ce}', '\u{0}', '\u{0}']), + ('\u{24e9}', ['\u{24cf}', '\u{0}', '\u{0}']), ('\u{2c30}', ['\u{2c00}', '\u{0}', '\u{0}']), + ('\u{2c31}', ['\u{2c01}', '\u{0}', '\u{0}']), ('\u{2c32}', ['\u{2c02}', '\u{0}', '\u{0}']), + ('\u{2c33}', ['\u{2c03}', '\u{0}', '\u{0}']), ('\u{2c34}', ['\u{2c04}', '\u{0}', '\u{0}']), + ('\u{2c35}', ['\u{2c05}', '\u{0}', '\u{0}']), ('\u{2c36}', ['\u{2c06}', '\u{0}', '\u{0}']), + ('\u{2c37}', ['\u{2c07}', '\u{0}', '\u{0}']), ('\u{2c38}', ['\u{2c08}', '\u{0}', '\u{0}']), + ('\u{2c39}', ['\u{2c09}', '\u{0}', '\u{0}']), ('\u{2c3a}', ['\u{2c0a}', '\u{0}', '\u{0}']), + ('\u{2c3b}', ['\u{2c0b}', '\u{0}', '\u{0}']), ('\u{2c3c}', ['\u{2c0c}', '\u{0}', '\u{0}']), + ('\u{2c3d}', ['\u{2c0d}', '\u{0}', '\u{0}']), ('\u{2c3e}', ['\u{2c0e}', '\u{0}', '\u{0}']), + ('\u{2c3f}', ['\u{2c0f}', '\u{0}', '\u{0}']), ('\u{2c40}', ['\u{2c10}', '\u{0}', '\u{0}']), + ('\u{2c41}', ['\u{2c11}', '\u{0}', '\u{0}']), ('\u{2c42}', ['\u{2c12}', '\u{0}', '\u{0}']), + ('\u{2c43}', ['\u{2c13}', '\u{0}', '\u{0}']), ('\u{2c44}', ['\u{2c14}', '\u{0}', '\u{0}']), + ('\u{2c45}', ['\u{2c15}', '\u{0}', '\u{0}']), ('\u{2c46}', ['\u{2c16}', '\u{0}', '\u{0}']), + ('\u{2c47}', ['\u{2c17}', '\u{0}', '\u{0}']), ('\u{2c48}', ['\u{2c18}', '\u{0}', '\u{0}']), + ('\u{2c49}', ['\u{2c19}', '\u{0}', '\u{0}']), ('\u{2c4a}', ['\u{2c1a}', '\u{0}', '\u{0}']), + ('\u{2c4b}', ['\u{2c1b}', '\u{0}', '\u{0}']), ('\u{2c4c}', ['\u{2c1c}', '\u{0}', '\u{0}']), + ('\u{2c4d}', ['\u{2c1d}', '\u{0}', '\u{0}']), ('\u{2c4e}', ['\u{2c1e}', '\u{0}', '\u{0}']), + ('\u{2c4f}', ['\u{2c1f}', '\u{0}', '\u{0}']), ('\u{2c50}', ['\u{2c20}', '\u{0}', '\u{0}']), + ('\u{2c51}', ['\u{2c21}', '\u{0}', '\u{0}']), ('\u{2c52}', ['\u{2c22}', '\u{0}', '\u{0}']), + ('\u{2c53}', ['\u{2c23}', '\u{0}', '\u{0}']), ('\u{2c54}', ['\u{2c24}', '\u{0}', '\u{0}']), + ('\u{2c55}', ['\u{2c25}', '\u{0}', '\u{0}']), ('\u{2c56}', ['\u{2c26}', '\u{0}', '\u{0}']), + ('\u{2c57}', ['\u{2c27}', '\u{0}', '\u{0}']), ('\u{2c58}', ['\u{2c28}', '\u{0}', '\u{0}']), + ('\u{2c59}', ['\u{2c29}', '\u{0}', '\u{0}']), ('\u{2c5a}', ['\u{2c2a}', '\u{0}', '\u{0}']), + ('\u{2c5b}', ['\u{2c2b}', '\u{0}', '\u{0}']), ('\u{2c5c}', ['\u{2c2c}', '\u{0}', '\u{0}']), + ('\u{2c5d}', ['\u{2c2d}', '\u{0}', '\u{0}']), ('\u{2c5e}', ['\u{2c2e}', '\u{0}', '\u{0}']), + ('\u{2c5f}', ['\u{2c2f}', '\u{0}', '\u{0}']), ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']), + ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']), ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']), + ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']), ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']), + ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']), ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']), + ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']), ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']), + ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']), ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']), + ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']), ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']), + ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']), ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']), + ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']), ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']), + ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']), ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']), + ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']), ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']), + ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']), ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']), + ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']), ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']), + ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']), ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']), + ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']), ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']), + ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']), ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']), + ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']), ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']), + ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']), ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']), + ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']), ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']), + ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']), ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']), + ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']), ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']), + ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']), ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']), + ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']), ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']), + ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']), ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']), + ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']), ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']), + ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']), ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']), + ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']), ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']), + ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']), ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']), + ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']), ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']), + ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']), ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']), + ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']), ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']), + ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']), ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']), + ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']), ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']), + ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']), ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']), + ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']), ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']), + ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']), ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']), + ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']), ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']), + ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']), ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']), + ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']), ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']), + ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']), ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']), + ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']), ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']), + ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']), ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']), + ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']), ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']), + ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']), ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']), + ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']), ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']), + ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']), ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']), + ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']), ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']), + ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']), ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']), + ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']), ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']), + ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']), ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']), + ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']), ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']), + ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']), ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']), + ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']), ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']), + ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']), ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']), + ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']), ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']), + ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']), ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']), + ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']), ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']), + ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']), ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']), + ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']), ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']), + ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']), ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']), + ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']), ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']), + ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']), ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']), + ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']), ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']), + ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']), ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']), + ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']), ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']), + ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']), ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']), + ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']), ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']), + ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']), ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']), + ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']), ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']), + ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']), ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']), + ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']), ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']), + ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']), ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']), + ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']), ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']), + ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']), ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']), + ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']), ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']), + ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']), ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']), + ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']), ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']), + ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']), ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']), + ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']), ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']), + ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']), ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']), + ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']), ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']), + ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']), ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']), + ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']), ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']), + ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']), ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']), + ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']), ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']), + ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']), ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']), + ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']), ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']), + ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']), ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']), + ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']), ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']), + ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']), ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']), + ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']), ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']), + ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']), ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']), + ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']), ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']), + ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']), ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']), + ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']), ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']), + ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']), ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']), + ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']), ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']), + ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']), ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']), + ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']), ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']), + ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']), ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']), + ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']), ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']), + ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']), ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']), + ('\u{a7c1}', ['\u{a7c0}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']), + ('\u{a7c8}', ['\u{a7c7}', '\u{0}', '\u{0}']), ('\u{a7ca}', ['\u{a7c9}', '\u{0}', '\u{0}']), + ('\u{a7cd}', ['\u{a7cc}', '\u{0}', '\u{0}']), ('\u{a7cf}', ['\u{a7ce}', '\u{0}', '\u{0}']), + ('\u{a7d1}', ['\u{a7d0}', '\u{0}', '\u{0}']), ('\u{a7d3}', ['\u{a7d2}', '\u{0}', '\u{0}']), + ('\u{a7d5}', ['\u{a7d4}', '\u{0}', '\u{0}']), ('\u{a7d7}', ['\u{a7d6}', '\u{0}', '\u{0}']), + ('\u{a7d9}', ['\u{a7d8}', '\u{0}', '\u{0}']), ('\u{a7db}', ['\u{a7da}', '\u{0}', '\u{0}']), + ('\u{a7f6}', ['\u{a7f5}', '\u{0}', '\u{0}']), ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']), + ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']), ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']), + ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']), ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']), + ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']), ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']), + ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']), ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']), + ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']), ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']), + ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']), ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']), + ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']), ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']), + ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']), ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']), + ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']), ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']), + ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']), ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']), + ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']), ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']), + ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']), ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']), + ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']), ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']), + ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']), ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']), + ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']), ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']), + ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']), ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']), + ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']), ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']), + ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']), ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']), + ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']), ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']), + ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']), ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']), + ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']), ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']), + ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']), ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']), + ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']), ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']), + ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']), ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']), + ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']), ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']), + ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']), ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']), + ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']), ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']), + ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']), ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']), + ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']), ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']), + ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']), ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']), + ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']), ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']), + ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']), ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']), + ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']), ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']), + ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']), ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']), + ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']), ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']), + ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']), ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']), + ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']), ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']), + ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']), ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']), + ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']), ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']), + ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']), ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']), + ('\u{fb00}', ['\u{46}', '\u{46}', '\u{0}']), ('\u{fb01}', ['\u{46}', '\u{49}', '\u{0}']), + ('\u{fb02}', ['\u{46}', '\u{4c}', '\u{0}']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), + ('\u{fb04}', ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\u{0}']), + ('\u{fb06}', ['\u{53}', '\u{54}', '\u{0}']), ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']), + ('\u{fb14}', ['\u{544}', '\u{535}', '\u{0}']), + ('\u{fb15}', ['\u{544}', '\u{53b}', '\u{0}']), + ('\u{fb16}', ['\u{54e}', '\u{546}', '\u{0}']), + ('\u{fb17}', ['\u{544}', '\u{53d}', '\u{0}']), ('\u{ff41}', ['\u{ff21}', '\u{0}', '\u{0}']), + ('\u{ff42}', ['\u{ff22}', '\u{0}', '\u{0}']), ('\u{ff43}', ['\u{ff23}', '\u{0}', '\u{0}']), + ('\u{ff44}', ['\u{ff24}', '\u{0}', '\u{0}']), ('\u{ff45}', ['\u{ff25}', '\u{0}', '\u{0}']), + ('\u{ff46}', ['\u{ff26}', '\u{0}', '\u{0}']), ('\u{ff47}', ['\u{ff27}', '\u{0}', '\u{0}']), + ('\u{ff48}', ['\u{ff28}', '\u{0}', '\u{0}']), ('\u{ff49}', ['\u{ff29}', '\u{0}', '\u{0}']), + ('\u{ff4a}', ['\u{ff2a}', '\u{0}', '\u{0}']), ('\u{ff4b}', ['\u{ff2b}', '\u{0}', '\u{0}']), + ('\u{ff4c}', ['\u{ff2c}', '\u{0}', '\u{0}']), ('\u{ff4d}', ['\u{ff2d}', '\u{0}', '\u{0}']), + ('\u{ff4e}', ['\u{ff2e}', '\u{0}', '\u{0}']), ('\u{ff4f}', ['\u{ff2f}', '\u{0}', '\u{0}']), + ('\u{ff50}', ['\u{ff30}', '\u{0}', '\u{0}']), ('\u{ff51}', ['\u{ff31}', '\u{0}', '\u{0}']), + ('\u{ff52}', ['\u{ff32}', '\u{0}', '\u{0}']), ('\u{ff53}', ['\u{ff33}', '\u{0}', '\u{0}']), + ('\u{ff54}', ['\u{ff34}', '\u{0}', '\u{0}']), ('\u{ff55}', ['\u{ff35}', '\u{0}', '\u{0}']), + ('\u{ff56}', ['\u{ff36}', '\u{0}', '\u{0}']), ('\u{ff57}', ['\u{ff37}', '\u{0}', '\u{0}']), + ('\u{ff58}', ['\u{ff38}', '\u{0}', '\u{0}']), ('\u{ff59}', ['\u{ff39}', '\u{0}', '\u{0}']), + ('\u{ff5a}', ['\u{ff3a}', '\u{0}', '\u{0}']), + ('\u{10428}', ['\u{10400}', '\u{0}', '\u{0}']), + ('\u{10429}', ['\u{10401}', '\u{0}', '\u{0}']), + ('\u{1042a}', ['\u{10402}', '\u{0}', '\u{0}']), + ('\u{1042b}', ['\u{10403}', '\u{0}', '\u{0}']), + ('\u{1042c}', ['\u{10404}', '\u{0}', '\u{0}']), + ('\u{1042d}', ['\u{10405}', '\u{0}', '\u{0}']), + ('\u{1042e}', ['\u{10406}', '\u{0}', '\u{0}']), + ('\u{1042f}', ['\u{10407}', '\u{0}', '\u{0}']), + ('\u{10430}', ['\u{10408}', '\u{0}', '\u{0}']), + ('\u{10431}', ['\u{10409}', '\u{0}', '\u{0}']), + ('\u{10432}', ['\u{1040a}', '\u{0}', '\u{0}']), + ('\u{10433}', ['\u{1040b}', '\u{0}', '\u{0}']), + ('\u{10434}', ['\u{1040c}', '\u{0}', '\u{0}']), + ('\u{10435}', ['\u{1040d}', '\u{0}', '\u{0}']), + ('\u{10436}', ['\u{1040e}', '\u{0}', '\u{0}']), + ('\u{10437}', ['\u{1040f}', '\u{0}', '\u{0}']), + ('\u{10438}', ['\u{10410}', '\u{0}', '\u{0}']), + ('\u{10439}', ['\u{10411}', '\u{0}', '\u{0}']), + ('\u{1043a}', ['\u{10412}', '\u{0}', '\u{0}']), + ('\u{1043b}', ['\u{10413}', '\u{0}', '\u{0}']), + ('\u{1043c}', ['\u{10414}', '\u{0}', '\u{0}']), + ('\u{1043d}', ['\u{10415}', '\u{0}', '\u{0}']), + ('\u{1043e}', ['\u{10416}', '\u{0}', '\u{0}']), + ('\u{1043f}', ['\u{10417}', '\u{0}', '\u{0}']), + ('\u{10440}', ['\u{10418}', '\u{0}', '\u{0}']), + ('\u{10441}', ['\u{10419}', '\u{0}', '\u{0}']), + ('\u{10442}', ['\u{1041a}', '\u{0}', '\u{0}']), + ('\u{10443}', ['\u{1041b}', '\u{0}', '\u{0}']), + ('\u{10444}', ['\u{1041c}', '\u{0}', '\u{0}']), + ('\u{10445}', ['\u{1041d}', '\u{0}', '\u{0}']), + ('\u{10446}', ['\u{1041e}', '\u{0}', '\u{0}']), + ('\u{10447}', ['\u{1041f}', '\u{0}', '\u{0}']), + ('\u{10448}', ['\u{10420}', '\u{0}', '\u{0}']), + ('\u{10449}', ['\u{10421}', '\u{0}', '\u{0}']), + ('\u{1044a}', ['\u{10422}', '\u{0}', '\u{0}']), + ('\u{1044b}', ['\u{10423}', '\u{0}', '\u{0}']), + ('\u{1044c}', ['\u{10424}', '\u{0}', '\u{0}']), + ('\u{1044d}', ['\u{10425}', '\u{0}', '\u{0}']), + ('\u{1044e}', ['\u{10426}', '\u{0}', '\u{0}']), + ('\u{1044f}', ['\u{10427}', '\u{0}', '\u{0}']), + ('\u{104d8}', ['\u{104b0}', '\u{0}', '\u{0}']), + ('\u{104d9}', ['\u{104b1}', '\u{0}', '\u{0}']), + ('\u{104da}', ['\u{104b2}', '\u{0}', '\u{0}']), + ('\u{104db}', ['\u{104b3}', '\u{0}', '\u{0}']), + ('\u{104dc}', ['\u{104b4}', '\u{0}', '\u{0}']), + ('\u{104dd}', ['\u{104b5}', '\u{0}', '\u{0}']), + ('\u{104de}', ['\u{104b6}', '\u{0}', '\u{0}']), + ('\u{104df}', ['\u{104b7}', '\u{0}', '\u{0}']), + ('\u{104e0}', ['\u{104b8}', '\u{0}', '\u{0}']), + ('\u{104e1}', ['\u{104b9}', '\u{0}', '\u{0}']), + ('\u{104e2}', ['\u{104ba}', '\u{0}', '\u{0}']), + ('\u{104e3}', ['\u{104bb}', '\u{0}', '\u{0}']), + ('\u{104e4}', ['\u{104bc}', '\u{0}', '\u{0}']), + ('\u{104e5}', ['\u{104bd}', '\u{0}', '\u{0}']), + ('\u{104e6}', ['\u{104be}', '\u{0}', '\u{0}']), + ('\u{104e7}', ['\u{104bf}', '\u{0}', '\u{0}']), + ('\u{104e8}', ['\u{104c0}', '\u{0}', '\u{0}']), + ('\u{104e9}', ['\u{104c1}', '\u{0}', '\u{0}']), + ('\u{104ea}', ['\u{104c2}', '\u{0}', '\u{0}']), + ('\u{104eb}', ['\u{104c3}', '\u{0}', '\u{0}']), + ('\u{104ec}', ['\u{104c4}', '\u{0}', '\u{0}']), + ('\u{104ed}', ['\u{104c5}', '\u{0}', '\u{0}']), + ('\u{104ee}', ['\u{104c6}', '\u{0}', '\u{0}']), + ('\u{104ef}', ['\u{104c7}', '\u{0}', '\u{0}']), + ('\u{104f0}', ['\u{104c8}', '\u{0}', '\u{0}']), + ('\u{104f1}', ['\u{104c9}', '\u{0}', '\u{0}']), + ('\u{104f2}', ['\u{104ca}', '\u{0}', '\u{0}']), + ('\u{104f3}', ['\u{104cb}', '\u{0}', '\u{0}']), + ('\u{104f4}', ['\u{104cc}', '\u{0}', '\u{0}']), + ('\u{104f5}', ['\u{104cd}', '\u{0}', '\u{0}']), + ('\u{104f6}', ['\u{104ce}', '\u{0}', '\u{0}']), + ('\u{104f7}', ['\u{104cf}', '\u{0}', '\u{0}']), + ('\u{104f8}', ['\u{104d0}', '\u{0}', '\u{0}']), + ('\u{104f9}', ['\u{104d1}', '\u{0}', '\u{0}']), + ('\u{104fa}', ['\u{104d2}', '\u{0}', '\u{0}']), + ('\u{104fb}', ['\u{104d3}', '\u{0}', '\u{0}']), + ('\u{10597}', ['\u{10570}', '\u{0}', '\u{0}']), + ('\u{10598}', ['\u{10571}', '\u{0}', '\u{0}']), + ('\u{10599}', ['\u{10572}', '\u{0}', '\u{0}']), + ('\u{1059a}', ['\u{10573}', '\u{0}', '\u{0}']), + ('\u{1059b}', ['\u{10574}', '\u{0}', '\u{0}']), + ('\u{1059c}', ['\u{10575}', '\u{0}', '\u{0}']), + ('\u{1059d}', ['\u{10576}', '\u{0}', '\u{0}']), + ('\u{1059e}', ['\u{10577}', '\u{0}', '\u{0}']), + ('\u{1059f}', ['\u{10578}', '\u{0}', '\u{0}']), + ('\u{105a0}', ['\u{10579}', '\u{0}', '\u{0}']), + ('\u{105a1}', ['\u{1057a}', '\u{0}', '\u{0}']), + ('\u{105a3}', ['\u{1057c}', '\u{0}', '\u{0}']), + ('\u{105a4}', ['\u{1057d}', '\u{0}', '\u{0}']), + ('\u{105a5}', ['\u{1057e}', '\u{0}', '\u{0}']), + ('\u{105a6}', ['\u{1057f}', '\u{0}', '\u{0}']), + ('\u{105a7}', ['\u{10580}', '\u{0}', '\u{0}']), + ('\u{105a8}', ['\u{10581}', '\u{0}', '\u{0}']), + ('\u{105a9}', ['\u{10582}', '\u{0}', '\u{0}']), + ('\u{105aa}', ['\u{10583}', '\u{0}', '\u{0}']), + ('\u{105ab}', ['\u{10584}', '\u{0}', '\u{0}']), + ('\u{105ac}', ['\u{10585}', '\u{0}', '\u{0}']), + ('\u{105ad}', ['\u{10586}', '\u{0}', '\u{0}']), + ('\u{105ae}', ['\u{10587}', '\u{0}', '\u{0}']), + ('\u{105af}', ['\u{10588}', '\u{0}', '\u{0}']), + ('\u{105b0}', ['\u{10589}', '\u{0}', '\u{0}']), + ('\u{105b1}', ['\u{1058a}', '\u{0}', '\u{0}']), + ('\u{105b3}', ['\u{1058c}', '\u{0}', '\u{0}']), + ('\u{105b4}', ['\u{1058d}', '\u{0}', '\u{0}']), + ('\u{105b5}', ['\u{1058e}', '\u{0}', '\u{0}']), + ('\u{105b6}', ['\u{1058f}', '\u{0}', '\u{0}']), + ('\u{105b7}', ['\u{10590}', '\u{0}', '\u{0}']), + ('\u{105b8}', ['\u{10591}', '\u{0}', '\u{0}']), + ('\u{105b9}', ['\u{10592}', '\u{0}', '\u{0}']), + ('\u{105bb}', ['\u{10594}', '\u{0}', '\u{0}']), + ('\u{105bc}', ['\u{10595}', '\u{0}', '\u{0}']), + ('\u{10cc0}', ['\u{10c80}', '\u{0}', '\u{0}']), + ('\u{10cc1}', ['\u{10c81}', '\u{0}', '\u{0}']), + ('\u{10cc2}', ['\u{10c82}', '\u{0}', '\u{0}']), + ('\u{10cc3}', ['\u{10c83}', '\u{0}', '\u{0}']), + ('\u{10cc4}', ['\u{10c84}', '\u{0}', '\u{0}']), + ('\u{10cc5}', ['\u{10c85}', '\u{0}', '\u{0}']), + ('\u{10cc6}', ['\u{10c86}', '\u{0}', '\u{0}']), + ('\u{10cc7}', ['\u{10c87}', '\u{0}', '\u{0}']), + ('\u{10cc8}', ['\u{10c88}', '\u{0}', '\u{0}']), + ('\u{10cc9}', ['\u{10c89}', '\u{0}', '\u{0}']), + ('\u{10cca}', ['\u{10c8a}', '\u{0}', '\u{0}']), + ('\u{10ccb}', ['\u{10c8b}', '\u{0}', '\u{0}']), + ('\u{10ccc}', ['\u{10c8c}', '\u{0}', '\u{0}']), + ('\u{10ccd}', ['\u{10c8d}', '\u{0}', '\u{0}']), + ('\u{10cce}', ['\u{10c8e}', '\u{0}', '\u{0}']), + ('\u{10ccf}', ['\u{10c8f}', '\u{0}', '\u{0}']), + ('\u{10cd0}', ['\u{10c90}', '\u{0}', '\u{0}']), + ('\u{10cd1}', ['\u{10c91}', '\u{0}', '\u{0}']), + ('\u{10cd2}', ['\u{10c92}', '\u{0}', '\u{0}']), + ('\u{10cd3}', ['\u{10c93}', '\u{0}', '\u{0}']), + ('\u{10cd4}', ['\u{10c94}', '\u{0}', '\u{0}']), + ('\u{10cd5}', ['\u{10c95}', '\u{0}', '\u{0}']), + ('\u{10cd6}', ['\u{10c96}', '\u{0}', '\u{0}']), + ('\u{10cd7}', ['\u{10c97}', '\u{0}', '\u{0}']), + ('\u{10cd8}', ['\u{10c98}', '\u{0}', '\u{0}']), + ('\u{10cd9}', ['\u{10c99}', '\u{0}', '\u{0}']), + ('\u{10cda}', ['\u{10c9a}', '\u{0}', '\u{0}']), + ('\u{10cdb}', ['\u{10c9b}', '\u{0}', '\u{0}']), + ('\u{10cdc}', ['\u{10c9c}', '\u{0}', '\u{0}']), + ('\u{10cdd}', ['\u{10c9d}', '\u{0}', '\u{0}']), + ('\u{10cde}', ['\u{10c9e}', '\u{0}', '\u{0}']), + ('\u{10cdf}', ['\u{10c9f}', '\u{0}', '\u{0}']), + ('\u{10ce0}', ['\u{10ca0}', '\u{0}', '\u{0}']), + ('\u{10ce1}', ['\u{10ca1}', '\u{0}', '\u{0}']), + ('\u{10ce2}', ['\u{10ca2}', '\u{0}', '\u{0}']), + ('\u{10ce3}', ['\u{10ca3}', '\u{0}', '\u{0}']), + ('\u{10ce4}', ['\u{10ca4}', '\u{0}', '\u{0}']), + ('\u{10ce5}', ['\u{10ca5}', '\u{0}', '\u{0}']), + ('\u{10ce6}', ['\u{10ca6}', '\u{0}', '\u{0}']), + ('\u{10ce7}', ['\u{10ca7}', '\u{0}', '\u{0}']), + ('\u{10ce8}', ['\u{10ca8}', '\u{0}', '\u{0}']), + ('\u{10ce9}', ['\u{10ca9}', '\u{0}', '\u{0}']), + ('\u{10cea}', ['\u{10caa}', '\u{0}', '\u{0}']), + ('\u{10ceb}', ['\u{10cab}', '\u{0}', '\u{0}']), + ('\u{10cec}', ['\u{10cac}', '\u{0}', '\u{0}']), + ('\u{10ced}', ['\u{10cad}', '\u{0}', '\u{0}']), + ('\u{10cee}', ['\u{10cae}', '\u{0}', '\u{0}']), + ('\u{10cef}', ['\u{10caf}', '\u{0}', '\u{0}']), + ('\u{10cf0}', ['\u{10cb0}', '\u{0}', '\u{0}']), + ('\u{10cf1}', ['\u{10cb1}', '\u{0}', '\u{0}']), + ('\u{10cf2}', ['\u{10cb2}', '\u{0}', '\u{0}']), + ('\u{10d70}', ['\u{10d50}', '\u{0}', '\u{0}']), + ('\u{10d71}', ['\u{10d51}', '\u{0}', '\u{0}']), + ('\u{10d72}', ['\u{10d52}', '\u{0}', '\u{0}']), + ('\u{10d73}', ['\u{10d53}', '\u{0}', '\u{0}']), + ('\u{10d74}', ['\u{10d54}', '\u{0}', '\u{0}']), + ('\u{10d75}', ['\u{10d55}', '\u{0}', '\u{0}']), + ('\u{10d76}', ['\u{10d56}', '\u{0}', '\u{0}']), + ('\u{10d77}', ['\u{10d57}', '\u{0}', '\u{0}']), + ('\u{10d78}', ['\u{10d58}', '\u{0}', '\u{0}']), + ('\u{10d79}', ['\u{10d59}', '\u{0}', '\u{0}']), + ('\u{10d7a}', ['\u{10d5a}', '\u{0}', '\u{0}']), + ('\u{10d7b}', ['\u{10d5b}', '\u{0}', '\u{0}']), + ('\u{10d7c}', ['\u{10d5c}', '\u{0}', '\u{0}']), + ('\u{10d7d}', ['\u{10d5d}', '\u{0}', '\u{0}']), + ('\u{10d7e}', ['\u{10d5e}', '\u{0}', '\u{0}']), + ('\u{10d7f}', ['\u{10d5f}', '\u{0}', '\u{0}']), + ('\u{10d80}', ['\u{10d60}', '\u{0}', '\u{0}']), + ('\u{10d81}', ['\u{10d61}', '\u{0}', '\u{0}']), + ('\u{10d82}', ['\u{10d62}', '\u{0}', '\u{0}']), + ('\u{10d83}', ['\u{10d63}', '\u{0}', '\u{0}']), + ('\u{10d84}', ['\u{10d64}', '\u{0}', '\u{0}']), + ('\u{10d85}', ['\u{10d65}', '\u{0}', '\u{0}']), + ('\u{118c0}', ['\u{118a0}', '\u{0}', '\u{0}']), + ('\u{118c1}', ['\u{118a1}', '\u{0}', '\u{0}']), + ('\u{118c2}', ['\u{118a2}', '\u{0}', '\u{0}']), + ('\u{118c3}', ['\u{118a3}', '\u{0}', '\u{0}']), + ('\u{118c4}', ['\u{118a4}', '\u{0}', '\u{0}']), + ('\u{118c5}', ['\u{118a5}', '\u{0}', '\u{0}']), + ('\u{118c6}', ['\u{118a6}', '\u{0}', '\u{0}']), + ('\u{118c7}', ['\u{118a7}', '\u{0}', '\u{0}']), + ('\u{118c8}', ['\u{118a8}', '\u{0}', '\u{0}']), + ('\u{118c9}', ['\u{118a9}', '\u{0}', '\u{0}']), + ('\u{118ca}', ['\u{118aa}', '\u{0}', '\u{0}']), + ('\u{118cb}', ['\u{118ab}', '\u{0}', '\u{0}']), + ('\u{118cc}', ['\u{118ac}', '\u{0}', '\u{0}']), + ('\u{118cd}', ['\u{118ad}', '\u{0}', '\u{0}']), + ('\u{118ce}', ['\u{118ae}', '\u{0}', '\u{0}']), + ('\u{118cf}', ['\u{118af}', '\u{0}', '\u{0}']), + ('\u{118d0}', ['\u{118b0}', '\u{0}', '\u{0}']), + ('\u{118d1}', ['\u{118b1}', '\u{0}', '\u{0}']), + ('\u{118d2}', ['\u{118b2}', '\u{0}', '\u{0}']), + ('\u{118d3}', ['\u{118b3}', '\u{0}', '\u{0}']), + ('\u{118d4}', ['\u{118b4}', '\u{0}', '\u{0}']), + ('\u{118d5}', ['\u{118b5}', '\u{0}', '\u{0}']), + ('\u{118d6}', ['\u{118b6}', '\u{0}', '\u{0}']), + ('\u{118d7}', ['\u{118b7}', '\u{0}', '\u{0}']), + ('\u{118d8}', ['\u{118b8}', '\u{0}', '\u{0}']), + ('\u{118d9}', ['\u{118b9}', '\u{0}', '\u{0}']), + ('\u{118da}', ['\u{118ba}', '\u{0}', '\u{0}']), + ('\u{118db}', ['\u{118bb}', '\u{0}', '\u{0}']), + ('\u{118dc}', ['\u{118bc}', '\u{0}', '\u{0}']), + ('\u{118dd}', ['\u{118bd}', '\u{0}', '\u{0}']), + ('\u{118de}', ['\u{118be}', '\u{0}', '\u{0}']), + ('\u{118df}', ['\u{118bf}', '\u{0}', '\u{0}']), + ('\u{16e60}', ['\u{16e40}', '\u{0}', '\u{0}']), + ('\u{16e61}', ['\u{16e41}', '\u{0}', '\u{0}']), + ('\u{16e62}', ['\u{16e42}', '\u{0}', '\u{0}']), + ('\u{16e63}', ['\u{16e43}', '\u{0}', '\u{0}']), + ('\u{16e64}', ['\u{16e44}', '\u{0}', '\u{0}']), + ('\u{16e65}', ['\u{16e45}', '\u{0}', '\u{0}']), + ('\u{16e66}', ['\u{16e46}', '\u{0}', '\u{0}']), + ('\u{16e67}', ['\u{16e47}', '\u{0}', '\u{0}']), + ('\u{16e68}', ['\u{16e48}', '\u{0}', '\u{0}']), + ('\u{16e69}', ['\u{16e49}', '\u{0}', '\u{0}']), + ('\u{16e6a}', ['\u{16e4a}', '\u{0}', '\u{0}']), + ('\u{16e6b}', ['\u{16e4b}', '\u{0}', '\u{0}']), + ('\u{16e6c}', ['\u{16e4c}', '\u{0}', '\u{0}']), + ('\u{16e6d}', ['\u{16e4d}', '\u{0}', '\u{0}']), + ('\u{16e6e}', ['\u{16e4e}', '\u{0}', '\u{0}']), + ('\u{16e6f}', ['\u{16e4f}', '\u{0}', '\u{0}']), + ('\u{16e70}', ['\u{16e50}', '\u{0}', '\u{0}']), + ('\u{16e71}', ['\u{16e51}', '\u{0}', '\u{0}']), + ('\u{16e72}', ['\u{16e52}', '\u{0}', '\u{0}']), + ('\u{16e73}', ['\u{16e53}', '\u{0}', '\u{0}']), + ('\u{16e74}', ['\u{16e54}', '\u{0}', '\u{0}']), + ('\u{16e75}', ['\u{16e55}', '\u{0}', '\u{0}']), + ('\u{16e76}', ['\u{16e56}', '\u{0}', '\u{0}']), + ('\u{16e77}', ['\u{16e57}', '\u{0}', '\u{0}']), + ('\u{16e78}', ['\u{16e58}', '\u{0}', '\u{0}']), + ('\u{16e79}', ['\u{16e59}', '\u{0}', '\u{0}']), + ('\u{16e7a}', ['\u{16e5a}', '\u{0}', '\u{0}']), + ('\u{16e7b}', ['\u{16e5b}', '\u{0}', '\u{0}']), + ('\u{16e7c}', ['\u{16e5c}', '\u{0}', '\u{0}']), + ('\u{16e7d}', ['\u{16e5d}', '\u{0}', '\u{0}']), + ('\u{16e7e}', ['\u{16e5e}', '\u{0}', '\u{0}']), + ('\u{16e7f}', ['\u{16e5f}', '\u{0}', '\u{0}']), + ('\u{16ebb}', ['\u{16ea0}', '\u{0}', '\u{0}']), + ('\u{16ebc}', ['\u{16ea1}', '\u{0}', '\u{0}']), + ('\u{16ebd}', ['\u{16ea2}', '\u{0}', '\u{0}']), + ('\u{16ebe}', ['\u{16ea3}', '\u{0}', '\u{0}']), + ('\u{16ebf}', ['\u{16ea4}', '\u{0}', '\u{0}']), + ('\u{16ec0}', ['\u{16ea5}', '\u{0}', '\u{0}']), + ('\u{16ec1}', ['\u{16ea6}', '\u{0}', '\u{0}']), + ('\u{16ec2}', ['\u{16ea7}', '\u{0}', '\u{0}']), + ('\u{16ec3}', ['\u{16ea8}', '\u{0}', '\u{0}']), + ('\u{16ec4}', ['\u{16ea9}', '\u{0}', '\u{0}']), + ('\u{16ec5}', ['\u{16eaa}', '\u{0}', '\u{0}']), + ('\u{16ec6}', ['\u{16eab}', '\u{0}', '\u{0}']), + ('\u{16ec7}', ['\u{16eac}', '\u{0}', '\u{0}']), + ('\u{16ec8}', ['\u{16ead}', '\u{0}', '\u{0}']), + ('\u{16ec9}', ['\u{16eae}', '\u{0}', '\u{0}']), + ('\u{16eca}', ['\u{16eaf}', '\u{0}', '\u{0}']), + ('\u{16ecb}', ['\u{16eb0}', '\u{0}', '\u{0}']), + ('\u{16ecc}', ['\u{16eb1}', '\u{0}', '\u{0}']), + ('\u{16ecd}', ['\u{16eb2}', '\u{0}', '\u{0}']), + ('\u{16ece}', ['\u{16eb3}', '\u{0}', '\u{0}']), + ('\u{16ecf}', ['\u{16eb4}', '\u{0}', '\u{0}']), + ('\u{16ed0}', ['\u{16eb5}', '\u{0}', '\u{0}']), + ('\u{16ed1}', ['\u{16eb6}', '\u{0}', '\u{0}']), + ('\u{16ed2}', ['\u{16eb7}', '\u{0}', '\u{0}']), + ('\u{16ed3}', ['\u{16eb8}', '\u{0}', '\u{0}']), + ('\u{1e922}', ['\u{1e900}', '\u{0}', '\u{0}']), + ('\u{1e923}', ['\u{1e901}', '\u{0}', '\u{0}']), + ('\u{1e924}', ['\u{1e902}', '\u{0}', '\u{0}']), + ('\u{1e925}', ['\u{1e903}', '\u{0}', '\u{0}']), + ('\u{1e926}', ['\u{1e904}', '\u{0}', '\u{0}']), + ('\u{1e927}', ['\u{1e905}', '\u{0}', '\u{0}']), + ('\u{1e928}', ['\u{1e906}', '\u{0}', '\u{0}']), + ('\u{1e929}', ['\u{1e907}', '\u{0}', '\u{0}']), + ('\u{1e92a}', ['\u{1e908}', '\u{0}', '\u{0}']), + ('\u{1e92b}', ['\u{1e909}', '\u{0}', '\u{0}']), + ('\u{1e92c}', ['\u{1e90a}', '\u{0}', '\u{0}']), + ('\u{1e92d}', ['\u{1e90b}', '\u{0}', '\u{0}']), + ('\u{1e92e}', ['\u{1e90c}', '\u{0}', '\u{0}']), + ('\u{1e92f}', ['\u{1e90d}', '\u{0}', '\u{0}']), + ('\u{1e930}', ['\u{1e90e}', '\u{0}', '\u{0}']), + ('\u{1e931}', ['\u{1e90f}', '\u{0}', '\u{0}']), + ('\u{1e932}', ['\u{1e910}', '\u{0}', '\u{0}']), + ('\u{1e933}', ['\u{1e911}', '\u{0}', '\u{0}']), + ('\u{1e934}', ['\u{1e912}', '\u{0}', '\u{0}']), + ('\u{1e935}', ['\u{1e913}', '\u{0}', '\u{0}']), + ('\u{1e936}', ['\u{1e914}', '\u{0}', '\u{0}']), + ('\u{1e937}', ['\u{1e915}', '\u{0}', '\u{0}']), + ('\u{1e938}', ['\u{1e916}', '\u{0}', '\u{0}']), + ('\u{1e939}', ['\u{1e917}', '\u{0}', '\u{0}']), + ('\u{1e93a}', ['\u{1e918}', '\u{0}', '\u{0}']), + ('\u{1e93b}', ['\u{1e919}', '\u{0}', '\u{0}']), + ('\u{1e93c}', ['\u{1e91a}', '\u{0}', '\u{0}']), + ('\u{1e93d}', ['\u{1e91b}', '\u{0}', '\u{0}']), + ('\u{1e93e}', ['\u{1e91c}', '\u{0}', '\u{0}']), + ('\u{1e93f}', ['\u{1e91d}', '\u{0}', '\u{0}']), + ('\u{1e940}', ['\u{1e91e}', '\u{0}', '\u{0}']), + ('\u{1e941}', ['\u{1e91f}', '\u{0}', '\u{0}']), + ('\u{1e942}', ['\u{1e920}', '\u{0}', '\u{0}']), + ('\u{1e943}', ['\u{1e921}', '\u{0}', '\u{0}']), +]; diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 6ab99ae799d70..f4c51a4870634 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -374,6 +374,7 @@ impl Step for UnicodeTableGenerator { fn run(self, builder: &Builder<'_>) { let mut cmd = builder.tool_cmd(Tool::UnicodeTableGenerator); cmd.arg(builder.src.join("library/core/src/unicode/unicode_data.rs")); + cmd.arg(builder.src.join("library/coretests/tests/unicode/test_data.rs")); cmd.run(builder); } } diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index c2c5650136959..78f63b5673a72 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -207,26 +207,23 @@ fn load_data() -> UnicodeData { } fn main() { - let write_location = std::env::args().nth(1).unwrap_or_else(|| { - eprintln!("Must provide path to write unicode tables to"); + let args = std::env::args().collect::>(); + + if args.len() != 3 { + eprintln!("Must provide paths to write unicode tables and tests to"); eprintln!( - "e.g. {} library/core/src/unicode/unicode_data.rs", - std::env::args().next().unwrap_or_default() + "e.g. {} library/core/src/unicode/unicode_data.rs library/coretests/tests/unicode/test_data.rs", + args[0] ); std::process::exit(1); - }); + } - // Optional test path, which is a Rust source file testing that the unicode - // property lookups are correct. - let test_path = std::env::args().nth(2); + let data_path = &args[1]; + let test_path = &args[2]; let unicode_data = load_data(); let ranges_by_property = &unicode_data.ranges; - if let Some(path) = test_path { - std::fs::write(&path, generate_tests(&unicode_data)).unwrap(); - } - let mut table_file = String::new(); writeln!( table_file, @@ -279,8 +276,12 @@ fn main() { writeln!(table_file, "}}\n"); } - std::fs::write(&write_location, table_file).unwrap(); - rustfmt(&write_location); + let test_file = generate_tests(&unicode_data); + + std::fs::write(&test_path, test_file).unwrap(); + std::fs::write(&data_path, table_file).unwrap(); + rustfmt(&data_path); + rustfmt(&test_path); } fn rustfmt(path: &str) { @@ -303,79 +304,67 @@ fn version() -> String { } fn generate_tests(data: &UnicodeData) -> String { - let mut s = format!( - "#![feature(core_intrinsics)] - #![allow(internal_features, dead_code)] - // ignore-tidy-filelength - mod rt; - mod unicode_data; - fn main() {{" + let mut s = String::new(); + writeln!( + s, + "//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!" ); + writeln!(s, "// ignore-tidy-filelength\n"); + writeln!(s, "use std::ops::RangeInclusive;\n"); for (property, ranges) in &data.ranges { - let prop = property.to_lowercase(); - let (is_true, is_false): (Vec<_>, Vec<_>) = (char::MIN..=char::MAX) + let prop_upper = property.to_uppercase(); + let is_true = (char::MIN..=char::MAX) .filter(|c| !c.is_ascii()) .map(u32::from) - .partition(|c| ranges.iter().any(|r| r.contains(c))); + .filter(|c| ranges.iter().any(|r| r.contains(c))) + .collect::>(); + let is_true = ranges_from_set(&is_true); + let is_true = is_true + .iter() + .map(|r| { + let start = char::from_u32(r.start).unwrap(); + let end = char::from_u32(r.end - 1).unwrap(); + CharEscape(start)..=CharEscape(end) + }) + .collect::>(); writeln!( s, - "println!(\"Testing {prop}\"); - {prop}_true(); - {prop}_false(); - fn {prop}_true() {{\n{}\n}} - fn {prop}_false() {{\n{}\n}}", - generate_asserts(&prop, &is_true, true), - generate_asserts(&prop, &is_false, false) + r#" +#[rustfmt::skip] +pub(super) static {prop_upper}: &[RangeInclusive; {is_true_len}] = &[{is_true}]; +"#, + is_true_len = is_true.len(), + is_true = fmt_list(is_true), ); } - for (name, conversion) in ["to_lower", "to_upper"].iter().zip([&data.to_lower, &data.to_upper]) + for (prop_lower, conversion) in + ["to_lower", "to_upper"].iter().zip([&data.to_lower, &data.to_upper]) { - writeln!(s, r#"println!("Testing {name}");"#); - for (c, mapping) in conversion { - let c = char::from_u32(*c).unwrap(); - let mapping = mapping.map(|c| char::from_u32(c).unwrap()); - writeln!(s, "assert_eq!(unicode_data::conversions::{name}({c:?}), {mapping:?});"); - } - let unmapped: Vec<_> = (char::MIN..=char::MAX) - .filter(|c| !c.is_ascii()) - .map(u32::from) - .filter(|c| !conversion.contains_key(c)) - .collect(); - let unmapped_ranges = ranges_from_set(&unmapped); - for range in unmapped_ranges { - let start = char::from_u32(range.start).unwrap(); - let end = char::from_u32(range.end - 1).unwrap(); - writeln!( - s, - r#"for c in {start:?}..={end:?} {{ - assert_eq!(unicode_data::conversions::{name}(c), [c, '\0', '\0']); - }}"# - ); - } - } + let prop_upper = prop_lower.to_uppercase(); + + let mapped = conversion + .iter() + .map(|(c, chars)| { + ( + CharEscape(char::from_u32(*c).unwrap()), + chars.map(|c| CharEscape(char::from_u32(c).unwrap())), + ) + }) + .collect::>(); - writeln!(s, "}}"); - s -} - -fn generate_asserts(prop: &str, points: &[u32], truthy: bool) -> String { - let mut s = String::new(); - let truthy = if truthy { "" } else { "!" }; - for range in ranges_from_set(points) { - let start = char::from_u32(range.start).unwrap(); - let end = char::from_u32(range.end - 1).unwrap(); - match range.len() { - 1 => writeln!(s, "assert!({truthy}unicode_data::{prop}::lookup({start:?}));"), - _ => writeln!( - s, - "for c in {start:?}..={end:?} {{ - assert!({truthy}unicode_data::{prop}::lookup(c)); - }}" - ), - } + writeln!( + s, + r#" +#[rustfmt::skip] +pub(super) static {prop_upper}: &[(char, [char; 3]); {mapped_len}] = &[{mapped}]; +"#, + mapped_len = mapped.len(), + mapped = fmt_list(mapped), + ); } + s } From 23edbb67bd832d187b6052fba515bd23b45479d7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:29:32 +0000 Subject: [PATCH 31/45] Don't require dlltool with the dummy backend on MinGW The dummy backend should be able to cross-compile to any target without requiring any external tool or library other than the rust standard library. --- compiler/rustc_interface/src/util.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index c9fdb61e9c2cb..5aacf1f8d960e 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -7,7 +7,7 @@ use std::{env, thread}; use rustc_ast as ast; use rustc_attr_parsing::{ShouldEmit, validate_attr}; -use rustc_codegen_ssa::back::archive::ArArchiveBuilderBuilder; +use rustc_codegen_ssa::back::archive::{ArArchiveBuilderBuilder, ArchiveBuilderBuilder}; use rustc_codegen_ssa::back::link::link_binary; use rustc_codegen_ssa::target_features::{self, cfg_target_feature}; use rustc_codegen_ssa::traits::CodegenBackend; @@ -440,7 +440,7 @@ impl CodegenBackend for DummyCodegenBackend { link_binary( sess, - &ArArchiveBuilderBuilder, + &DummyArchiveBuilderBuilder, codegen_results, metadata, outputs, @@ -449,6 +449,28 @@ impl CodegenBackend for DummyCodegenBackend { } } +struct DummyArchiveBuilderBuilder; + +impl ArchiveBuilderBuilder for DummyArchiveBuilderBuilder { + fn new_archive_builder<'a>( + &self, + sess: &'a Session, + ) -> Box { + ArArchiveBuilderBuilder.new_archive_builder(sess) + } + + fn create_dll_import_lib( + &self, + sess: &Session, + _lib_name: &str, + _items: Vec, + output_path: &Path, + ) { + // Build an empty static library to avoid calling an external dlltool on mingw + ArArchiveBuilderBuilder.new_archive_builder(sess).build(output_path); + } +} + // This is used for rustdoc, but it uses similar machinery to codegen backend // loading, so we leave the code here. It is potentially useful for other tools // that want to invoke the rustc binary while linking to rustc as well. From 04a10f76106a5f80cfebb596bf2c762d6c6c8626 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 27 Oct 2025 14:34:57 +0100 Subject: [PATCH 32/45] Simplify code to generate line numbers in highlight --- src/librustdoc/html/highlight.rs | 56 +++++++++++++++++++------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index c37736f137df9..1a59456a5322e 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -343,7 +343,7 @@ struct TokenHandler<'a, 'tcx, F: Write> { /// We need to keep the `Class` for each element because it could contain a `Span` which is /// used to generate links. href_context: Option>, - write_line_number: fn(u32) -> String, + write_line_number: LineNumberKind, line: u32, max_lines: u32, } @@ -355,10 +355,10 @@ impl std::fmt::Debug for TokenHandler<'_, '_, F> { } impl<'a, F: Write> TokenHandler<'a, '_, F> { - fn handle_backline(&mut self) -> Option { + fn handle_backline(&mut self) -> Option> { self.line += 1; if self.line < self.max_lines { - return Some((self.write_line_number)(self.line)); + return Some(self.write_line_number.render(self.line)); } None } @@ -376,8 +376,7 @@ impl<'a, F: Write> TokenHandler<'a, '_, F> { if text == "\n" && let Some(backline) = self.handle_backline() { - self.out.write_str(&text).unwrap(); - self.out.write_str(&backline).unwrap(); + write!(self.out, "{text}{backline}").unwrap(); } else { self.push_token_without_backline_check(class, text, true); } @@ -437,20 +436,29 @@ impl Drop for TokenHandler<'_, '_, F> { } } -fn scraped_line_number(line: u32) -> String { - // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr - // Do not show "1 2 3 4 5 ..." in web search results. - format!("{line}") -} - -fn line_number(line: u32) -> String { - // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr - // Do not show "1 2 3 4 5 ..." in web search results. - format!("{line}") +/// Represents line numbers to be generated as HTML. +#[derive(Clone, Copy)] +enum LineNumberKind { + /// Used for scraped code examples. + Scraped, + /// Used for source code pages. + Normal, + /// Code examples in documentation don't have line number generated by rustdoc. + Empty, } -fn empty_line_number(_: u32) -> String { - String::new() +impl LineNumberKind { + fn render(self, line: u32) -> impl Display { + fmt::from_fn(move |f| { + match self { + // https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr + // Do not show "1 2 3 4 5 ..." in web search results. + Self::Scraped => write!(f, "{line}"), + Self::Normal => write!(f, "{line}"), + Self::Empty => Ok(()), + } + }) + } } fn get_next_expansion( @@ -537,12 +545,12 @@ pub(super) fn write_code( write_line_number: match line_info { Some(line_info) => { if line_info.is_scraped_example { - scraped_line_number + LineNumberKind::Scraped } else { - line_number + LineNumberKind::Normal } } - None => empty_line_number, + None => LineNumberKind::Empty, }, line: 0, max_lines: u32::MAX, @@ -552,8 +560,12 @@ pub(super) fn write_code( if let Some(line_info) = line_info { token_handler.line = line_info.start_line - 1; token_handler.max_lines = line_info.max_lines; - if let Some(text) = token_handler.handle_backline() { - token_handler.push_token_without_backline_check(None, Cow::Owned(text), false); + if let Some(backline) = token_handler.handle_backline() { + token_handler.push_token_without_backline_check( + None, + Cow::Owned(backline.to_string()), + false, + ); } } From e1e8913d858abe71bb2ad03c265e07783500c04f Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Fri, 31 Oct 2025 11:41:36 -0400 Subject: [PATCH 33/45] bootstrap: Use cargo's `build.warnings=deny` rather than -Dwarnings This has two major advantages. First, it makes us less dependent on the rustc shim, which is nice but not super important. More importantly, it gives us much nicer caching properties. Previously, `x build --warnings warn && x build --warnings deny` would rebuild all of bootstrap, and if there were any warnings emitted on the last build of the compiler, they would *not* fail the build, because cargo would cache the output rather than rerunning the shim. After this change, bootstrap rebuilds instantly, and cargo knows that it should fail the build but *without* invalidating the cache. Here is an example of rebuilding bootstrap after a switch from warn->deny: ``` INFO: Downloading and building bootstrap before processing --help command. See src/bootstrap/README.md for help with common commands. Building bootstrap Compiling bootstrap v0.0.0 (/Users/jyn/src/ferrocene3/src/bootstrap) warning: unused variable: `x` --> src/bootstrap/src/core/builder/mod.rs:1792:13 | 1792 | let x: (); | ^ | = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default help: if this is intentional, prefix it with an underscore | 1792 | let _x: (); | + help: you might have meant to pattern match on the similarly named constant `_` | 1792 - let x: (); 1792 + let utils::render_tests::_: (); | warning: `bootstrap` (lib) generated 1 warning (run `cargo fix --lib -p bootstrap` to apply 1 suggestion) Finished `dev` profile [unoptimized] target(s) in 5.14s error: warnings are denied by `build.warnings` configuration failed to run: /Users/jyn/src/ferrocene3/build/aarch64-apple-darwin/stage0/bin/cargo build --jobs=default --manifest-path /Users/jyn/src/ferrocene3/src/bootstrap/Cargo.toml -Zroot-dir=/Users/jyn/src/ferrocene3 -Zwarnings ``` building the compiler from scratch with `deny`: https://gist.github.com/jyn514/493ed26c2aa6f61bf47c21e75efa2175 and rebuilding the compiler after switching from deny->warn (note that it reuses the whole cache, there are no invalidations): ``` $ x c compiler Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.15s Checking stage1 compiler artifacts{rustc-main, rustc_abi, rustc_arena, rustc_ast, rustc_ast_ir, rustc_ast_lowering, rustc_ast_passes, rustc_ast_pretty, rustc_attr_parsing, rustc_baked_icu_data, rustc_borrowck, rustc_builtin_macros, rustc_codegen_llvm, rustc_codegen_ssa, rustc_const_eval, rustc_data_structures, rustc_driver, rustc_driver_impl, rustc_error_codes, rustc_error_messages, rustc_errors, rustc_expand, rustc_feature, rustc_fluent_macro, rustc_fs_util, rustc_graphviz, rustc_hashes, rustc_hir, rustc_hir_analysis, rustc_hir_id, rustc_hir_pretty, rustc_hir_typeck, rustc_incremental, rustc_index, rustc_index_macros, rustc_infer, rustc_interface, rustc_lexer, rustc_lint, rustc_lint_defs, rustc_llvm, rustc_log, rustc_macros, rustc_metadata, rustc_middle, rustc_mir_build, rustc_mir_dataflow, rustc_mir_transform, rustc_monomorphize, rustc_next_trait_solver, rustc_parse, rustc_parse_format, rustc_passes, rustc_pattern_analysis, rustc_privacy, rustc_proc_macro, rustc_public, rustc_public_bridge, rustc_query_impl, rustc_query_system, rustc_resolve, rustc_sanitizers, rustc_serialize, rustc_session, rustc_span, rustc_symbol_mangling, rustc_target, rustc_thread_pool, rustc_trait_selection, rustc_traits, rustc_transmute, rustc_ty_utils, rustc_type_ir, rustc_type_ir_macros, rustc_windows_rc} (stage0 -> stage1, aarch64-apple-darwin) warning: function `foo` is never used --> compiler/rustc_hashes/src/lib.rs:16:4 | 16 | fn foo() {} | ^^^ | = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default warning: `rustc_hashes` (lib) generated 1 warning Finished `release` profile [optimized + debuginfo] target(s) in 0.53s Build completed successfully in 0:00:08 ``` --- src/bootstrap/bootstrap.py | 32 ++++++++++++------------- src/bootstrap/bootstrap_test.py | 10 ++++---- src/bootstrap/src/core/builder/cargo.rs | 11 +++++++-- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 4dd465edb0df9..2e16f2cf27e7b 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1113,6 +1113,19 @@ def build_bootstrap_cmd(self, env): else: env["RUSTFLAGS"] = "-Zallow-features=" + if not os.path.isfile(self.cargo()): + raise Exception("no cargo executable found at `{}`".format(self.cargo())) + args = [ + self.cargo(), + "build", + "--jobs=" + self.jobs, + "--manifest-path", + os.path.join(self.rust_root, "src/bootstrap/Cargo.toml"), + "-Zroot-dir=" + self.rust_root, + ] + # verbose cargo output is very noisy, so only enable it with -vv + args.extend("--verbose" for _ in range(self.verbose - 1)) + target_features = [] if self.get_toml("crt-static", build_section) == "true": target_features += ["+crt-static"] @@ -1131,28 +1144,15 @@ def build_bootstrap_cmd(self, env): else: deny_warnings = self.warnings == "deny" if deny_warnings: - env["RUSTFLAGS"] += " -Dwarnings" + args += ["-Zwarnings"] + env["CARGO_BUILD_WARNINGS"] = "deny" # Add RUSTFLAGS_BOOTSTRAP to RUSTFLAGS for bootstrap compilation. # Note that RUSTFLAGS_BOOTSTRAP should always be added to the end of - # RUSTFLAGS to be actually effective (e.g., if we have `-Dwarnings` in - # RUSTFLAGS, passing `-Awarnings` from RUSTFLAGS_BOOTSTRAP should override it). + # RUSTFLAGS, since that causes RUSTFLAGS_BOOTSTRAP to override RUSTFLAGS. if "RUSTFLAGS_BOOTSTRAP" in env: env["RUSTFLAGS"] += " " + env["RUSTFLAGS_BOOTSTRAP"] - if not os.path.isfile(self.cargo()): - raise Exception("no cargo executable found at `{}`".format(self.cargo())) - args = [ - self.cargo(), - "build", - "--jobs=" + self.jobs, - "--manifest-path", - os.path.join(self.rust_root, "src/bootstrap/Cargo.toml"), - "-Zroot-dir=" + self.rust_root, - ] - # verbose cargo output is very noisy, so only enable it with -vv - args.extend("--verbose" for _ in range(self.verbose - 1)) - if "BOOTSTRAP_TRACING" in env: args.append("--features=tracing") diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 9e12982a43dc3..1dbe997d23f3a 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -244,8 +244,10 @@ def test_warnings(self): if toml_warnings is not None: configure_args = ["--set", "rust.deny-warnings=" + toml_warnings] - _, env = self.build_args(configure_args, args=["--warnings=warn"]) - self.assertFalse("-Dwarnings" in env["RUSTFLAGS"]) + args, env = self.build_args(configure_args, args=["--warnings=warn"]) + self.assertFalse("CARGO_BUILD_WARNINGS" in env) + self.assertFalse("-Zwarnings" in args) - _, env = self.build_args(configure_args, args=["--warnings=deny"]) - self.assertTrue("-Dwarnings" in env["RUSTFLAGS"]) + args, env = self.build_args(configure_args, args=["--warnings=deny"]) + self.assertEqual("deny", env["CARGO_BUILD_WARNINGS"]) + self.assertTrue("-Zwarnings" in args) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index c2029f97391d4..76eb03c8d499d 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -459,6 +459,11 @@ impl Builder<'_> { let out_dir = self.stage_out(compiler, mode); cargo.env("CARGO_TARGET_DIR", &out_dir); + // Set this unconditionally. Cargo silently ignores `CARGO_BUILD_WARNINGS` when `-Z + // warnings` isn't present, which is hard to debug, and it's not worth the effort to keep + // them in sync. + cargo.arg("-Zwarnings"); + // Bootstrap makes a lot of assumptions about the artifacts produced in the target // directory. If users override the "build directory" using `build-dir` // (https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-dir), then @@ -1159,8 +1164,10 @@ impl Builder<'_> { lint_flags.push("-Wunused_lifetimes"); if self.config.deny_warnings { - lint_flags.push("-Dwarnings"); - rustdocflags.arg("-Dwarnings"); + // We use this instead of `lint_flags` so that we don't have to rebuild all + // workspace dependencies when `deny-warnings` changes, but we still get an error + // immediately instead of having to wait until the next rebuild. + cargo.env("CARGO_BUILD_WARNINGS", "deny"); } rustdocflags.arg("-Wrustdoc::invalid_codeblock_attributes"); From 5fabd2da1c0665a80eb6c5cc339208b200ffa35e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 31 Oct 2025 17:32:42 +0100 Subject: [PATCH 34/45] Improve code --- src/librustdoc/html/highlight.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 1a59456a5322e..0363418f91647 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -343,7 +343,7 @@ struct TokenHandler<'a, 'tcx, F: Write> { /// We need to keep the `Class` for each element because it could contain a `Span` which is /// used to generate links. href_context: Option>, - write_line_number: LineNumberKind, + line_number_kind: LineNumberKind, line: u32, max_lines: u32, } @@ -358,7 +358,7 @@ impl<'a, F: Write> TokenHandler<'a, '_, F> { fn handle_backline(&mut self) -> Option> { self.line += 1; if self.line < self.max_lines { - return Some(self.write_line_number.render(self.line)); + return Some(self.line_number_kind.render(self.line)); } None } @@ -436,7 +436,7 @@ impl Drop for TokenHandler<'_, '_, F> { } } -/// Represents line numbers to be generated as HTML. +/// Represents the type of line number to be generated as HTML. #[derive(Clone, Copy)] enum LineNumberKind { /// Used for scraped code examples. @@ -542,7 +542,7 @@ pub(super) fn write_code( let mut token_handler = TokenHandler { out, href_context, - write_line_number: match line_info { + line_number_kind: match line_info { Some(line_info) => { if line_info.is_scraped_example { LineNumberKind::Scraped From efb9a41f0ecdf432b9e163806d6714f53f090bd8 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Fri, 31 Oct 2025 13:47:57 -0400 Subject: [PATCH 35/45] cleanup: upstream dropped amx-transpose functionality See also LLVM change 5322fb626820. Looks like this was just removed entirely. --- compiler/rustc_target/src/target_features.rs | 1 - library/std_detect/src/detect/arch/x86.rs | 3 --- library/std_detect/src/detect/os/x86.rs | 1 - library/std_detect/tests/x86-specific.rs | 1 - tests/ui/check-cfg/target_feature.stderr | 1 - 5 files changed, 7 deletions(-) diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index dc70089c385fe..288ee6357a510 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -386,7 +386,6 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]), - ("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]), ("apxf", Unstable(sym::apx_target_feature), &[]), ("avx", Stable, &["sse4.2"]), ("avx2", Stable, &["avx"]), diff --git a/library/std_detect/src/detect/arch/x86.rs b/library/std_detect/src/detect/arch/x86.rs index bd749b88f566d..e4318bedb2a6f 100644 --- a/library/std_detect/src/detect/arch/x86.rs +++ b/library/std_detect/src/detect/arch/x86.rs @@ -93,7 +93,6 @@ features! { /// * `"amx-fp8"` /// * `"amx-movrs"` /// * `"amx-tf32"` - /// * `"amx-transpose"` /// * `"f16c"` /// * `"fma"` /// * `"bmi1"` @@ -231,8 +230,6 @@ features! { /// AMX-MOVRS (Matrix MOVERS operations) @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_tf32: "amx-tf32"; /// AMX-TF32 (TensorFloat32 Operations) - @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_transpose: "amx-transpose"; - /// AMX-TRANSPOSE (Matrix Transpose Operations) @FEATURE: #[unstable(feature = "apx_target_feature", issue = "139284")] apxf: "apxf"; /// APX-F (Advanced Performance Extensions - Foundation) @FEATURE: #[unstable(feature = "avx10_target_feature", issue = "138843")] avx10_1: "avx10.1"; diff --git a/library/std_detect/src/detect/os/x86.rs b/library/std_detect/src/detect/os/x86.rs index cf11d8333127f..18925da2b2755 100644 --- a/library/std_detect/src/detect/os/x86.rs +++ b/library/std_detect/src/detect/os/x86.rs @@ -285,7 +285,6 @@ pub(crate) fn detect_features() -> cache::Initializer { unsafe { __cpuid_count(0x1e_u32, 1) }; enable(amx_feature_flags_eax, 4, Feature::amx_fp8); - enable(amx_feature_flags_eax, 5, Feature::amx_transpose); enable(amx_feature_flags_eax, 6, Feature::amx_tf32); enable(amx_feature_flags_eax, 7, Feature::amx_avx512); enable(amx_feature_flags_eax, 8, Feature::amx_movrs); diff --git a/library/std_detect/tests/x86-specific.rs b/library/std_detect/tests/x86-specific.rs index 2ed2bb2a99ecd..90ca32208e78d 100644 --- a/library/std_detect/tests/x86-specific.rs +++ b/library/std_detect/tests/x86-specific.rs @@ -76,7 +76,6 @@ fn dump() { println!("widekl: {:?}", is_x86_feature_detected!("widekl")); println!("movrs: {:?}", is_x86_feature_detected!("movrs")); println!("amx-fp8: {:?}", is_x86_feature_detected!("amx-fp8")); - println!("amx-transpose: {:?}", is_x86_feature_detected!("amx-transpose")); println!("amx-tf32: {:?}", is_x86_feature_detected!("amx-tf32")); println!("amx-avx512: {:?}", is_x86_feature_detected!("amx-avx512")); println!("amx-movrs: {:?}", is_x86_feature_detected!("amx-movrs")); diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 258f21324661b..d25e7f094964e 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -27,7 +27,6 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `amx-movrs` `amx-tf32` `amx-tile` -`amx-transpose` `apxf` `atomics` `avx` From af5b7981acc3d8ed39e4a65f3d92eb211ba1d34c Mon Sep 17 00:00:00 2001 From: Kyuuhachi Date: Thu, 16 Oct 2025 19:14:51 +0200 Subject: [PATCH 36/45] Add Ord::clamp_min and clamp_max Add example clamping by length Implement clamp_min/max on floats Fix copypaste mistakes in tests --- library/core/src/cmp.rs | 48 ++++++++++++++++++++++++++++++++++++ library/core/src/num/f128.rs | 48 ++++++++++++++++++++++++++++++++++++ library/core/src/num/f16.rs | 48 ++++++++++++++++++++++++++++++++++++ library/core/src/num/f32.rs | 44 +++++++++++++++++++++++++++++++++ library/core/src/num/f64.rs | 44 +++++++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 7f369d19c3d12..872597992fc16 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1096,6 +1096,54 @@ pub const trait Ord: [const] Eq + [const] PartialOrd + PointeeSized { self } } + + /// Restricts a value to a maximum bound. + /// + /// Returns `max` if `self` is greater than `max`, otherwise returns `self`. + /// + /// This is identical to `min`, but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_min_max)] + /// assert_eq!(12.clamp_max(10), 10); + /// assert_eq!(4.clamp_max(7), 4); + /// let s = "hello"; + /// assert_eq!(&s[..32.clamp_max(s.len())], s); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "clamp_min_max", issue = "147781")] + fn clamp_max(self, min: Self) -> Self + where + Self: Sized + [const] Destruct, + { + self.min(min) + } + + /// Restricts a value to a minimum bound. + /// + /// Returns `min` if `self` is less than `min`, otherwise returns `self`. + /// + /// This is identical to `max`, but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_min_max)] + /// assert_eq!((-3).clamp_min(0), 0); + /// assert_eq!(4.clamp_min(0), 4); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "clamp_min_max", issue = "147781")] + fn clamp_min(self, min: Self) -> Self + where + Self: Sized + [const] Destruct, + { + self.max(min) + } } /// Derive macro generating an impl of the trait [`Ord`]. diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index e7101537b298f..ee702b86adda7 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1276,6 +1276,54 @@ impl f128 { self } + /// Restrict a value to a maximum bound. + /// + /// Returns `max` if `self` is greater than `max`. Otherwise this returns `self`. If either `self` or `max` is NaN, the other is returned. + /// + /// This is identical to [`f128::min`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128, clamp_min_max)] + /// assert_eq!((3.0f128).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f128).clamp_max(1.0), 0.0); + /// assert_eq!((f128::NAN).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f128).clamp_max(f128::NAN), 0.0); + /// ``` + #[inline] + #[unstable(feature = "f128", issue = "116909")] + // #[unstable(feature = "clamp_min_max", issue = "147781")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn clamp_max(self, max: f128) -> f128 { + self.min(max) + } + + /// Restrict a value to a minimum bound. + /// + /// Returns `min` if `self` is less than `min`. Otherwise this returns `self`. If either `self` or `min` is NaN, the other is returned. + /// + /// This is identical to [`f128::max`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128, clamp_min_max)] + /// assert_eq!((-3.0f128).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f128).clamp_min(-2.0), 0.0); + /// assert_eq!((f128::NAN).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f128).clamp_min(f128::NAN), 0.0); + /// ``` + #[inline] + #[unstable(feature = "f128", issue = "116909")] + // #[unstable(feature = "clamp_min_max", issue = "147781")] + #[rustc_const_unstable(feature = "f128", issue = "116909")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn clamp_min(self, min: f128) -> f128 { + self.max(min) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index aa8342a22ad58..9c29696fbfe05 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1254,6 +1254,54 @@ impl f16 { self } + /// Restrict a value to a maximum bound. + /// + /// Returns `max` if `self` is greater than `max`. Otherwise this returns `self`. If either `self` or `max` is NaN, the other is returned. + /// + /// This is identical to [`f16::min`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16, clamp_min_max)] + /// assert_eq!((3.0f16).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f16).clamp_max(1.0), 0.0); + /// assert_eq!((f16::NAN).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f16).clamp_max(f16::NAN), 0.0); + /// ``` + #[inline] + #[unstable(feature = "f16", issue = "116909")] + // #[unstable(feature = "clamp_min_max", issue = "147781")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn clamp_max(self, max: f16) -> f16 { + self.min(max) + } + + /// Restrict a value to a minimum bound. + /// + /// Returns `min` if `self` is less than `min`. Otherwise this returns `self`. If either `self` or `min` is NaN, the other is returned. + /// + /// This is identical to [`f16::max`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16, clamp_min_max)] + /// assert_eq!((-3.0f16).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f16).clamp_min(-2.0), 0.0); + /// assert_eq!((f16::NAN).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f16).clamp_min(f16::NAN), 0.0); + /// ``` + #[inline] + #[unstable(feature = "f16", issue = "116909")] + // #[unstable(feature = "clamp_min_max", issue = "147781")] + #[rustc_const_unstable(feature = "f16", issue = "116909")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn clamp_min(self, min: f16) -> f16 { + self.max(min) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 3070e1dedbe43..8041d2d0a4b41 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1431,6 +1431,50 @@ impl f32 { self } + /// Restrict a value to a maximum bound. + /// + /// Returns `max` if `self` is greater than `max`. Otherwise this returns `self`. If either `self` or `max` is NaN, the other is returned. + /// + /// This is identical to [`f32::min`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_min_max)] + /// assert_eq!((3.0f32).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f32).clamp_max(1.0), 0.0); + /// assert_eq!((f32::NAN).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f32).clamp_max(f32::NAN), 0.0); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[unstable(feature = "clamp_min_max", issue = "147781")] + #[inline] + pub const fn clamp_max(self, max: f32) -> f32 { + self.min(max) + } + + /// Restrict a value to a minimum bound. + /// + /// Returns `min` if `self` is less than `min`. Otherwise this returns `self`. If either `self` or `min` is NaN, the other is returned. + /// + /// This is identical to [`f32::max`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_min_max)] + /// assert_eq!((-3.0f32).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f32).clamp_min(-2.0), 0.0); + /// assert_eq!((f32::NAN).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f32).clamp_min(f32::NAN), 0.0); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[unstable(feature = "clamp_min_max", issue = "147781")] + #[inline] + pub const fn clamp_min(self, min: f32) -> f32 { + self.max(min) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index dc8ccc551b2da..1623fd25e6fec 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1429,6 +1429,50 @@ impl f64 { self } + /// Restrict a value to a maximum bound. + /// + /// Returns `max` if `self` is greater than `max`. Otherwise this returns `self`. If either `self` or `max` is NaN, the other is returned. + /// + /// This is identical to [`f64::min`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_min_max)] + /// assert_eq!((3.0f64).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f64).clamp_max(1.0), 0.0); + /// assert_eq!((f64::NAN).clamp_max(1.0), 1.0); + /// assert_eq!((0.0f64).clamp_max(f64::NAN), 0.0); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[unstable(feature = "clamp_min_max", issue = "147781")] + #[inline] + pub const fn clamp_max(self, max: f64) -> f64 { + self.min(max) + } + + /// Restrict a value to a minimum bound. + /// + /// Returns `min` if `self` is less than `min`. Otherwise this returns `self`. If either `self` or `min` is NaN, the other is returned. + /// + /// This is identical to [`f64::max`], but is easier to read when using method call syntax. + /// + /// # Examples + /// + /// ``` + /// #![feature(clamp_min_max)] + /// assert_eq!((-3.0f64).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f64).clamp_min(-2.0), 0.0); + /// assert_eq!((f64::NAN).clamp_min(-2.0), -2.0); + /// assert_eq!((0.0f64).clamp_min(f64::NAN), 0.0); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[unstable(feature = "clamp_min_max", issue = "147781")] + #[inline] + pub const fn clamp_min(self, min: f64) -> f64 { + self.max(min) + } + /// Computes the absolute value of `self`. /// /// This function always returns the precise result. From 7069400c477c71609928024dc9a3416eb1336041 Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Fri, 31 Oct 2025 14:49:45 -0400 Subject: [PATCH 37/45] revert combined nonpoison/poison tests for condvar Setup for writing different tests for the `nonpoison::Condvar` since it will have a different API. Signed-off-by: Connor Tsui --- library/std/tests/sync/condvar.rs | 472 ++++++++++++++---------------- 1 file changed, 226 insertions(+), 246 deletions(-) diff --git a/library/std/tests/sync/condvar.rs b/library/std/tests/sync/condvar.rs index 42b880e283afe..74328793caeae 100644 --- a/library/std/tests/sync/condvar.rs +++ b/library/std/tests/sync/condvar.rs @@ -17,256 +17,237 @@ nonpoison_and_poison_unwrap_test!( } ); +#[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: notify_one, - test_body: { - use locks::{Condvar, Mutex}; +fn notify_one() { + use std::sync::{Condvar, Mutex}; - let m = Arc::new(Mutex::new(())); - let m2 = m.clone(); - let c = Arc::new(Condvar::new()); - let c2 = c.clone(); + let m = Arc::new(Mutex::new(())); + let m2 = m.clone(); + let c = Arc::new(Condvar::new()); + let c2 = c.clone(); - let g = maybe_unwrap(m.lock()); - let _t = thread::spawn(move || { - let _g = maybe_unwrap(m2.lock()); - c2.notify_one(); - }); - let g = maybe_unwrap(c.wait(g)); - drop(g); - } -); + let g = m.lock().unwrap(); + let _t = thread::spawn(move || { + let _g = m2.lock().unwrap(); + c2.notify_one(); + }); -#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: notify_all, - test_body: { - use locks::{Condvar, Mutex}; - - const N: usize = 10; - - let data = Arc::new((Mutex::new(0), Condvar::new())); - let (tx, rx) = channel(); - for _ in 0..N { - let data = data.clone(); - let tx = tx.clone(); - thread::spawn(move || { - let &(ref lock, ref cond) = &*data; - let mut cnt = maybe_unwrap(lock.lock()); - *cnt += 1; - if *cnt == N { - tx.send(()).unwrap(); - } - while *cnt != 0 { - cnt = maybe_unwrap(cond.wait(cnt)); - } - tx.send(()).unwrap(); - }); - } - drop(tx); - - let &(ref lock, ref cond) = &*data; - rx.recv().unwrap(); - let mut cnt = maybe_unwrap(lock.lock()); - *cnt = 0; - cond.notify_all(); - drop(cnt); - - for _ in 0..N { - rx.recv().unwrap(); - } - } -); + let g = c.wait(g).unwrap(); + drop(g); +} +#[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: test_mutex_arc_condvar, - test_body: { - use locks::{Condvar, Mutex}; - - struct Packet(Arc<(Mutex, Condvar)>); +fn notify_all() { + use std::sync::{Condvar, Mutex}; - let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); - let packet2 = Packet(packet.0.clone()); + const N: usize = 10; - let (tx, rx) = channel(); - - let _t = thread::spawn(move || { - // Wait until our parent has taken the lock. - rx.recv().unwrap(); - let &(ref lock, ref cvar) = &*packet2.0; - - // Set the data to `true` and wake up our parent. - let mut guard = maybe_unwrap(lock.lock()); - *guard = true; - cvar.notify_one(); + let data = Arc::new((Mutex::new(0), Condvar::new())); + let (tx, rx) = channel(); + for _ in 0..N { + let data = data.clone(); + let tx = tx.clone(); + thread::spawn(move || { + let &(ref lock, ref cond) = &*data; + let mut cnt = lock.lock().unwrap(); + *cnt += 1; + if *cnt == N { + tx.send(()).unwrap(); + } + while *cnt != 0 { + cnt = cond.wait(cnt).unwrap(); + } + tx.send(()).unwrap(); }); + } + drop(tx); - let &(ref lock, ref cvar) = &*packet.0; - let mut guard = maybe_unwrap(lock.lock()); - // Wake up our child. - tx.send(()).unwrap(); + let &(ref lock, ref cond) = &*data; + rx.recv().unwrap(); + let mut cnt = lock.lock().unwrap(); + *cnt = 0; + cond.notify_all(); + drop(cnt); - // Wait until our child has set the data to `true`. - assert!(!*guard); - while !*guard { - guard = maybe_unwrap(cvar.wait(guard)); - } + for _ in 0..N { + rx.recv().unwrap(); } -); +} +#[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: wait_while, - test_body: { - use locks::{Condvar, Mutex}; +fn test_mutex_arc_condvar() { + use std::sync::{Condvar, Mutex}; - let pair = Arc::new((Mutex::new(false), Condvar::new())); - let pair2 = pair.clone(); + struct Packet(Arc<(Mutex, Condvar)>); - // Inside of our lock, spawn a new thread, and then wait for it to start. - thread::spawn(move || { - let &(ref lock, ref cvar) = &*pair2; - let mut started = maybe_unwrap(lock.lock()); - *started = true; - // We notify the condvar that the value has changed. - cvar.notify_one(); - }); + let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); + let packet2 = Packet(packet.0.clone()); - // Wait for the thread to start up. - let &(ref lock, ref cvar) = &*pair; - let guard = cvar.wait_while(maybe_unwrap(lock.lock()), |started| !*started); - assert!(*maybe_unwrap(guard)); + let (tx, rx) = channel(); + + let _t = thread::spawn(move || { + // Wait until our parent has taken the lock. + rx.recv().unwrap(); + let &(ref lock, ref cvar) = &*packet2.0; + + // Set the data to `true` and wake up our parent. + let mut guard = lock.lock().unwrap(); + *guard = true; + cvar.notify_one(); + }); + + let &(ref lock, ref cvar) = &*packet.0; + let mut guard = lock.lock().unwrap(); + // Wake up our child. + tx.send(()).unwrap(); + + // Wait until our child has set the data to `true`. + assert!(!*guard); + while !*guard { + guard = cvar.wait(guard).unwrap(); } -); +} +#[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: wait_timeout_wait, - test_body: { - use locks::{Condvar, Mutex}; - - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); - - loop { - let g = maybe_unwrap(m.lock()); - let (_g, no_timeout) = maybe_unwrap(c.wait_timeout(g, Duration::from_millis(1))); - // spurious wakeups mean this isn't necessarily true - // so execute test again, if not timeout - if !no_timeout.timed_out() { - continue; - } - - break; +fn wait_while() { + use std::sync::{Condvar, Mutex}; + + let pair = Arc::new((Mutex::new(false), Condvar::new())); + let pair2 = pair.clone(); + + // Inside of our lock, spawn a new thread, and then wait for it to start. + thread::spawn(move || { + let &(ref lock, ref cvar) = &*pair2; + let mut started = lock.lock().unwrap(); + *started = true; + // We notify the condvar that the value has changed. + cvar.notify_one(); + }); + + // Wait for the thread to start up. + let &(ref lock, ref cvar) = &*pair; + let guard = cvar.wait_while(lock.lock().unwrap(), |started| !*started).unwrap(); + assert!(*guard); +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn wait_timeout_wait() { + use std::sync::{Condvar, Mutex}; + + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + loop { + let g = m.lock().unwrap(); + let (_g, no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap(); + // spurious wakeups mean this isn't necessarily true + // so execute test again, if not timeout + if !no_timeout.timed_out() { + continue; } + + break; } -); +} +#[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: wait_timeout_while_wait, - test_body: { - use locks::{Condvar, Mutex}; +fn wait_timeout_while_wait() { + use std::sync::{Condvar, Mutex}; - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); - let g = maybe_unwrap(m.lock()); - let (_g, wait) = maybe_unwrap(c.wait_timeout_while(g, Duration::from_millis(1), |_| true)); - // no spurious wakeups. ensure it timed-out - assert!(wait.timed_out()); - } -); + let g = m.lock().unwrap(); + let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(1), |_| true).unwrap(); + // no spurious wakeups. ensure it timed-out + assert!(wait.timed_out()); +} +#[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: wait_timeout_while_instant_satisfy, - test_body: { - use locks::{Condvar, Mutex}; +fn wait_timeout_while_instant_satisfy() { + use std::sync::{Condvar, Mutex}; - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); - let g = maybe_unwrap(m.lock()); - let (_g, wait) = - maybe_unwrap(c.wait_timeout_while(g, Duration::from_millis(0), |_| false)); - // ensure it didn't time-out even if we were not given any time. - assert!(!wait.timed_out()); - } -); + let g = m.lock().unwrap(); + let (_g, wait) = c.wait_timeout_while(g, Duration::from_millis(0), |_| false).unwrap(); + // ensure it didn't time-out even if we were not given any time. + assert!(!wait.timed_out()); +} +#[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: wait_timeout_while_wake, - test_body: { - use locks::{Condvar, Mutex}; +fn wait_timeout_while_wake() { + use std::sync::{Condvar, Mutex}; + + let pair = Arc::new((Mutex::new(false), Condvar::new())); + let pair_copy = pair.clone(); + + let &(ref m, ref c) = &*pair; + let g = m.lock().unwrap(); + let _t = thread::spawn(move || { + let &(ref lock, ref cvar) = &*pair_copy; + let mut started = lock.lock().unwrap(); + thread::sleep(Duration::from_millis(1)); + *started = true; + cvar.notify_one(); + }); + + let (g2, wait) = c + .wait_timeout_while(g, Duration::from_millis(u64::MAX), |&mut notified| !notified) + .unwrap(); + // ensure it didn't time-out even if we were not given any time. + assert!(!wait.timed_out()); + assert!(*g2); +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn wait_timeout_wake() { + use std::sync::{Condvar, Mutex}; - let pair = Arc::new((Mutex::new(false), Condvar::new())); - let pair_copy = pair.clone(); + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); - let &(ref m, ref c) = &*pair; - let g = maybe_unwrap(m.lock()); - let _t = thread::spawn(move || { - let &(ref lock, ref cvar) = &*pair_copy; - let mut started = maybe_unwrap(lock.lock()); - thread::sleep(Duration::from_millis(1)); - *started = true; - cvar.notify_one(); - }); - let (g2, wait) = maybe_unwrap(c.wait_timeout_while( - g, - Duration::from_millis(u64::MAX), - |&mut notified| !notified - )); - // ensure it didn't time-out even if we were not given any time. - assert!(!wait.timed_out()); - assert!(*g2); - } -); + loop { + let g = m.lock().unwrap(); -#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -nonpoison_and_poison_unwrap_test!( - name: wait_timeout_wake, - test_body: { - use locks::{Condvar, Mutex}; + let c2 = c.clone(); + let m2 = m.clone(); - let m = Arc::new(Mutex::new(())); - let c = Arc::new(Condvar::new()); + let notified = Arc::new(AtomicBool::new(false)); + let notified_copy = notified.clone(); - loop { - let g = maybe_unwrap(m.lock()); - - let c2 = c.clone(); - let m2 = m.clone(); - - let notified = Arc::new(AtomicBool::new(false)); - let notified_copy = notified.clone(); - - let t = thread::spawn(move || { - let _g = maybe_unwrap(m2.lock()); - thread::sleep(Duration::from_millis(1)); - notified_copy.store(true, Ordering::Relaxed); - c2.notify_one(); - }); - let (g, timeout_res) = - maybe_unwrap(c.wait_timeout(g, Duration::from_millis(u64::MAX))); - assert!(!timeout_res.timed_out()); - // spurious wakeups mean this isn't necessarily true - // so execute test again, if not notified - if !notified.load(Ordering::Relaxed) { - t.join().unwrap(); - continue; - } - drop(g); + let t = thread::spawn(move || { + let _g = m2.lock().unwrap(); + thread::sleep(Duration::from_millis(1)); + notified_copy.store(true, Ordering::Relaxed); + c2.notify_one(); + }); + let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap(); + assert!(!timeout_res.timed_out()); + // spurious wakeups mean this isn't necessarily true + // so execute test again, if not notified + if !notified.load(Ordering::Relaxed) { t.join().unwrap(); - - break; + continue; } + drop(g); + + t.join().unwrap(); + + break; } -); +} // Some platforms internally cast the timeout duration into nanoseconds. // If they fail to consider overflow during the conversion (I'm looking @@ -274,42 +255,41 @@ nonpoison_and_poison_unwrap_test!( // timeout for durations that are slightly longer than u64::MAX nanoseconds. // `std` should guard against this by clamping the timeout. // See #37440 for context. -nonpoison_and_poison_unwrap_test!( - name: timeout_nanoseconds, - test_body: { - use locks::Mutex; - use locks::Condvar; +#[test] +fn timeout_nanoseconds() { + use std::sync::{Condvar, Mutex}; + + let sent = Mutex::new(false); + let cond = Condvar::new(); + + thread::scope(|s| { + s.spawn(|| { + // Sleep so that the other thread has a chance to encounter the + // timeout. + thread::sleep(Duration::from_secs(2)); + *sent.lock().unwrap() = true; + cond.notify_all(); + }); - let sent = Mutex::new(false); - let cond = Condvar::new(); - - thread::scope(|s| { - s.spawn(|| { - // Sleep so that the other thread has a chance to encounter the - // timeout. - thread::sleep(Duration::from_secs(2)); - maybe_unwrap(sent.set(true)); - cond.notify_all(); - }); - - let mut guard = maybe_unwrap(sent.lock()); - // Loop until `sent` is set by the thread to guard against spurious - // wakeups. If the `wait_timeout` happens just before the signal by - // the other thread, such a spurious wakeup might prevent the - // miscalculated timeout from occurring, but this is basically just - // a smoke test anyway. - loop { - if *guard { - break; - } - - // If there is internal overflow, this call will return almost - // immediately, before the other thread has reached the `notify_all`, - // and indicate a timeout. - let (g, res) = maybe_unwrap(cond.wait_timeout(guard, Duration::from_secs(u64::MAX.div_ceil(1_000_000_000)))); - assert!(!res.timed_out()); - guard = g; + let mut guard = sent.lock().unwrap(); + // Loop until `sent` is set by the thread to guard against spurious + // wakeups. If the `wait_timeout` happens just before the signal by + // the other thread, such a spurious wakeup might prevent the + // miscalculated timeout from occurring, but this is basically just + // a smoke test anyway. + loop { + if *guard { + break; } - }) - } -); + + // If there is internal overflow, this call will return almost + // immediately, before the other thread has reached the `notify_all`, + // and indicate a timeout. + let (g, res) = cond + .wait_timeout(guard, Duration::from_secs(u64::MAX.div_ceil(1_000_000_000))) + .unwrap(); + assert!(!res.timed_out()); + guard = g; + } + }) +} From 3d5a40809c8322de933205a4d581059dc8adc3f3 Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Fri, 31 Oct 2025 15:12:46 -0400 Subject: [PATCH 38/45] update `nonpoison::Condvar` to take guards by reference Since non-poisoning `Condvar` take non-poisoing `Mutex`es when `wait`ing, we do not need to take by ownership since a poison error cannot occur while we wait. Signed-off-by: Connor Tsui --- library/std/src/sync/barrier.rs | 2 +- library/std/src/sync/nonpoison/condvar.rs | 71 +++-- library/std/tests/sync/condvar.rs | 309 ++++++++++++++++++++-- 3 files changed, 324 insertions(+), 58 deletions(-) diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs index 8988126bd90c0..c2c18889dde7d 100644 --- a/library/std/src/sync/barrier.rs +++ b/library/std/src/sync/barrier.rs @@ -125,7 +125,7 @@ impl Barrier { let local_gen = lock.generation_id; lock.count += 1; if lock.count < self.num_threads { - let _guard = self.cvar.wait_while(lock, |state| local_gen == state.generation_id); + self.cvar.wait_while(&mut lock, |state| local_gen == state.generation_id); BarrierWaitResult(false) } else { lock.count = 0; diff --git a/library/std/src/sync/nonpoison/condvar.rs b/library/std/src/sync/nonpoison/condvar.rs index 994fc6816a0d0..d2b251d7c44c1 100644 --- a/library/std/src/sync/nonpoison/condvar.rs +++ b/library/std/src/sync/nonpoison/condvar.rs @@ -1,4 +1,5 @@ use crate::fmt; +use crate::ops::DerefMut; use crate::sync::WaitTimeoutResult; use crate::sync::nonpoison::{MutexGuard, mutex}; use crate::sys::sync as sys; @@ -38,7 +39,7 @@ use crate::time::{Duration, Instant}; /// let (lock, cvar) = &*pair; /// let mut started = lock.lock(); /// while !*started { -/// started = cvar.wait(started); +/// cvar.wait(&mut started); /// } /// ``` /// @@ -115,16 +116,15 @@ impl Condvar { /// let mut started = lock.lock(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { - /// started = cvar.wait(started); + /// cvar.wait(&mut started); /// } /// ``` #[unstable(feature = "nonpoison_condvar", issue = "134645")] - pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> { + pub fn wait(&self, guard: &mut MutexGuard<'_, T>) { unsafe { - let lock = mutex::guard_lock(&guard); + let lock = mutex::guard_lock(guard); self.inner.wait(lock); } - guard } /// Blocks the current thread until the provided condition becomes false. @@ -167,21 +167,17 @@ impl Condvar { /// // Wait for the thread to start up. /// let (lock, cvar) = &*pair; /// // As long as the value inside the `Mutex` is `true`, we wait. - /// let _guard = cvar.wait_while(lock.lock(), |pending| { *pending }); + /// let mut guard = lock.lock(); + /// cvar.wait_while(&mut guard, |pending| { *pending }); /// ``` #[unstable(feature = "nonpoison_condvar", issue = "134645")] - pub fn wait_while<'a, T, F>( - &self, - mut guard: MutexGuard<'a, T>, - mut condition: F, - ) -> MutexGuard<'a, T> + pub fn wait_while(&self, guard: &mut MutexGuard<'_, T>, mut condition: F) where F: FnMut(&mut T) -> bool, { - while condition(&mut *guard) { - guard = self.wait(guard); + while condition(guard.deref_mut()) { + self.wait(guard); } - guard } /// Waits on this condition variable for a notification, timing out after a @@ -206,7 +202,7 @@ impl Condvar { /// The returned [`WaitTimeoutResult`] value indicates if the timeout is /// known to have elapsed. /// - /// Like [`wait`], the lock specified will be re-acquired when this function + /// Like [`wait`], the lock specified will have been re-acquired when this function /// returns, regardless of whether the timeout elapsed or not. /// /// [`wait`]: Self::wait @@ -239,9 +235,8 @@ impl Condvar { /// let mut started = lock.lock(); /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { - /// let result = cvar.wait_timeout(started, Duration::from_millis(10)); + /// let result = cvar.wait_timeout(&mut started, Duration::from_millis(10)); /// // 10 milliseconds have passed, or maybe the value changed! - /// started = result.0; /// if *started == true { /// // We received the notification and the value has been updated, we can leave. /// break @@ -249,16 +244,16 @@ impl Condvar { /// } /// ``` #[unstable(feature = "nonpoison_condvar", issue = "134645")] - pub fn wait_timeout<'a, T>( + pub fn wait_timeout( &self, - guard: MutexGuard<'a, T>, + guard: &mut MutexGuard<'_, T>, dur: Duration, - ) -> (MutexGuard<'a, T>, WaitTimeoutResult) { + ) -> WaitTimeoutResult { let success = unsafe { - let lock = mutex::guard_lock(&guard); + let lock = mutex::guard_lock(guard); self.inner.wait_timeout(lock, dur) }; - (guard, WaitTimeoutResult(!success)) + WaitTimeoutResult(!success) } /// Waits on this condition variable for a notification, timing out after a @@ -277,7 +272,7 @@ impl Condvar { /// The returned [`WaitTimeoutResult`] value indicates if the timeout is /// known to have elapsed without the condition being met. /// - /// Like [`wait_while`], the lock specified will be re-acquired when this + /// Like [`wait_while`], the lock specified will have been re-acquired when this /// function returns, regardless of whether the timeout elapsed or not. /// /// [`wait_while`]: Self::wait_while @@ -307,37 +302,39 @@ impl Condvar { /// /// // wait for the thread to start up /// let (lock, cvar) = &*pair; + /// let mut guard = lock.lock(); /// let result = cvar.wait_timeout_while( - /// lock.lock(), + /// &mut guard, /// Duration::from_millis(100), /// |&mut pending| pending, /// ); - /// if result.1.timed_out() { + /// if result.timed_out() { /// // timed-out without the condition ever evaluating to false. /// } - /// // access the locked mutex via result.0 + /// // access the locked mutex via guard /// ``` #[unstable(feature = "nonpoison_condvar", issue = "134645")] - pub fn wait_timeout_while<'a, T, F>( + pub fn wait_timeout_while( &self, - mut guard: MutexGuard<'a, T>, + guard: &mut MutexGuard<'_, T>, dur: Duration, mut condition: F, - ) -> (MutexGuard<'a, T>, WaitTimeoutResult) + ) -> WaitTimeoutResult where F: FnMut(&mut T) -> bool, { let start = Instant::now(); - loop { - if !condition(&mut *guard) { - return (guard, WaitTimeoutResult(false)); - } + + while condition(guard.deref_mut()) { let timeout = match dur.checked_sub(start.elapsed()) { Some(timeout) => timeout, - None => return (guard, WaitTimeoutResult(true)), + None => return WaitTimeoutResult(true), }; - guard = self.wait_timeout(guard, timeout).0; + + self.wait_timeout(guard, timeout); } + + WaitTimeoutResult(false) } /// Wakes up one blocked thread on this condvar. @@ -378,7 +375,7 @@ impl Condvar { /// let mut started = lock.lock(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { - /// started = cvar.wait(started); + /// cvar.wait(&mut started); /// } /// ``` #[unstable(feature = "nonpoison_condvar", issue = "134645")] @@ -422,7 +419,7 @@ impl Condvar { /// let mut started = lock.lock(); /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { - /// started = cvar.wait(started); + /// cvar.wait(&mut started); /// } /// ``` #[unstable(feature = "nonpoison_condvar", issue = "134645")] diff --git a/library/std/tests/sync/condvar.rs b/library/std/tests/sync/condvar.rs index 74328793caeae..a52e0a00caf48 100644 --- a/library/std/tests/sync/condvar.rs +++ b/library/std/tests/sync/condvar.rs @@ -19,8 +19,8 @@ nonpoison_and_poison_unwrap_test!( #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn notify_one() { - use std::sync::{Condvar, Mutex}; +fn poison_notify_one() { + use std::sync::poison::{Condvar, Mutex}; let m = Arc::new(Mutex::new(())); let m2 = m.clone(); @@ -39,8 +39,28 @@ fn notify_one() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn notify_all() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_notify_one() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let m = Arc::new(Mutex::new(())); + let m2 = m.clone(); + let c = Arc::new(Condvar::new()); + let c2 = c.clone(); + + let mut g = m.lock(); + let _t = thread::spawn(move || { + let _g = m2.lock(); + c2.notify_one(); + }); + + c.wait(&mut g); + drop(g); +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_notify_all() { + use std::sync::poison::{Condvar, Mutex}; const N: usize = 10; @@ -78,8 +98,47 @@ fn notify_all() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn test_mutex_arc_condvar() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_notify_all() { + use std::sync::nonpoison::{Condvar, Mutex}; + + const N: usize = 10; + + let data = Arc::new((Mutex::new(0), Condvar::new())); + let (tx, rx) = channel(); + for _ in 0..N { + let data = data.clone(); + let tx = tx.clone(); + thread::spawn(move || { + let &(ref lock, ref cond) = &*data; + let mut cnt = lock.lock(); + *cnt += 1; + if *cnt == N { + tx.send(()).unwrap(); + } + while *cnt != 0 { + cond.wait(&mut cnt); + } + tx.send(()).unwrap(); + }); + } + drop(tx); + + let &(ref lock, ref cond) = &*data; + rx.recv().unwrap(); + let mut cnt = lock.lock(); + *cnt = 0; + cond.notify_all(); + drop(cnt); + + for _ in 0..N { + rx.recv().unwrap(); + } +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_test_mutex_arc_condvar() { + use std::sync::poison::{Condvar, Mutex}; struct Packet(Arc<(Mutex, Condvar)>); @@ -113,8 +172,43 @@ fn test_mutex_arc_condvar() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn wait_while() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_test_mutex_arc_condvar() { + use std::sync::nonpoison::{Condvar, Mutex}; + + struct Packet(Arc<(Mutex, Condvar)>); + + let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); + let packet2 = Packet(packet.0.clone()); + + let (tx, rx) = channel(); + + let _t = thread::spawn(move || { + // Wait until our parent has taken the lock. + rx.recv().unwrap(); + let &(ref lock, ref cvar) = &*packet2.0; + + // Set the data to `true` and wake up our parent. + let mut guard = lock.lock(); + *guard = true; + cvar.notify_one(); + }); + + let &(ref lock, ref cvar) = &*packet.0; + let mut guard = lock.lock(); + // Wake up our child. + tx.send(()).unwrap(); + + // Wait until our child has set the data to `true`. + assert!(!*guard); + while !*guard { + cvar.wait(&mut guard); + } +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_wait_while() { + use std::sync::poison::{Condvar, Mutex}; let pair = Arc::new((Mutex::new(false), Condvar::new())); let pair2 = pair.clone(); @@ -136,8 +230,32 @@ fn wait_while() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn wait_timeout_wait() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_wait_while() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let pair = Arc::new((Mutex::new(false), Condvar::new())); + let pair2 = pair.clone(); + + // Inside of our lock, spawn a new thread, and then wait for it to start. + thread::spawn(move || { + let &(ref lock, ref cvar) = &*pair2; + let mut started = lock.lock(); + *started = true; + // We notify the condvar that the value has changed. + cvar.notify_one(); + }); + + // Wait for the thread to start up. + let &(ref lock, ref cvar) = &*pair; + let mut guard = lock.lock(); + cvar.wait_while(&mut guard, |started| !*started); + assert!(*guard); +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_wait_timeout_wait() { + use std::sync::poison::{Condvar, Mutex}; let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -157,8 +275,29 @@ fn wait_timeout_wait() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn wait_timeout_while_wait() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_wait_timeout_wait() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + loop { + let mut g = m.lock(); + let no_timeout = c.wait_timeout(&mut g, Duration::from_millis(1)); + // spurious wakeups mean this isn't necessarily true + // so execute test again, if not timeout + if !no_timeout.timed_out() { + continue; + } + + break; + } +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_wait_timeout_while_wait() { + use std::sync::poison::{Condvar, Mutex}; let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -171,8 +310,22 @@ fn wait_timeout_while_wait() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn wait_timeout_while_instant_satisfy() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_wait_timeout_while_wait() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + let mut g = m.lock(); + let wait = c.wait_timeout_while(&mut g, Duration::from_millis(1), |_| true); + // no spurious wakeups. ensure it timed-out + assert!(wait.timed_out()); +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_wait_timeout_while_instant_satisfy() { + use std::sync::poison::{Condvar, Mutex}; let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -185,8 +338,22 @@ fn wait_timeout_while_instant_satisfy() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn wait_timeout_while_wake() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_wait_timeout_while_instant_satisfy() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + let mut g = m.lock(); + let wait = c.wait_timeout_while(&mut g, Duration::from_millis(0), |_| false); + // ensure it didn't time-out even if we were not given any time. + assert!(!wait.timed_out()); +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_wait_timeout_while_wake() { + use std::sync::poison::{Condvar, Mutex}; let pair = Arc::new((Mutex::new(false), Condvar::new())); let pair_copy = pair.clone(); @@ -211,8 +378,33 @@ fn wait_timeout_while_wake() { #[test] #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. -fn wait_timeout_wake() { - use std::sync::{Condvar, Mutex}; +fn nonpoison_wait_timeout_while_wake() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let pair = Arc::new((Mutex::new(false), Condvar::new())); + let pair_copy = pair.clone(); + + let &(ref m, ref c) = &*pair; + let mut g = m.lock(); + let _t = thread::spawn(move || { + let &(ref lock, ref cvar) = &*pair_copy; + let mut started = lock.lock(); + thread::sleep(Duration::from_millis(1)); + *started = true; + cvar.notify_one(); + }); + + let wait = + c.wait_timeout_while(&mut g, Duration::from_millis(u64::MAX), |&mut notified| !notified); + // ensure it didn't time-out even if we were not given any time. + assert!(!wait.timed_out()); + assert!(*g); +} + +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn poison_wait_timeout_wake() { + use std::sync::poison::{Condvar, Mutex}; let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -249,6 +441,46 @@ fn wait_timeout_wake() { } } +#[test] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads. +fn nonpoison_wait_timeout_wake() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let m = Arc::new(Mutex::new(())); + let c = Arc::new(Condvar::new()); + + loop { + let mut g = m.lock(); + + let c2 = c.clone(); + let m2 = m.clone(); + + let notified = Arc::new(AtomicBool::new(false)); + let notified_copy = notified.clone(); + + let t = thread::spawn(move || { + let _g = m2.lock(); + thread::sleep(Duration::from_millis(1)); + notified_copy.store(true, Ordering::Relaxed); + c2.notify_one(); + }); + + let timeout_res = c.wait_timeout(&mut g, Duration::from_millis(u64::MAX)); + assert!(!timeout_res.timed_out()); + // spurious wakeups mean this isn't necessarily true + // so execute test again, if not notified + if !notified.load(Ordering::Relaxed) { + t.join().unwrap(); + continue; + } + drop(g); + + t.join().unwrap(); + + break; + } +} + // Some platforms internally cast the timeout duration into nanoseconds. // If they fail to consider overflow during the conversion (I'm looking // at you, macOS), `wait_timeout` will return immediately and indicate a @@ -256,8 +488,8 @@ fn wait_timeout_wake() { // `std` should guard against this by clamping the timeout. // See #37440 for context. #[test] -fn timeout_nanoseconds() { - use std::sync::{Condvar, Mutex}; +fn poison_timeout_nanoseconds() { + use std::sync::poison::{Condvar, Mutex}; let sent = Mutex::new(false); let cond = Condvar::new(); @@ -293,3 +525,40 @@ fn timeout_nanoseconds() { } }) } + +#[test] +fn nonpoison_timeout_nanoseconds() { + use std::sync::nonpoison::{Condvar, Mutex}; + + let sent = Mutex::new(false); + let cond = Condvar::new(); + + thread::scope(|s| { + s.spawn(|| { + // Sleep so that the other thread has a chance to encounter the + // timeout. + thread::sleep(Duration::from_secs(2)); + sent.set(true); + cond.notify_all(); + }); + + let mut guard = sent.lock(); + // Loop until `sent` is set by the thread to guard against spurious + // wakeups. If the `wait_timeout` happens just before the signal by + // the other thread, such a spurious wakeup might prevent the + // miscalculated timeout from occurring, but this is basically just + // a smoke test anyway. + loop { + if *guard { + break; + } + + // If there is internal overflow, this call will return almost + // immediately, before the other thread has reached the `notify_all`, + // and indicate a timeout. + let res = cond + .wait_timeout(&mut guard, Duration::from_secs(u64::MAX.div_ceil(1_000_000_000))); + assert!(!res.timed_out()); + } + }) +} From c1153b08ff87d09ab043bf1878cfb3f1cf55c8ec Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Fri, 31 Oct 2025 15:14:21 -0400 Subject: [PATCH 39/45] move condvar test from mutex to condvar test file Signed-off-by: Connor Tsui --- library/std/tests/sync/condvar.rs | 34 +++++++++++++++++++++++++++++++ library/std/tests/sync/mutex.rs | 34 +------------------------------ 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/library/std/tests/sync/condvar.rs b/library/std/tests/sync/condvar.rs index a52e0a00caf48..e5a7ad8f9b331 100644 --- a/library/std/tests/sync/condvar.rs +++ b/library/std/tests/sync/condvar.rs @@ -562,3 +562,37 @@ fn nonpoison_timeout_nanoseconds() { } }) } + +#[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] +fn test_arc_condvar_poison() { + use std::sync::poison::{Condvar, Mutex}; + + struct Packet(Arc<(Mutex, Condvar)>); + + let packet = Packet(Arc::new((Mutex::new(1), Condvar::new()))); + let packet2 = Packet(packet.0.clone()); + let (tx, rx) = channel(); + + let _t = thread::spawn(move || -> () { + rx.recv().unwrap(); + let &(ref lock, ref cvar) = &*packet2.0; + let _g = lock.lock().unwrap(); + cvar.notify_one(); + // Parent should fail when it wakes up. + panic!(); + }); + + let &(ref lock, ref cvar) = &*packet.0; + let mut lock = lock.lock().unwrap(); + tx.send(()).unwrap(); + while *lock == 1 { + match cvar.wait(lock) { + Ok(l) => { + lock = l; + assert_eq!(*lock, 1); + } + Err(..) => break, + } + } +} diff --git a/library/std/tests/sync/mutex.rs b/library/std/tests/sync/mutex.rs index ff6aef717936f..75a6bf64607ef 100644 --- a/library/std/tests/sync/mutex.rs +++ b/library/std/tests/sync/mutex.rs @@ -3,7 +3,7 @@ use std::ops::FnMut; use std::panic::{self, AssertUnwindSafe}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::channel; -use std::sync::{Arc, Condvar, MappedMutexGuard, Mutex, MutexGuard, TryLockError}; +use std::sync::{Arc, MappedMutexGuard, Mutex, MutexGuard, TryLockError}; use std::{hint, mem, thread}; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -423,38 +423,6 @@ fn test_replace_poison() { inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20)); } -#[test] -#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] -fn test_arc_condvar_poison() { - struct Packet(Arc<(Mutex, Condvar)>); - - let packet = Packet(Arc::new((Mutex::new(1), Condvar::new()))); - let packet2 = Packet(packet.0.clone()); - let (tx, rx) = channel(); - - let _t = thread::spawn(move || -> () { - rx.recv().unwrap(); - let &(ref lock, ref cvar) = &*packet2.0; - let _g = lock.lock().unwrap(); - cvar.notify_one(); - // Parent should fail when it wakes up. - panic!(); - }); - - let &(ref lock, ref cvar) = &*packet.0; - let mut lock = lock.lock().unwrap(); - tx.send(()).unwrap(); - while *lock == 1 { - match cvar.wait(lock) { - Ok(l) => { - lock = l; - assert_eq!(*lock, 1); - } - Err(..) => break, - } - } -} - #[test] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_mutex_arc_poison() { From 2e01acc59e721dc220807cbf7ca4a599ff923f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2025 20:56:37 +0000 Subject: [PATCH 40/45] Add tests for some cases mentioned in #135589 --- .../missing-lifetime-in-assoc-type-1.rs | 16 +++++++++++++ .../missing-lifetime-in-assoc-type-1.stderr | 15 ++++++++++++ .../missing-lifetime-in-assoc-type-2.rs | 14 +++++++++++ .../missing-lifetime-in-assoc-type-2.stderr | 24 +++++++++++++++++++ .../missing-lifetime-in-assoc-type-3.rs | 14 +++++++++++ .../missing-lifetime-in-assoc-type-3.stderr | 20 ++++++++++++++++ .../missing-lifetime-in-assoc-type-4.rs | 14 +++++++++++ .../missing-lifetime-in-assoc-type-4.stderr | 15 ++++++++++++ 8 files changed, 132 insertions(+) create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs new file mode 100644 index 0000000000000..28e86635b1b79 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs @@ -0,0 +1,16 @@ +struct S; +struct T; + +impl<'a> IntoIterator for &S { + //~^ ERROR E0207 + //~| NOTE unconstrained lifetime parameter + type Item = &T; + //~^ ERROR in the trait associated type + //~| NOTE this lifetime must come from the implemented type + type IntoIter = std::collections::btree_map::Values<'a, i32, T>; + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +fn main() {} diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr new file mode 100644 index 0000000000000..0796f65b9b2d1 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -0,0 +1,15 @@ +error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $DIR/missing-lifetime-in-assoc-type-1.rs:7:17 + | +LL | type Item = &T; + | ^ this lifetime must come from the implemented type + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/missing-lifetime-in-assoc-type-1.rs:4:6 + | +LL | impl<'a> IntoIterator for &S { + | ^^ unconstrained lifetime parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs new file mode 100644 index 0000000000000..dd720f075ac46 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.rs @@ -0,0 +1,14 @@ +struct S; +struct T; + +impl IntoIterator for &S { + type Item = &T; + //~^ ERROR in the trait associated type + type IntoIter = std::collections::btree_map::Values<'a, i32, T>; + //~^ ERROR use of undeclared lifetime name `'a` + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +fn main() {} diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr new file mode 100644 index 0000000000000..77916b651b13c --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr @@ -0,0 +1,24 @@ +error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 + | +LL | type Item = &T; + | ^ this lifetime must come from the implemented type + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/missing-lifetime-in-assoc-type-2.rs:7:57 + | +LL | type IntoIter = std::collections::btree_map::Values<'a, i32, T>; + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; + | ++++ +help: consider introducing lifetime `'a` here + | +LL | impl<'a> IntoIterator for &S { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs new file mode 100644 index 0000000000000..60d1f0f8fe571 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.rs @@ -0,0 +1,14 @@ +struct S; +struct T; + +impl IntoIterator for &S { + type Item = &T; + //~^ ERROR in the trait associated type + type IntoIter = std::collections::btree_map::Values; + //~^ ERROR missing lifetime specifier + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +fn main() {} diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr new file mode 100644 index 0000000000000..50012ac72d22f --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr @@ -0,0 +1,20 @@ +error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $DIR/missing-lifetime-in-assoc-type-3.rs:5:17 + | +LL | type Item = &T; + | ^ this lifetime must come from the implemented type + +error[E0106]: missing lifetime specifier + --> $DIR/missing-lifetime-in-assoc-type-3.rs:7:56 + | +LL | type IntoIter = std::collections::btree_map::Values; + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; + | ++++ +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs new file mode 100644 index 0000000000000..b01c59f3ee6d2 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs @@ -0,0 +1,14 @@ +struct S; +struct T; + +impl IntoIterator for &S { + type Item = &T; + //~^ ERROR in the trait associated type + type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; + //~^ ERROR lifetime parameters or bounds on type `IntoIter` do not match the trait declaration + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +fn main() {} diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr new file mode 100644 index 0000000000000..f17c098ab6d04 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr @@ -0,0 +1,15 @@ +error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $DIR/missing-lifetime-in-assoc-type-4.rs:5:17 + | +LL | type Item = &T; + | ^ this lifetime must come from the implemented type + +error[E0195]: lifetime parameters or bounds on type `IntoIter` do not match the trait declaration + --> $DIR/missing-lifetime-in-assoc-type-4.rs:7:18 + | +LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; + | ^^^^ lifetimes do not match type in trait + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0195`. From 8ba2950fb6ebb3f5e7cf10afb79dda6f5ed61bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2025 21:02:23 +0000 Subject: [PATCH 41/45] Detect case of missing lifetime in assoc type When an associated type is missing a lifetime, point at its enclosing `impl`, whether it has or doesn't have lifetimes defined. If it does have a lifetime, suggest using it. ``` error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-1.rs:8:17 | LL | impl<'a> IntoIterator for &S { | ---- there is a named lifetime specified on the impl block you could use ... LL | type Item = &T; | ^ this lifetime must come from the implemented type | help: consider using the lifetime from the impl block | LL | type Item = &'a T; | ++ ``` ``` error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 | LL | impl IntoIterator for &S { | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type ``` --- compiler/rustc_resolve/src/late.rs | 54 +++++++++++++++++-- .../assoc-type.stderr | 2 + .../missing-lifetime-in-assoc-type-1.rs | 2 + .../missing-lifetime-in-assoc-type-1.stderr | 10 +++- .../missing-lifetime-in-assoc-type-2.stderr | 2 + .../missing-lifetime-in-assoc-type-3.stderr | 2 + .../missing-lifetime-in-assoc-type-4.rs | 2 +- .../missing-lifetime-in-assoc-type-4.stderr | 6 ++- .../ui/lifetimes/no_lending_iterators.stderr | 2 + 9 files changed, 74 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e3051dc38eca2..4a4cb51390623 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -19,7 +19,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; use rustc_errors::{ - Applicability, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions, + Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions, + pluralize, }; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; @@ -1874,9 +1875,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ty: ty.span, }); } else { - self.r.dcx().emit_err(errors::AnonymousLifetimeNonGatReportError { - lifetime: lifetime.ident.span, - }); + let mut err = self.r.dcx().create_err( + errors::AnonymousLifetimeNonGatReportError { + lifetime: lifetime.ident.span, + }, + ); + self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span); + err.emit(); } } else { self.r.dcx().emit_err(errors::ElidedAnonymousLifetimeReportError { @@ -1913,6 +1918,47 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.report_missing_lifetime_specifiers(vec![missing_lifetime], None); } + fn point_at_impl_lifetimes(&mut self, err: &mut Diag<'_>, i: usize, lifetime: Span) { + let Some((rib, span)) = self.lifetime_ribs[..i] + .iter() + .rev() + .skip(1) + .filter_map(|rib| match rib.kind { + LifetimeRibKind::Generics { span, kind: LifetimeBinderKind::ImplBlock, .. } => { + Some((rib, span)) + } + _ => None, + }) + .next() + else { + return; + }; + if !rib.bindings.is_empty() { + err.span_label( + span, + format!( + "there {} named lifetime{} specified on the impl block you could use", + if rib.bindings.len() == 1 { "is a" } else { "are" }, + pluralize!(rib.bindings.len()), + ), + ); + if rib.bindings.len() == 1 { + err.span_suggestion_verbose( + lifetime.shrink_to_hi(), + "consider using the lifetime from the impl block", + format!("{} ", rib.bindings.keys().next().unwrap()), + Applicability::MaybeIncorrect, + ); + } + } else { + err.span_label( + span, + "you could add a lifetime on the impl block, if the trait or the self type can \ + have one", + ); + } + } + #[instrument(level = "debug", skip(self))] fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) { let id = self.r.next_node_id(); diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr index e650eeca48ad9..72c066426bd99 100644 --- a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr +++ b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr @@ -1,6 +1,8 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/assoc-type.rs:11:19 | +LL | impl MyTrait for &i32 { + | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Output = &i32; | ^ this lifetime must come from the implemented type diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs index 28e86635b1b79..5953466375d4e 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs @@ -3,9 +3,11 @@ struct T; impl<'a> IntoIterator for &S { //~^ ERROR E0207 + //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter type Item = &T; //~^ ERROR in the trait associated type + //~| HELP consider using the lifetime from the impl block //~| NOTE this lifetime must come from the implemented type type IntoIter = std::collections::btree_map::Values<'a, i32, T>; diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr index 0796f65b9b2d1..1fbde0cfb3988 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -1,8 +1,16 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type - --> $DIR/missing-lifetime-in-assoc-type-1.rs:7:17 + --> $DIR/missing-lifetime-in-assoc-type-1.rs:8:17 | +LL | impl<'a> IntoIterator for &S { + | ---- there is a named lifetime specified on the impl block you could use +... LL | type Item = &T; | ^ this lifetime must come from the implemented type + | +help: consider using the lifetime from the impl block + | +LL | type Item = &'a T; + | ++ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/missing-lifetime-in-assoc-type-1.rs:4:6 diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr index 77916b651b13c..8408d37a901fd 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr @@ -1,6 +1,8 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-2.rs:5:17 | +LL | impl IntoIterator for &S { + | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr index 50012ac72d22f..d93852aee1bd3 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr @@ -1,6 +1,8 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-3.rs:5:17 | +LL | impl IntoIterator for &S { + | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs index b01c59f3ee6d2..0c99e8874c354 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.rs @@ -5,7 +5,7 @@ impl IntoIterator for &S { type Item = &T; //~^ ERROR in the trait associated type type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; - //~^ ERROR lifetime parameters or bounds on type `IntoIter` do not match the trait declaration + //~^ ERROR lifetime parameters or bounds on associated type `IntoIter` do not match the trait declaration fn into_iter(self) -> Self::IntoIter { todo!() diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr index f17c098ab6d04..ebe051509aad2 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-4.stderr @@ -1,14 +1,16 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/missing-lifetime-in-assoc-type-4.rs:5:17 | +LL | impl IntoIterator for &S { + | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &T; | ^ this lifetime must come from the implemented type -error[E0195]: lifetime parameters or bounds on type `IntoIter` do not match the trait declaration +error[E0195]: lifetime parameters or bounds on associated type `IntoIter` do not match the trait declaration --> $DIR/missing-lifetime-in-assoc-type-4.rs:7:18 | LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; - | ^^^^ lifetimes do not match type in trait + | ^^^^ lifetimes do not match associated type in trait error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/no_lending_iterators.stderr b/tests/ui/lifetimes/no_lending_iterators.stderr index 340ef93588515..cadba149c234d 100644 --- a/tests/ui/lifetimes/no_lending_iterators.stderr +++ b/tests/ui/lifetimes/no_lending_iterators.stderr @@ -13,6 +13,8 @@ LL | impl Iterator for Data { error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type --> $DIR/no_lending_iterators.rs:18:17 | +LL | impl Bar for usize { + | - you could add a lifetime on the impl block, if the trait or the self type can have one LL | type Item = &usize; | ^ this lifetime must come from the implemented type From 1e9e1f2f9ae414f96013568d134e2c4bdaafe62e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2025 21:38:14 +0000 Subject: [PATCH 42/45] On unconstrained lifetime on `impl` block, suggest using it if there's an implicit borrow in the self type ``` error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/missing-lifetime-in-assoc-type-1.rs:4:6 | LL | impl<'a> IntoIterator for &S { | ^^ unconstrained lifetime parameter | help: consider using the named lifetime here instead of an implict lifetime | LL | impl<'a> IntoIterator for &'a S { | ++ ``` --- .../rustc_hir_analysis/src/impl_wf_check.rs | 24 +++++++++++++++- .../missing-lifetime-in-assoc-type-1.rs | 1 + .../missing-lifetime-in-assoc-type-1.stderr | 7 ++++- .../missing-lifetime-in-assoc-type-5.rs | 19 +++++++++++++ .../missing-lifetime-in-assoc-type-5.stderr | 28 +++++++++++++++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs create mode 100644 tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 3dede69ce1063..44867e980e478 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -12,11 +12,12 @@ use std::assert_matches::debug_assert_matches; use min_specialization::check_min_specialization; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::Applicability; use rustc_errors::codes::*; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; -use rustc_span::ErrorGuaranteed; +use rustc_span::{ErrorGuaranteed, kw}; use crate::constrained_generic_params as cgp; use crate::errors::UnconstrainedGenericParameter; @@ -150,6 +151,27 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( const_param_note2: false, }); diag.code(E0207); + for p in &impl_generics.own_params { + if p.name == kw::UnderscoreLifetime { + let span = tcx.def_span(p.def_id); + let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) else { + continue; + }; + + let (span, sugg) = if &snippet == "'_" { + (span, param.name.to_string()) + } else { + (span.shrink_to_hi(), format!("{} ", param.name)) + }; + diag.span_suggestion_verbose( + span, + "consider using the named lifetime here instead of an implict \ + lifetime", + sugg, + Applicability::MaybeIncorrect, + ); + } + } res = Err(diag.emit()); } } diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs index 5953466375d4e..1ae381ef7bc02 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs @@ -5,6 +5,7 @@ impl<'a> IntoIterator for &S { //~^ ERROR E0207 //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter + //~| HELP consider using the named lifetime here instead of an implict lifetime type Item = &T; //~^ ERROR in the trait associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr index 1fbde0cfb3988..bf26ce4a63027 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -1,5 +1,5 @@ error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type - --> $DIR/missing-lifetime-in-assoc-type-1.rs:8:17 + --> $DIR/missing-lifetime-in-assoc-type-1.rs:9:17 | LL | impl<'a> IntoIterator for &S { | ---- there is a named lifetime specified on the impl block you could use @@ -17,6 +17,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, | LL | impl<'a> IntoIterator for &S { | ^^ unconstrained lifetime parameter + | +help: consider using the named lifetime here instead of an implict lifetime + | +LL | impl<'a> IntoIterator for &'a S { + | ++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs new file mode 100644 index 0000000000000..ff64d6b900949 --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs @@ -0,0 +1,19 @@ +struct S; +struct T; + +impl<'a> IntoIterator for &'_ S { + //~^ ERROR E0207 + //~| NOTE there is a named lifetime specified on the impl block you could use + //~| NOTE unconstrained lifetime parameter + //~| HELP consider using the named lifetime here instead of an implict lifetime + type Item = &T; + //~^ ERROR in the trait associated type + //~| HELP consider using the lifetime from the impl block + //~| NOTE this lifetime must come from the implemented type + type IntoIter = std::collections::btree_map::Values<'a, i32, T>; + + fn into_iter(self) -> Self::IntoIter { + todo!() + } +} +fn main() {} diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr new file mode 100644 index 0000000000000..7a63bd5b05eff --- /dev/null +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr @@ -0,0 +1,28 @@ +error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + --> $DIR/missing-lifetime-in-assoc-type-5.rs:9:17 + | +LL | impl<'a> IntoIterator for &'_ S { + | ---- there is a named lifetime specified on the impl block you could use +... +LL | type Item = &T; + | ^ this lifetime must come from the implemented type + | +help: consider using the lifetime from the impl block + | +LL | type Item = &'a T; + | ++ + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/missing-lifetime-in-assoc-type-5.rs:4:6 + | +LL | impl<'a> IntoIterator for &'_ S { + | ^^ unconstrained lifetime parameter + | +help: consider using the named lifetime here instead of an implict lifetime + | +LL | impl<'a> IntoIterator for &'a S { + | ~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. From 75bb675f96a261851cf3ed562b9fae31dc739dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2025 22:12:35 +0000 Subject: [PATCH 43/45] Do not suggest introducing lifetime in impl assoc type ``` error[E0261]: use of undeclared lifetime name `'a` --> $DIR/missing-lifetime-in-assoc-type-2.rs:7:57 | LL | impl IntoIterator for &S { | - help: consider introducing lifetime `'a` here: `<'a>` ... LL | type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | ^^ undeclared lifetime ``` ``` error[E0106]: missing lifetime specifier --> $DIR/issue-74918-missing-lifetime.rs:9:30 | LL | type Item = IteratorChunk; | ^ expected named lifetime parameter | help: consider introducing a named lifetime parameter | LL ~ impl<'a, T, S: Iterator> Iterator for ChunkingIterator { LL ~ type Item = IteratorChunk<'a, T, S>; | ``` --- compiler/rustc_resolve/src/late.rs | 4 +++- compiler/rustc_resolve/src/late/diagnostics.rs | 3 +++ tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr | 4 ---- tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr | 7 +++++-- tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr | 5 +++-- .../mismatched_types/issue-74918-missing-lifetime.stderr | 5 +++-- .../ui/nll/user-annotations/region-error-ice-109072.stderr | 4 ---- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4a4cb51390623..91d0cae062a7e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -378,6 +378,7 @@ enum LifetimeBinderKind { Function, Closure, ImplBlock, + ImplAssocType, } impl LifetimeBinderKind { @@ -388,6 +389,7 @@ impl LifetimeBinderKind { PolyTrait => "bound", WhereBound => "bound", Item | ConstItem => "item", + ImplAssocType => "associated type", ImplBlock => "impl block", Function => "function", Closure => "closure", @@ -3398,7 +3400,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { &generics.params, RibKind::AssocItem, item.id, - LifetimeBinderKind::Item, + LifetimeBinderKind::ImplAssocType, generics.span, |this| { this.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9e82237694e3c..57f81ebf0d81e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3178,6 +3178,9 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { { continue; } + if let LifetimeBinderKind::ImplAssocType = kind { + continue; + } if !span.can_be_used_for_suggestions() && suggest_note diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr index 8408d37a901fd..7a0246eaac8fd 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-2.stderr @@ -14,10 +14,6 @@ LL | type IntoIter = std::collections::btree_map::Values<'a, i32, T>; | help: consider introducing lifetime `'a` here | -LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; - | ++++ -help: consider introducing lifetime `'a` here - | LL | impl<'a> IntoIterator for &S { | ++++ diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr index d93852aee1bd3..408d5bb40664d 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-3.stderr @@ -14,8 +14,11 @@ LL | type IntoIter = std::collections::btree_map::Values; | help: consider introducing a named lifetime parameter | -LL | type IntoIter<'a> = std::collections::btree_map::Values<'a, i32, T>; - | ++++ +++ +LL ~ impl<'a> IntoIterator for &S { +LL | type Item = &T; +LL | +LL ~ type IntoIter = std::collections::btree_map::Values<'a, i32, T>; + | error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr index 7a63bd5b05eff..9c960c67e2502 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr @@ -20,8 +20,9 @@ LL | impl<'a> IntoIterator for &'_ S { | help: consider using the named lifetime here instead of an implict lifetime | -LL | impl<'a> IntoIterator for &'a S { - | ~~ +LL - impl<'a> IntoIterator for &'_ S { +LL + impl<'a> IntoIterator for &'a S { + | error: aborting due to 2 previous errors diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr index 5020395eb6aea..dc21c2e3cf9bf 100644 --- a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr +++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr @@ -6,8 +6,9 @@ LL | type Item = IteratorChunk; | help: consider introducing a named lifetime parameter | -LL | type Item<'a> = IteratorChunk<'a, T, S>; - | ++++ +++ +LL ~ impl<'a, T, S: Iterator> Iterator for ChunkingIterator { +LL ~ type Item = IteratorChunk<'a, T, S>; + | error: aborting due to 1 previous error diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr index 42551b87f6234..026f5b5f80a9b 100644 --- a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr @@ -17,10 +17,6 @@ LL | type T = &'missing (); | help: consider introducing lifetime `'missing` here | -LL | type T<'missing> = &'missing (); - | ++++++++++ -help: consider introducing lifetime `'missing` here - | LL | impl<'missing> Lt<'missing> for () { | ++++++++++ From 8d5166710bf39c1218c9cdc43d7859ce4fd0ee64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 Oct 2025 20:46:47 +0000 Subject: [PATCH 44/45] fix typo --- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs | 2 +- tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 44867e980e478..cadbc54c34108 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -165,7 +165,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( }; diag.span_suggestion_verbose( span, - "consider using the named lifetime here instead of an implict \ + "consider using the named lifetime here instead of an implicit \ lifetime", sugg, Applicability::MaybeIncorrect, diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs index 1ae381ef7bc02..5401bc4ecb873 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.rs @@ -5,7 +5,7 @@ impl<'a> IntoIterator for &S { //~^ ERROR E0207 //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter - //~| HELP consider using the named lifetime here instead of an implict lifetime + //~| HELP consider using the named lifetime here instead of an implicit lifetime type Item = &T; //~^ ERROR in the trait associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr index bf26ce4a63027..feac49eb0ff52 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-1.stderr @@ -18,7 +18,7 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, LL | impl<'a> IntoIterator for &S { | ^^ unconstrained lifetime parameter | -help: consider using the named lifetime here instead of an implict lifetime +help: consider using the named lifetime here instead of an implicit lifetime | LL | impl<'a> IntoIterator for &'a S { | ++ diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs index ff64d6b900949..17cca7cc9e37b 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.rs @@ -5,7 +5,7 @@ impl<'a> IntoIterator for &'_ S { //~^ ERROR E0207 //~| NOTE there is a named lifetime specified on the impl block you could use //~| NOTE unconstrained lifetime parameter - //~| HELP consider using the named lifetime here instead of an implict lifetime + //~| HELP consider using the named lifetime here instead of an implicit lifetime type Item = &T; //~^ ERROR in the trait associated type //~| HELP consider using the lifetime from the impl block diff --git a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr index 9c960c67e2502..cb15bcb7d5049 100644 --- a/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr +++ b/tests/ui/lifetimes/missing-lifetime-in-assoc-type-5.stderr @@ -18,7 +18,7 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, LL | impl<'a> IntoIterator for &'_ S { | ^^ unconstrained lifetime parameter | -help: consider using the named lifetime here instead of an implict lifetime +help: consider using the named lifetime here instead of an implicit lifetime | LL - impl<'a> IntoIterator for &'_ S { LL + impl<'a> IntoIterator for &'a S { From 2a1595e2fea2dfa7f853f07d3595cbd543342d8e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 30 Oct 2025 16:10:53 +0100 Subject: [PATCH 45/45] Add regression test for including extern crates in import filtering --- tests/rustdoc-js/import-filter.js | 20 ++++++++++++++++++++ tests/rustdoc-js/import-filter.rs | 7 +++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/rustdoc-js/import-filter.js create mode 100644 tests/rustdoc-js/import-filter.rs diff --git a/tests/rustdoc-js/import-filter.js b/tests/rustdoc-js/import-filter.js new file mode 100644 index 0000000000000..408d0e3326179 --- /dev/null +++ b/tests/rustdoc-js/import-filter.js @@ -0,0 +1,20 @@ +// This test ensures that when filtering on `import`, `externcrate` items are also displayed. +// It also ensures that the opposite is not true. + +const EXPECTED = [ + { + 'query': 'import:st', + 'others': [ + { 'path': 'foo', 'name': 'st', 'href': '../foo/index.html#reexport.st' }, + // FIXME: `href` is wrong: + { 'path': 'foo', 'name': 'st2', 'href': '../st2/index.html' }, + ], + }, + { + 'query': 'externcrate:st', + 'others': [ + // FIXME: `href` is wrong: + { 'path': 'foo', 'name': 'st2', 'href': '../st2/index.html' }, + ], + }, +]; diff --git a/tests/rustdoc-js/import-filter.rs b/tests/rustdoc-js/import-filter.rs new file mode 100644 index 0000000000000..7d30d00f5bbf8 --- /dev/null +++ b/tests/rustdoc-js/import-filter.rs @@ -0,0 +1,7 @@ +#![crate_name = "foo"] + +pub extern crate std as st2; + +pub use crate::Bar as st; + +pub struct Bar;