git: e3ca7e34aeb0 - main - mail/thunderbird: Fix build with rust 1.78.0

From: Mikael Urankar <mikael_at_FreeBSD.org>
Date: Mon, 13 May 2024 11:03:56 UTC
The branch main has been updated by mikael:

URL: https://cgit.FreeBSD.org/ports/commit/?id=e3ca7e34aeb0638d4d27346c4fc369e11ef54b4c

commit e3ca7e34aeb0638d4d27346c4fc369e11ef54b4c
Author:     Mikael Urankar <mikael@FreeBSD.org>
AuthorDate: 2024-05-08 08:52:27 +0000
Commit:     Mikael Urankar <mikael@FreeBSD.org>
CommitDate: 2024-05-13 11:03:22 +0000

    mail/thunderbird: Fix build with rust 1.78.0
    
    PR:             278834
    Approved by:    portmgr (build fix blanket)
---
 mail/thunderbird/files/patch-rust-1.78.0     | 3582 ++++++++++++++++++++++++++
 mail/thunderbird/files/patch-rust-1.78.0-arm |   64 +
 2 files changed, 3646 insertions(+)

diff --git a/mail/thunderbird/files/patch-rust-1.78.0 b/mail/thunderbird/files/patch-rust-1.78.0
new file mode 100644
index 000000000000..7e6685d5e8e7
--- /dev/null
+++ b/mail/thunderbird/files/patch-rust-1.78.0
@@ -0,0 +1,3582 @@
+Adapted from https://hg.mozilla.org/mozilla-central/rev/1db2ef126a6a
+--
+
+# HG changeset patch
+# User Henri Sivonen <hsivonen@hsivonen.fi>
+# Date 1714462184 0
+# Node ID 1db2ef126a6a8555dbf50345e16492c977b42e92
+# Parent  a545e84b3674c4878f2e618b7bce23058f2ac690
+Bug 1882209 - Update encoding_rs to 0.8.34 to deal with rustc changes. r=glandium,supply-chain-reviewers
+
+Differential Revision: https://phabricator.services.mozilla.com/D207167
+
+diff --git a/.cargo/config.in b/.cargo/config.in
+--- .cargo/config.in
++++ .cargo/config.in
+@@ -35,31 +35,31 @@ git = "https://github.com/gfx-rs/wgpu"
+ rev = "f71a1bc736fde37509262ca03e91d8f56a13aeb5"
+ replace-with = "vendored-sources"
+ 
+ [source."git+https://github.com/glandium/warp?rev=4af45fae95bc98b0eba1ef0db17e1dac471bb23d"]
+ git = "https://github.com/glandium/warp"
+ rev = "4af45fae95bc98b0eba1ef0db17e1dac471bb23d"
+ replace-with = "vendored-sources"
+ 
++[source."git+https://github.com/hsivonen/any_all_workaround?rev=7fb1b7034c9f172aade21ee1c8554e8d8a48af80"]
++git = "https://github.com/hsivonen/any_all_workaround"
++rev = "7fb1b7034c9f172aade21ee1c8554e8d8a48af80"
++replace-with = "vendored-sources"
++
+ [source."git+https://github.com/hsivonen/chardetng?rev=3484d3e3ebdc8931493aa5df4d7ee9360a90e76b"]
+ git = "https://github.com/hsivonen/chardetng"
+ rev = "3484d3e3ebdc8931493aa5df4d7ee9360a90e76b"
+ replace-with = "vendored-sources"
+ 
+ [source."git+https://github.com/hsivonen/chardetng_c?rev=ed8a4c6f900a90d4dbc1d64b856e61490a1c3570"]
+ git = "https://github.com/hsivonen/chardetng_c"
+ rev = "ed8a4c6f900a90d4dbc1d64b856e61490a1c3570"
+ replace-with = "vendored-sources"
+ 
+-[source."git+https://github.com/hsivonen/packed_simd?rev=e588ceb568878e1a3156ea9ce551d5b63ef0cdc4"]
+-git = "https://github.com/hsivonen/packed_simd"
+-rev = "e588ceb568878e1a3156ea9ce551d5b63ef0cdc4"
+-replace-with = "vendored-sources"
+-
+ [source."git+https://github.com/jfkthame/mapped_hyph.git?rev=c7651a0cffff41996ad13c44f689bd9cd2192c01"]
+ git = "https://github.com/jfkthame/mapped_hyph.git"
+ rev = "c7651a0cffff41996ad13c44f689bd9cd2192c01"
+ replace-with = "vendored-sources"
+ 
+ [source."git+https://github.com/mozilla-spidermonkey/jsparagus?rev=64ba08e24749616de2344112f226d1ef4ba893ae"]
+ git = "https://github.com/mozilla-spidermonkey/jsparagus"
+ rev = "64ba08e24749616de2344112f226d1ef4ba893ae"
+diff --git a/Cargo.lock b/Cargo.lock
+--- Cargo.lock
++++ Cargo.lock
+@@ -80,16 +80,25 @@ dependencies = [
+ name = "android_system_properties"
+ version = "0.1.5"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+ dependencies = [
+  "libc",
+ ]
+ 
++[[package]]
++name = "any_all_workaround"
++version = "0.1.0"
++source = "git+https://github.com/hsivonen/any_all_workaround?rev=7fb1b7034c9f172aade21ee1c8554e8d8a48af80#7fb1b7034c9f172aade21ee1c8554e8d8a48af80"
++dependencies = [
++ "cfg-if 1.0.0",
++ "version_check",
++]
++
+ [[package]]
+ name = "anyhow"
+ version = "1.0.69"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
+ 
+ [[package]]
+ name = "app_services_logger"
+@@ -1431,22 +1440,22 @@ dependencies = [
+  "encoding_rs",
+  "nserror",
+  "nsstring",
+  "xmldecl",
+ ]
+ 
+ [[package]]
+ name = "encoding_rs"
+-version = "0.8.33"
++version = "0.8.34"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
++checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
+ dependencies = [
++ "any_all_workaround",
+  "cfg-if 1.0.0",
+- "packed_simd",
+ ]
+ 
+ [[package]]
+ name = "enum-primitive-derive"
+ version = "0.2.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e"
+ dependencies = [
+@@ -3901,25 +3910,16 @@ checksum = "8d91edf4fbb970279443471345a4e8c491bf05bb283b3e6c88e4e606fd8c181b"
+ [[package]]
+ name = "oxilangtag-ffi"
+ version = "0.1.0"
+ dependencies = [
+  "nsstring",
+  "oxilangtag",
+ ]
+ 
+-[[package]]
+-name = "packed_simd"
+-version = "0.3.9"
+-source = "git+https://github.com/hsivonen/packed_simd?rev=e588ceb568878e1a3156ea9ce551d5b63ef0cdc4#e588ceb568878e1a3156ea9ce551d5b63ef0cdc4"
+-dependencies = [
+- "cfg-if 1.0.0",
+- "num-traits",
+-]
+-
+ [[package]]
+ name = "parking_lot"
+ version = "0.11.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
+ dependencies = [
+  "instant",
+  "lock_api",
+diff --git a/Cargo.toml b/Cargo.toml
+--- Cargo.toml
++++ Cargo.toml
+@@ -154,22 +154,22 @@ rure = { path = "third_party/rust/rure" }
+ 
+ # 0.31.1 but without rust-cssparser#342.
+ # TODO: Remove these, and just use v0.31.1 once bug 1836219 lands
+ # (which will get syn 2 into the tree).
+ cssparser = { path = "third_party/rust/cssparser" }
+ cssparser-macros = { path = "third_party/rust/cssparser-macros" }
+ 
+ # Other overrides
++any_all_workaround = { git = "https://github.com/hsivonen/any_all_workaround", rev = "7fb1b7034c9f172aade21ee1c8554e8d8a48af80" }
+ chardetng = { git = "https://github.com/hsivonen/chardetng", rev="3484d3e3ebdc8931493aa5df4d7ee9360a90e76b" }
+ chardetng_c = { git = "https://github.com/hsivonen/chardetng_c", rev="ed8a4c6f900a90d4dbc1d64b856e61490a1c3570" }
+ coremidi = { git = "https://github.com/chris-zen/coremidi.git", rev="fc68464b5445caf111e41f643a2e69ccce0b4f83" }
+ firefox-on-glean = { path = "toolkit/components/glean/api" }
+ libudev-sys = { path = "dom/webauthn/libudev-sys" }
+-packed_simd = { git = "https://github.com/hsivonen/packed_simd", rev = "e588ceb568878e1a3156ea9ce551d5b63ef0cdc4" }
+ midir = { git = "https://github.com/mozilla/midir.git", rev = "519e651241e867af3391db08f9ae6400bc023e18" }
+ # warp 0.3.3 + https://github.com/seanmonstar/warp/pull/1007
+ warp = { git = "https://github.com/glandium/warp", rev = "4af45fae95bc98b0eba1ef0db17e1dac471bb23d" }
+ 
+ # application-services overrides to make updating them all simpler.
+ interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "86c84c217036c12283d19368867323a66bf35883" }
+ sql-support = { git = "https://github.com/mozilla/application-services", rev = "86c84c217036c12283d19368867323a66bf35883" }
+ sync15 = { git = "https://github.com/mozilla/application-services", rev = "86c84c217036c12283d19368867323a66bf35883" }
+diff --git a/config/makefiles/rust.mk b/config/makefiles/rust.mk
+--- config/makefiles/rust.mk
++++ config/makefiles/rust.mk
+@@ -260,17 +260,17 @@ export COREAUDIO_SDK_PATH=$(IPHONEOS_SDK
+ export IPHONEOS_SDK_DIR
+ PATH := $(topsrcdir)/build/macosx:$(PATH)
+ endif
+ endif
+ 
+ ifndef RUSTC_BOOTSTRAP
+ RUSTC_BOOTSTRAP := mozglue_static,qcms
+ ifdef MOZ_RUST_SIMD
+-RUSTC_BOOTSTRAP := $(RUSTC_BOOTSTRAP),encoding_rs,packed_simd
++RUSTC_BOOTSTRAP := $(RUSTC_BOOTSTRAP),encoding_rs,any_all_workaround
+ endif
+ export RUSTC_BOOTSTRAP
+ endif
+ 
+ target_rust_ltoable := force-cargo-library-build $(ADD_RUST_LTOABLE)
+ target_rust_nonltoable := force-cargo-test-run force-cargo-program-build
+ 
+ ifdef MOZ_PGO_RUST
+diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml
+--- supply-chain/audits.toml
++++ supply-chain/audits.toml
+@@ -596,16 +596,29 @@ who = "Mike Hommey <mh+mozilla@glandium.
+ criteria = "safe-to-deploy"
+ delta = "0.1.2 -> 0.1.4"
+ 
+ [[audits.android_system_properties]]
+ who = "Mike Hommey <mh+mozilla@glandium.org>"
+ criteria = "safe-to-deploy"
+ delta = "0.1.4 -> 0.1.5"
+ 
++[[audits.any_all_workaround]]
++who = "Henri Sivonen <hsivonen@hsivonen.fi>"
++criteria = "safe-to-deploy"
++version = "0.1.0"
++notes = "The little code that is in this crate I reviewed and modified from packed_simd (which has previously been vendored in full instead of just this small part)."
++
++[[audits.any_all_workaround]]
++who = "Henri Sivonen <hsivonen@hsivonen.fi>"
++criteria = "safe-to-deploy"
++delta = "0.1.0 -> 0.1.0@git:7fb1b7034c9f172aade21ee1c8554e8d8a48af80"
++importable = false
++notes = "This is a trivial workaround copied from elsewhere in m-c, specifically qcms."
++
+ [[audits.anyhow]]
+ who = "Mike Hommey <mh+mozilla@glandium.org>"
+ criteria = "safe-to-deploy"
+ delta = "1.0.57 -> 1.0.61"
+ 
+ [[audits.anyhow]]
+ who = "Bobby Holley <bobbyholley@gmail.com>"
+ criteria = "safe-to-deploy"
+diff --git a/supply-chain/config.toml b/supply-chain/config.toml
+--- supply-chain/config.toml
++++ supply-chain/config.toml
+@@ -14,16 +14,20 @@ url = "https://raw.githubusercontent.com
+ url = "https://raw.githubusercontent.com/google/supply-chain/main/audits.toml"
+ 
+ [imports.isrg]
+ url = "https://raw.githubusercontent.com/divviup/libprio-rs/main/supply-chain/audits.toml"
+ 
+ [imports.mozilla]
+ url = "https://raw.githubusercontent.com/mozilla/supply-chain/main/audits.toml"
+ 
++[policy.any_all_workaround]
++audit-as-crates-io = true
++notes = "This is the upstream code plus the ARM intrinsics workaround from qcms, see bug 1882209."
++
+ [policy.autocfg]
+ audit-as-crates-io = true
+ notes = "This is the upstream code plus a few local fixes, see bug 1685697."
+ 
+ [policy.chardetng]
+ audit-as-crates-io = true
+ notes = "This is a crate Henri wrote which is also published. We should probably update Firefox to tip and certify that."
+ 
+diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock
+--- supply-chain/imports.lock
++++ supply-chain/imports.lock
+@@ -115,16 +115,23 @@ user-name = "David Tolnay"
+ 
+ [[publisher.encoding_rs]]
+ version = "0.8.33"
+ when = "2023-08-23"
+ user-id = 4484
+ user-login = "hsivonen"
+ user-name = "Henri Sivonen"
+ 
++[[publisher.encoding_rs]]
++version = "0.8.34"
++when = "2024-04-10"
++user-id = 4484
++user-login = "hsivonen"
++user-name = "Henri Sivonen"
++
+ [[publisher.etagere]]
+ version = "0.2.7"
+ when = "2022-05-04"
+ user-id = 1281
+ user-login = "nical"
+ user-name = "Nicolas Silva"
+ 
+ [[publisher.euclid]]
+diff --git a/third_party/rust/any_all_workaround/.cargo-checksum.json b/third_party/rust/any_all_workaround/.cargo-checksum.json
+new file mode 100644
+--- /dev/null
++++ third_party/rust/any_all_workaround/.cargo-checksum.json
+@@ -0,0 +1,1 @@
++{"files":{"Cargo.toml":"f8c127449dc9432d404c21c99833e4617ab88a797445af249a7fe3c989985d6d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","LICENSE-MIT-QCMS":"36d847ae882f6574ebc72f56a4f354e4f104fde4a584373496482e97d52d31bc","README.md":"4c617b8ced3a27b7edecf0e5e41ed451c04e88dab529e7a35fccc4e1551efbd7","build.rs":"56b29ab6da3e49075bfd0a7b690267c8016298bf0d332e2e68bbaf19decbbf71","src/lib.rs":"7118106690b9d25c5d0a3e2079feb83d76f1d434d0da36b9d0351806d27c850d"},"package":null}
+\ No newline at end of file
+diff --git a/third_party/rust/any_all_workaround/Cargo.toml b/third_party/rust/any_all_workaround/Cargo.toml
+new file mode 100644
+--- /dev/null
++++ third_party/rust/any_all_workaround/Cargo.toml
+@@ -0,0 +1,28 @@
++# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
++#
++# When uploading crates to the registry Cargo will automatically
++# "normalize" Cargo.toml files for maximal compatibility
++# with all versions of Cargo and also rewrite `path` dependencies
++# to registry (e.g., crates.io) dependencies.
++#
++# If you are reading this file be aware that the original Cargo.toml
++# will likely look very different (and much more reasonable).
++# See Cargo.toml.orig for the original contents.
++
++[package]
++edition = "2021"
++name = "any_all_workaround"
++version = "0.1.0"
++authors = ["Henri Sivonen <hsivonen@hsivonen.fi>"]
++description = "Workaround for bad LLVM codegen for boolean reductions on 32-bit ARM"
++homepage = "https://docs.rs/any_all_workaround/"
++documentation = "https://docs.rs/any_all_workaround/"
++readme = "README.md"
++license = "MIT OR Apache-2.0"
++repository = "https://github.com/hsivonen/any_all_workaround"
++
++[dependencies]
++cfg-if = "1.0"
++
++[build-dependencies]
++version_check = "0.9"
+diff --git a/third_party/rust/packed_simd/LICENSE-APACHE b/third_party/rust/any_all_workaround/LICENSE-APACHE
+rename from third_party/rust/packed_simd/LICENSE-APACHE
+rename to third_party/rust/any_all_workaround/LICENSE-APACHE
+diff --git a/third_party/rust/packed_simd/LICENSE-MIT b/third_party/rust/any_all_workaround/LICENSE-MIT
+rename from third_party/rust/packed_simd/LICENSE-MIT
+rename to third_party/rust/any_all_workaround/LICENSE-MIT
+diff --git a/third_party/rust/any_all_workaround/LICENSE-MIT-QCMS b/third_party/rust/any_all_workaround/LICENSE-MIT-QCMS
+new file mode 100644
+--- /dev/null
++++ third_party/rust/any_all_workaround/LICENSE-MIT-QCMS
+@@ -0,0 +1,21 @@
++qcms
++Copyright (C) 2009-2024 Mozilla Corporation
++Copyright (C) 1998-2007 Marti Maria
++
++Permission is hereby granted, free of charge, to any person obtaining 
++a copy of this software and associated documentation files (the "Software"), 
++to deal in the Software without restriction, including without limitation 
++the rights to use, copy, modify, merge, publish, distribute, sublicense, 
++and/or sell copies of the Software, and to permit persons to whom the Software 
++is furnished to do so, subject to the following conditions:
++
++The above copyright notice and this permission notice shall be included in 
++all copies or substantial portions of the Software.
++
++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
++THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+diff --git a/third_party/rust/any_all_workaround/README.md b/third_party/rust/any_all_workaround/README.md
+new file mode 100644
+--- /dev/null
++++ third_party/rust/any_all_workaround/README.md
+@@ -0,0 +1,13 @@
++# any_all_workaround
++
++This is a workaround for bad codegen ([Rust bug](https://github.com/rust-lang/portable-simd/issues/146), [LLVM bug](https://github.com/llvm/llvm-project/issues/50466)) for the `any()` and `all()` reductions for NEON-backed SIMD vectors on 32-bit ARM. On other platforms these delegate to `any()` and `all()` in `core::simd`.
++
++The plan is to abandon this crate once the LLVM bug is fixed or `core::simd` works around the LLVM bug.
++
++The code is forked from the [`packed_simd` crate](https://raw.githubusercontent.com/hsivonen/packed_simd/d938e39bee9bc5c222f5f2f2a0df9e53b5ce36ae/src/codegen/reductions/mask/arm.rs).
++
++This crate requires Nightly Rust as it depends on the `portable_simd` feature.
++
++# License
++
++`MIT OR Apache-2.0`, since that's how `packed_simd` is licensed. (The ARM intrinsics Rust version workaround is from qcms, see LICENSE-MIT-QCMS.)
+diff --git a/third_party/rust/any_all_workaround/build.rs b/third_party/rust/any_all_workaround/build.rs
+new file mode 100644
+--- /dev/null
++++ third_party/rust/any_all_workaround/build.rs
+@@ -0,0 +1,7 @@
++extern crate version_check as rustc;
++
++fn main() {
++    if rustc::is_min_version("1.78.0").unwrap_or(false) {
++        println!("cargo:rustc-cfg=stdsimd_split");
++    }
++}
+diff --git a/third_party/rust/any_all_workaround/src/lib.rs b/third_party/rust/any_all_workaround/src/lib.rs
+new file mode 100644
+--- /dev/null
++++ third_party/rust/any_all_workaround/src/lib.rs
+@@ -0,0 +1,110 @@
++// This code began as a fork of
++// https://raw.githubusercontent.com/rust-lang/packed_simd/d938e39bee9bc5c222f5f2f2a0df9e53b5ce36ae/src/codegen/reductions/mask/arm.rs
++// which didn't have a license header on the file, but Cargo.toml said "MIT OR Apache-2.0".
++// See LICENSE-MIT and LICENSE-APACHE.
++
++#![no_std]
++#![feature(portable_simd)]
++#![cfg_attr(
++    all(
++        stdsimd_split,
++        target_arch = "arm",
++        target_endian = "little",
++        target_feature = "neon",
++        target_feature = "v7"
++    ),
++    feature(stdarch_arm_neon_intrinsics)
++)]
++#![cfg_attr(
++    all(
++        not(stdsimd_split),
++        target_arch = "arm",
++        target_endian = "little",
++        target_feature = "neon",
++        target_feature = "v7"
++    ),
++    feature(stdsimd)
++)]
++
++use cfg_if::cfg_if;
++use core::simd::mask16x8;
++use core::simd::mask32x4;
++use core::simd::mask8x16;
++
++cfg_if! {
++    if #[cfg(all(target_arch = "arm", target_endian = "little", target_feature = "neon", target_feature = "v7"))] {
++        use core::simd::mask8x8;
++        use core::simd::mask16x4;
++        use core::simd::mask32x2;
++        macro_rules! arm_128_v7_neon_impl {
++            ($all:ident, $any:ident, $id:ident, $half:ident, $vpmin:ident, $vpmax:ident) => {
++                #[inline]
++                pub fn $all(s: $id) -> bool {
++                    use core::arch::arm::$vpmin;
++                    use core::mem::transmute;
++                    unsafe {
++                        union U {
++                            halves: ($half, $half),
++                            vec: $id,
++                        }
++                        let halves = U { vec: s }.halves;
++                        let h: $half = transmute($vpmin(transmute(halves.0), transmute(halves.1)));
++                        h.all()
++                    }
++                }
++                #[inline]
++                pub fn $any(s: $id) -> bool {
++                    use core::arch::arm::$vpmax;
++                    use core::mem::transmute;
++                    unsafe {
++                        union U {
++                            halves: ($half, $half),
++                            vec: $id,
++                        }
++                        let halves = U { vec: s }.halves;
++                        let h: $half = transmute($vpmax(transmute(halves.0), transmute(halves.1)));
++                        h.any()
++                    }
++                }
++            }
++        }
++    } else {
++        macro_rules! arm_128_v7_neon_impl {
++            ($all:ident, $any:ident, $id:ident, $half:ident, $vpmin:ident, $vpmax:ident) => {
++                #[inline(always)]
++                pub fn $all(s: $id) -> bool {
++                    s.all()
++                }
++                #[inline(always)]
++                pub fn $any(s: $id) -> bool {
++                    s.any()
++                }
++            }
++        }
++    }
++}
++
++arm_128_v7_neon_impl!(
++    all_mask8x16,
++    any_mask8x16,
++    mask8x16,
++    mask8x8,
++    vpmin_u8,
++    vpmax_u8
++);
++arm_128_v7_neon_impl!(
++    all_mask16x8,
++    any_mask16x8,
++    mask16x8,
++    mask16x4,
++    vpmin_u16,
++    vpmax_u16
++);
++arm_128_v7_neon_impl!(
++    all_mask32x4,
++    any_mask32x4,
++    mask32x4,
++    mask32x2,
++    vpmin_u32,
++    vpmax_u32
++);
+diff --git a/third_party/rust/encoding_rs/Cargo.toml b/third_party/rust/encoding_rs/Cargo.toml
+--- third_party/rust/encoding_rs/Cargo.toml
++++ third_party/rust/encoding_rs/Cargo.toml
+@@ -6,18 +6,19 @@
+ # to registry (e.g., crates.io) dependencies.
+ #
+ # If you are reading this file be aware that the original Cargo.toml
+ # will likely look very different (and much more reasonable).
+ # See Cargo.toml.orig for the original contents.
+ 
+ [package]
+ edition = "2018"
++rust-version = "1.36"
+ name = "encoding_rs"
+-version = "0.8.33"
++version = "0.8.34"
+ authors = ["Henri Sivonen <hsivonen@hsivonen.fi>"]
+ description = "A Gecko-oriented implementation of the Encoding Standard"
+ homepage = "https://docs.rs/encoding_rs/"
+ documentation = "https://docs.rs/encoding_rs/"
+ readme = "README.md"
+ keywords = [
+     "encoding",
+     "web",
+@@ -31,23 +32,23 @@ categories = [
+     "internationalization",
+ ]
+ license = "(Apache-2.0 OR MIT) AND BSD-3-Clause"
+ repository = "https://github.com/hsivonen/encoding_rs"
+ 
+ [profile.release]
+ lto = true
+ 
++[dependencies.any_all_workaround]
++version = "0.1.0"
++optional = true
++
+ [dependencies.cfg-if]
+ version = "1.0"
+ 
+-[dependencies.packed_simd]
+-version = "0.3.9"
+-optional = true
+-
+ [dependencies.serde]
+ version = "1.0"
+ optional = true
+ 
+ [dev-dependencies.bincode]
+ version = "1.0"
+ 
+ [dev-dependencies.serde_derive]
+@@ -69,15 +70,9 @@ fast-legacy-encode = [
+     "fast-hanja-encode",
+     "fast-kanji-encode",
+     "fast-gb-hanzi-encode",
+     "fast-big5-hanzi-encode",
+ ]
+ less-slow-big5-hanzi-encode = []
+ less-slow-gb-hanzi-encode = []
+ less-slow-kanji-encode = []
+-simd-accel = [
+-    "packed_simd",
+-    "packed_simd/into_bits",
+-]
+-
+-[badges.travis-ci]
+-repository = "hsivonen/encoding_rs"
++simd-accel = ["any_all_workaround"]
+diff --git a/third_party/rust/encoding_rs/README.md b/third_party/rust/encoding_rs/README.md
+--- third_party/rust/encoding_rs/README.md
++++ third_party/rust/encoding_rs/README.md
+@@ -162,50 +162,36 @@ wrappers.
+ * [C++](https://github.com/hsivonen/recode_cpp)
+ 
+ ## Optional features
+ 
+ There are currently these optional cargo features:
+ 
+ ### `simd-accel`
+ 
+-Enables SIMD acceleration using the nightly-dependent `packed_simd` crate.
++Enables SIMD acceleration using the nightly-dependent `portable_simd` standard
++library feature.
+ 
+ This is an opt-in feature, because enabling this feature _opts out_ of Rust's
+ guarantees of future compilers compiling old code (aka. "stability story").
+ 
+ Currently, this has not been tested to be an improvement except for these
+-targets:
++targets and enabling the `simd-accel` feature is expected to break the build
++on other targets:
+ 
+ * x86_64
+ * i686
+ * aarch64
+ * thumbv7neon
+ 
+ If you use nightly Rust, you use targets whose first component is one of the
+ above, and you are prepared _to have to revise your configuration when updating
+ Rust_, you should enable this feature. Otherwise, please _do not_ enable this
+ feature.
+ 
+-_Note!_ If you are compiling for a target that does not have 128-bit SIMD
+-enabled as part of the target definition and you are enabling 128-bit SIMD
+-using `-C target_feature`, you need to enable the `core_arch` Cargo feature
+-for `packed_simd` to compile a crates.io snapshot of `core_arch` instead of
+-using the standard-library copy of `core::arch`, because the `core::arch`
+-module of the pre-compiled standard library has been compiled with the
+-assumption that the CPU doesn't have 128-bit SIMD. At present this applies
+-mainly to 32-bit ARM targets whose first component does not include the
+-substring `neon`.
+-
+-The encoding_rs side of things has not been properly set up for POWER,
+-PowerPC, MIPS, etc., SIMD at this time, so even if you were to follow
+-the advice from the previous paragraph, you probably shouldn't use
+-the `simd-accel` option on the less mainstream architectures at this
+-time.
+-
+ Used by Firefox.
+ 
+ ### `serde`
+ 
+ Enables support for serializing and deserializing `&'static Encoding`-typed
+ struct fields using [Serde][1].
+ 
+ [1]: https://serde.rs/
+@@ -376,18 +362,19 @@ It is a goal to support the latest stabl
+ the version of Rust that's used for Firefox Nightly.
+ 
+ At this time, there is no firm commitment to support a version older than
+ what's required by Firefox, and there is no commitment to treat MSRV changes
+ as semver-breaking, because this crate depends on `cfg-if`, which doesn't
+ appear to treat MSRV changes as semver-breaking, so it would be useless for
+ this crate to treat MSRV changes as semver-breaking.
+ 
+-As of 2021-02-04, MSRV appears to be Rust 1.36.0 for using the crate and
++As of 2024-04-04, MSRV appears to be Rust 1.36.0 for using the crate and
+ 1.42.0 for doc tests to pass without errors about the global allocator.
++With the `simd-accel` feature, the MSRV is even higher.
+ 
+ ## Compatibility with rust-encoding
+ 
+ A compatibility layer that implements the rust-encoding API on top of
+ encoding_rs is
+ [provided as a separate crate](https://github.com/hsivonen/encoding_rs_compat)
+ (cannot be uploaded to crates.io). The compatibility layer was originally
+ written with the assuption that Firefox would need it, but it is not currently
+@@ -441,20 +428,27 @@ To regenerate the generated code:
+ - [x] Implement the rust-encoding API in terms of encoding_rs.
+ - [x] Add SIMD acceleration for Aarch64.
+ - [x] Investigate the use of NEON on 32-bit ARM.
+ - [ ] ~Investigate Björn Höhrmann's lookup table acceleration for UTF-8 as
+       adapted to Rust in rust-encoding.~
+ - [x] Add actually fast CJK encode options.
+ - [ ] ~Investigate [Bob Steagall's lookup table acceleration for UTF-8](https://github.com/BobSteagall/CppNow2018/blob/master/FastConversionFromUTF-8/Fast%20Conversion%20From%20UTF-8%20with%20C%2B%2B%2C%20DFAs%2C%20and%20SSE%20Intrinsics%20-%20Bob%20Steagall%20-%20C%2B%2BNow%202018.pdf).~
+ - [x] Provide a build mode that works without `alloc` (with lesser API surface).
+-- [ ] Migrate to `std::simd` once it is stable and declare 1.0.
++- [x] Migrate to `std::simd` ~once it is stable and declare 1.0.~
++- [ ] Migrate `unsafe` slice access by larger types than `u8`/`u16` to `align_to`.
+ 
+ ## Release Notes
+ 
++### 0.8.34
++
++* Use the `portable_simd` nightly feature of the standard library instead of the `packed_simd` crate. Only affects the `simd-accel` optional nightly feature.
++* Internal documentation improvements and minor code improvements around `unsafe`.
++* Added `rust-version` to `Cargo.toml`.
++
+ ### 0.8.33
+ 
+ * Use `packed_simd` instead of `packed_simd_2` again now that updates are back under the `packed_simd` name. Only affects the `simd-accel` optional nightly feature.
+ 
+ ### 0.8.32
+ 
+ * Removed `build.rs`. (This removal should resolve false positives reported by some antivirus products. This may break some build configurations that have opted out of Rust's guarantees against future build breakage.)
+ * Internal change to what API is used for reinterpreting the lane configuration of SIMD vectors.
+diff --git a/third_party/rust/encoding_rs/src/ascii.rs b/third_party/rust/encoding_rs/src/ascii.rs
+--- third_party/rust/encoding_rs/src/ascii.rs
++++ third_party/rust/encoding_rs/src/ascii.rs
+@@ -46,71 +46,87 @@ cfg_if! {
+         #[allow(dead_code)]
+         #[inline(always)]
+         fn likely(b: bool) -> bool {
+             b
+         }
+     }
+ }
+ 
++// Safety invariants for masks: data & mask = 0 for valid ASCII or basic latin utf-16
++
+ // `as` truncates, so works on 32-bit, too.
+ #[allow(dead_code)]
+ pub const ASCII_MASK: usize = 0x8080_8080_8080_8080u64 as usize;
+ 
+ // `as` truncates, so works on 32-bit, too.
+ #[allow(dead_code)]
+ pub const BASIC_LATIN_MASK: usize = 0xFF80_FF80_FF80_FF80u64 as usize;
+ 
+ #[allow(unused_macros)]
+ macro_rules! ascii_naive {
+     ($name:ident, $src_unit:ty, $dst_unit:ty) => {
++        /// Safety: src and dst must have len_unit elements and be aligned
++        /// Safety-usable invariant: will return Some() when it fails
++        /// to convert. The first value will be a u8 that is > 127.
+         #[inline(always)]
+         pub unsafe fn $name(
+             src: *const $src_unit,
+             dst: *mut $dst_unit,
+             len: usize,
+         ) -> Option<($src_unit, usize)> {
+             // Yes, manually omitting the bound check here matters
+             // a lot for perf.
+             for i in 0..len {
++                // Safety: len invariant used here
+                 let code_unit = *(src.add(i));
++                // Safety: Upholds safety-usable invariant here
+                 if code_unit > 127 {
+                     return Some((code_unit, i));
+                 }
++                // Safety: len invariant used here
+                 *(dst.add(i)) = code_unit as $dst_unit;
+             }
+             return None;
+         }
+     };
+ }
+ 
+ #[allow(unused_macros)]
+ macro_rules! ascii_alu {
+     ($name:ident,
++     // safety invariant: src/dst MUST be u8
+      $src_unit:ty,
+      $dst_unit:ty,
++     // Safety invariant: stride_fn must consume and produce two usizes, and return the index of the first non-ascii when it fails
+      $stride_fn:ident) => {
++        /// Safety: src and dst must have len elements, src is valid for read, dst is valid for
++        /// write
++        /// Safety-usable invariant: will return Some() when it fails
++        /// to convert. The first value will be a u8 that is > 127.
+         #[cfg_attr(feature = "cargo-clippy", allow(never_loop, cast_ptr_alignment))]
+         #[inline(always)]
+         pub unsafe fn $name(
+             src: *const $src_unit,
+             dst: *mut $dst_unit,
+             len: usize,
+         ) -> Option<($src_unit, usize)> {
+             let mut offset = 0usize;
+             // This loop is only broken out of as a `goto` forward
+             loop {
++                // Safety: until_alignment becomes the number of bytes we need to munch until we are aligned to usize
+                 let mut until_alignment = {
+                     // Check if the other unit aligns if we move the narrower unit
+                     // to alignment.
+                     //               if ::core::mem::size_of::<$src_unit>() == ::core::mem::size_of::<$dst_unit>() {
+                     // ascii_to_ascii
+                     let src_alignment = (src as usize) & ALU_ALIGNMENT_MASK;
+                     let dst_alignment = (dst as usize) & ALU_ALIGNMENT_MASK;
+                     if src_alignment != dst_alignment {
++                        // Safety: bails early and ends up in the naïve branch where usize-alignment doesn't matter
+                         break;
+                     }
+                     (ALU_ALIGNMENT - src_alignment) & ALU_ALIGNMENT_MASK
+                     //               } else if ::core::mem::size_of::<$src_unit>() < ::core::mem::size_of::<$dst_unit>() {
+                     // ascii_to_basic_latin
+                     //                   let src_until_alignment = (ALIGNMENT - ((src as usize) & ALIGNMENT_MASK)) & ALIGNMENT_MASK;
+                     //                   if (dst.add(src_until_alignment) as usize) & ALIGNMENT_MASK != 0 {
+                     //                       break;
+@@ -129,74 +145,104 @@ macro_rules! ascii_alu {
+                     // Moving pointers to alignment seems to be a pessimization on
+                     // x86_64 for operations that have UTF-16 as the internal
+                     // Unicode representation. However, since it seems to be a win
+                     // on ARM (tested ARMv7 code running on ARMv8 [rpi3]), except
+                     // mixed results when encoding from UTF-16 and since x86 and
+                     // x86_64 should be using SSE2 in due course, keeping the move
+                     // to alignment here. It would be good to test on more ARM CPUs
+                     // and on real MIPS and POWER hardware.
++                    //
++                    // Safety: This is the naïve code once again, for `until_alignment` bytes
+                     while until_alignment != 0 {
+                         let code_unit = *(src.add(offset));
+                         if code_unit > 127 {
++                            // Safety: Upholds safety-usable invariant here
+                             return Some((code_unit, offset));
+                         }
+                         *(dst.add(offset)) = code_unit as $dst_unit;
++                        // Safety: offset is the number of bytes copied so far
+                         offset += 1;
+                         until_alignment -= 1;
+                     }
+                     let len_minus_stride = len - ALU_STRIDE_SIZE;
+                     loop {
++                        // Safety: num_ascii is known to be a byte index of a non-ascii byte due to stride_fn's invariant
+                         if let Some(num_ascii) = $stride_fn(
++                            // Safety: These are known to be valid and aligned since we have at
++                            // least ALU_STRIDE_SIZE data in these buffers, and offset is the
++                            // number of elements copied so far, which according to the
++                            // until_alignment calculation above will cause both src and dst to be
++                            // aligned to usize after this add
+                             src.add(offset) as *const usize,
+                             dst.add(offset) as *mut usize,
+                         ) {
+                             offset += num_ascii;
++                            // Safety: Upholds safety-usable invariant here by indexing into non-ascii byte
+                             return Some((*(src.add(offset)), offset));
+                         }
++                        // Safety: offset continues to be the number of bytes copied so far, and
++                        // maintains usize alignment for the next loop iteration
+                         offset += ALU_STRIDE_SIZE;
++                        // Safety: This is `offset > len - stride. This loop will continue as long as
++                        // `offset <= len - stride`, which means there are `stride` bytes to still be read.
+                         if offset > len_minus_stride {
+                             break;
+                         }
+                     }
+                 }
+                 break;
+             }
++
++            // Safety: This is the naïve code, same as ascii_naive, and has no requirements
++            // other than src/dst being valid for the the right lens
+             while offset < len {
++                // Safety: len invariant used here
+                 let code_unit = *(src.add(offset));
+                 if code_unit > 127 {
++                    // Safety: Upholds safety-usable invariant here
+                     return Some((code_unit, offset));
+                 }
++                // Safety: len invariant used here
+                 *(dst.add(offset)) = code_unit as $dst_unit;
+                 offset += 1;
+             }
+             None
+         }
+     };
+ }
+ 
+ #[allow(unused_macros)]
+ macro_rules! basic_latin_alu {
+     ($name:ident,
++    // safety invariant: use u8 for src/dest for ascii, and u16 for basic_latin
+      $src_unit:ty,
+      $dst_unit:ty,
++    // safety invariant: stride function must munch ALU_STRIDE_SIZE*size(src_unit) bytes off of src and
++    // write ALU_STRIDE_SIZE*size(dst_unit) bytes to dst
+      $stride_fn:ident) => {
++        /// Safety: src and dst must have len elements, src is valid for read, dst is valid for
++        /// write
++        /// Safety-usable invariant: will return Some() when it fails
++        /// to convert. The first value will be a u8 that is > 127.
+         #[cfg_attr(
+             feature = "cargo-clippy",
+             allow(never_loop, cast_ptr_alignment, cast_lossless)
+         )]
+         #[inline(always)]
+         pub unsafe fn $name(
+             src: *const $src_unit,
+             dst: *mut $dst_unit,
+             len: usize,
+         ) -> Option<($src_unit, usize)> {
+             let mut offset = 0usize;
+             // This loop is only broken out of as a `goto` forward
+             loop {
++                // Safety: until_alignment becomes the number of bytes we need to munch from src/dest until we are aligned to usize
++                // We ensure basic-latin has the same alignment as ascii, starting with ascii since it is smaller.
+                 let mut until_alignment = {
+                     // Check if the other unit aligns if we move the narrower unit
+                     // to alignment.
+                     //               if ::core::mem::size_of::<$src_unit>() == ::core::mem::size_of::<$dst_unit>() {
+                     // ascii_to_ascii
+                     //                   let src_alignment = (src as usize) & ALIGNMENT_MASK;
+                     //                   let dst_alignment = (dst as usize) & ALIGNMENT_MASK;
+                     //                   if src_alignment != dst_alignment {
+@@ -232,66 +278,89 @@ macro_rules! basic_latin_alu {
+                     // Moving pointers to alignment seems to be a pessimization on
+                     // x86_64 for operations that have UTF-16 as the internal
+                     // Unicode representation. However, since it seems to be a win
+                     // on ARM (tested ARMv7 code running on ARMv8 [rpi3]), except
+                     // mixed results when encoding from UTF-16 and since x86 and
+                     // x86_64 should be using SSE2 in due course, keeping the move
+                     // to alignment here. It would be good to test on more ARM CPUs
+                     // and on real MIPS and POWER hardware.
++                    //
++                    // Safety: This is the naïve code once again, for `until_alignment` bytes
+                     while until_alignment != 0 {
+                         let code_unit = *(src.add(offset));
+                         if code_unit > 127 {
++                            // Safety: Upholds safety-usable invariant here
+                             return Some((code_unit, offset));
+                         }
+                         *(dst.add(offset)) = code_unit as $dst_unit;
++                        // Safety: offset is the number of bytes copied so far
+                         offset += 1;
+                         until_alignment -= 1;
+                     }
+                     let len_minus_stride = len - ALU_STRIDE_SIZE;
+                     loop {
+                         if !$stride_fn(
++                            // Safety: These are known to be valid and aligned since we have at
++                            // least ALU_STRIDE_SIZE data in these buffers, and offset is the
++                            // number of elements copied so far, which according to the
++                            // until_alignment calculation above will cause both src and dst to be
++                            // aligned to usize after this add
+                             src.add(offset) as *const usize,
+                             dst.add(offset) as *mut usize,
+                         ) {
+                             break;
+                         }
++                        // Safety: offset continues to be the number of bytes copied so far, and
++                        // maintains usize alignment for the next loop iteration
+                         offset += ALU_STRIDE_SIZE;
++                        // Safety: This is `offset > len - stride. This loop will continue as long as
++                        // `offset <= len - stride`, which means there are `stride` bytes to still be read.
+                         if offset > len_minus_stride {
+                             break;
+                         }
+                     }
+                 }
+                 break;
+             }
++            // Safety: This is the naïve code once again, for leftover bytes
+             while offset < len {
++                // Safety: len invariant used here
+                 let code_unit = *(src.add(offset));
+                 if code_unit > 127 {
++                    // Safety: Upholds safety-usable invariant here
+                     return Some((code_unit, offset));
+                 }
++                // Safety: len invariant used here
+                 *(dst.add(offset)) = code_unit as $dst_unit;
+                 offset += 1;
+             }
+             None
+         }
+     };
+ }
+ 
+ #[allow(unused_macros)]
+ macro_rules! latin1_alu {
++    // safety invariant: stride function must munch ALU_STRIDE_SIZE*size(src_unit) bytes off of src and
++    // write ALU_STRIDE_SIZE*size(dst_unit) bytes to dst
+     ($name:ident, $src_unit:ty, $dst_unit:ty, $stride_fn:ident) => {
++        /// Safety: src and dst must have len elements, src is valid for read, dst is valid for
++        /// write
+         #[cfg_attr(
+             feature = "cargo-clippy",
+             allow(never_loop, cast_ptr_alignment, cast_lossless)
+         )]
+         #[inline(always)]
+         pub unsafe fn $name(src: *const $src_unit, dst: *mut $dst_unit, len: usize) {
+             let mut offset = 0usize;
+             // This loop is only broken out of as a `goto` forward
+             loop {
++                // Safety: until_alignment becomes the number of bytes we need to munch from src/dest until we are aligned to usize
++                // We ensure the UTF-16 side has the same alignment as the Latin-1 side, starting with Latin-1 since it is smaller.
+                 let mut until_alignment = {
+                     if ::core::mem::size_of::<$src_unit>() < ::core::mem::size_of::<$dst_unit>() {
+                         // unpack
+                         let src_until_alignment = (ALU_ALIGNMENT
+                             - ((src as usize) & ALU_ALIGNMENT_MASK))
+                             & ALU_ALIGNMENT_MASK;
+                         if (dst.wrapping_add(src_until_alignment) as usize) & ALU_ALIGNMENT_MASK
+                             != 0
+@@ -308,373 +377,485 @@ macro_rules! latin1_alu {
+                             != 0
+                         {
+                             break;
+                         }
+                         dst_until_alignment
+                     }
+                 };
+                 if until_alignment + ALU_STRIDE_SIZE <= len {
++                    // Safety: This is the naïve code once again, for `until_alignment` bytes
+                     while until_alignment != 0 {
+                         let code_unit = *(src.add(offset));
+                         *(dst.add(offset)) = code_unit as $dst_unit;
++                        // Safety: offset is the number of bytes copied so far
+                         offset += 1;
*** 2691 LINES SKIPPED ***