Binary files firefox-140.10.2.orig/.cargo/.global-cache and firefox-140.10.2/.cargo/.global-cache differ
diff -rNu firefox-140.10.2.orig/.cargo/config.toml.in firefox-140.10.2/.cargo/config.toml.in
--- firefox-140.10.2.orig/.cargo/config.toml.in	Wed May  6 16:54:36 2026
+++ firefox-140.10.2/.cargo/config.toml.in	Mon May 11 04:50:32 2026
@@ -110,6 +110,11 @@
 tag = "v0.13.4"
 replace-with = "vendored-sources"
 
+[source."git+https://github.com/rust-lang/rust-bindgen?rev=9366e0af8da529c958b4cd4fcbe492d951c86f5c"]
+git = "https://github.com/rust-lang/rust-bindgen"
+rev = "9366e0af8da529c958b4cd4fcbe492d951c86f5c"
+replace-with = "vendored-sources"
+
 [source."git+https://github.com/servo/rust-cssparser?rev=958a3f098acb92ddacdce18a7ef2c4a87ac3326f"]
 git = "https://github.com/servo/rust-cssparser"
 rev = "958a3f098acb92ddacdce18a7ef2c4a87ac3326f"
diff -rNu firefox-140.10.2.orig/Cargo.lock firefox-140.10.2/Cargo.lock
--- firefox-140.10.2.orig/Cargo.lock	Wed May  6 16:54:36 2026
+++ firefox-140.10.2/Cargo.lock	Mon May 11 07:16:53 2026
@@ -454,25 +454,24 @@
 
 [[package]]
 name = "bindgen"
-version = "0.64.999"
+version = "0.69.999"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.72.0",
 ]
 
 [[package]]
 name = "bindgen"
-version = "0.69.4"
+version = "0.72.0"
+source = "git+https://github.com/rust-lang/rust-bindgen?rev=9366e0af8da529c958b4cd4fcbe492d951c86f5c#9366e0af8da529c958b4cd4fcbe492d951c86f5c"
 dependencies = [
  "bitflags 2.9.0",
  "cexpr",
  "clang-sys",
- "itertools 0.10.999",
- "lazy_static",
- "lazycell",
+ "itertools 0.14.0",
  "proc-macro2",
  "quote",
  "regex",
- "rustc-hash 1.999.999",
+ "rustc-hash 2.1.1",
  "shlex",
  "syn",
 ]
@@ -947,7 +946,7 @@
 name = "cocoabind"
 version = "0.1.0"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "block",
  "mozbuild",
  "objc",
@@ -1080,7 +1079,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f3120ebb80a9de008e638ad833d4127d50ea3d3a960ea23ea69bc66d9358a028"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
 ]
 
 [[package]]
@@ -1208,7 +1207,7 @@
 version = "1.0.0"
 dependencies = [
  "anyhow",
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "block",
  "buildid_reader",
  "bytes",
@@ -2395,7 +2394,7 @@
 version = "0.1.0"
 dependencies = [
  "bincode",
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "lazy_static",
  "mozbuild",
  "profiler-macros",
@@ -2878,7 +2877,7 @@
 name = "gtkbind"
 version = "0.1.0"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "mozbuild",
 ]
 
@@ -3041,7 +3040,7 @@
 version = "0.1.1"
 dependencies = [
  "base64 0.22.1",
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "cfg-if",
  "http",
  "hyper",
@@ -3666,12 +3665,6 @@
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
-name = "lazycell"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
-
-[[package]]
 name = "leak"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4469,7 +4462,7 @@
 dependencies = [
  "allocator-api2",
  "arrayvec",
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "bitflags 2.9.0",
  "byteorder",
  "bytes",
@@ -4639,7 +4632,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4c30d3771729ec4349aae3b1a7c0b6b4a1500459e60b1fda95fe0657c3711574"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "cfg_aliases",
  "libc",
  "mozbuild",
@@ -4705,7 +4698,6 @@
 [[package]]
 name = "neqo-common"
 version = "0.13.4"
-source = "git+https://github.com/mozilla/neqo?tag=v0.13.4#c3179d9f363bf92a908d90e4240b315b9ff72516"
 dependencies = [
  "enum-map",
  "env_logger",
@@ -4718,9 +4710,8 @@
 [[package]]
 name = "neqo-crypto"
 version = "0.13.4"
-source = "git+https://github.com/mozilla/neqo?tag=v0.13.4#c3179d9f363bf92a908d90e4240b315b9ff72516"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "enum-map",
  "log",
  "mozbuild",
@@ -4892,7 +4883,7 @@
 version = "0.3.0"
 source = "git+https://github.com/beurdouche/nss-gk-api?rev=e48a946811ffd64abc78de3ee284957d8d1c0d63#e48a946811ffd64abc78de3ee284957d8d1c0d63"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.72.0",
  "log",
  "mozbuild",
  "once_cell",
@@ -4998,7 +4989,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "578cb11a3fb5c85697ed8bb850d5ad1cbf819d3eea05c2b253cf1d240fbb10c5"
 dependencies = [
- "bindgen 0.64.999",
+ "bindgen 0.69.999",
  "byteorder",
  "hex",
  "lazy_static",
@@ -5251,7 +5242,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d0fabbdbe64b22820753da90995b3a73d02907eaeeac6f2414962a566aaa18ea"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.72.0",
 ]
 
 [[package]]
@@ -6344,7 +6335,7 @@
  "app_units",
  "arrayvec",
  "atomic_refcell",
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "bitflags 2.9.0",
  "byteorder",
  "cssparser",
@@ -6594,7 +6585,7 @@
 name = "test-trust-anchors-static"
 version = "0.1.0"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "mozbuild",
  "mozilla-central-workspace-hack",
  "nom",
@@ -6864,7 +6855,7 @@
 name = "trust-anchors"
 version = "0.1.0"
 dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.999",
  "mozbuild",
  "nom",
  "pkcs11-bindings",
diff -rNu firefox-140.10.2.orig/Cargo.toml firefox-140.10.2/Cargo.toml
--- firefox-140.10.2.orig/Cargo.toml	Wed May  6 16:54:36 2026
+++ firefox-140.10.2/Cargo.toml	Mon May 11 05:33:36 2026
@@ -160,12 +160,12 @@
 # else we do use requires backtrace, so dummy it out for now.
 backtrace = { path = "build/rust/backtrace" }
 
-# Patch bindgen 0.63 to 0.69
-bindgen_0_63 = { package = "bindgen", path = "build/rust/bindgen-0.63" }
-# Locally patch bindgen for https://github.com/rust-lang/rust-bindgen/pull/2824
-# and for bug 1945218
-bindgen = { path = "third_party/rust/bindgen" }
+# Locally patch bindgen to a yet-unreleased version.
+bindgen_0_72 = { package = "bindgen", git = "https://github.com/rust-lang/rust-bindgen", rev = "9366e0af8da529c958b4cd4fcbe492d951c86f5c" }
 
+# Patch bindgen 0.69 to 0.72
+bindgen = { path = "build/rust/bindgen" }
+
 # Patch nix 0.26 to 0.30+
 nix_0_26 = { package = "nix", path = "build/rust/nix" }
 
@@ -266,6 +266,12 @@
 
 # allocator-api2 + f95e3419ce41883904fcb2279b52aa35b5f04d76 + fdd92751afa7ce34408b677004b429d597e72c90
 allocator-api2 = { git = "https://github.com/glandium/allocator-api2", rev = "ad5f3d56a5a4519eff52af4ff85293431466ef5c" }
+
+# Patch neqo-crypto (and neqo-common to avoid duplicating it) to cherry-pick
+# https://github.com/mozilla/neqo/pull/2913
+[patch."https://github.com/mozilla/neqo"]
+neqo-crypto = { path = "third_party/rust/neqo-crypto" }
+neqo-common = { path = "third_party/rust/neqo-common" }
 
 # application-services overrides to make updating them all simpler.
 context_id = { git = "https://github.com/mozilla/application-services", rev = "f5907a411e52a3985d0369d71c486eb507c2c4e6" }
diff -rNu firefox-140.10.2.orig/build/rust/bindgen/Cargo.toml firefox-140.10.2/build/rust/bindgen/Cargo.toml
--- firefox-140.10.2.orig/build/rust/bindgen/Cargo.toml	Thu Jan  1 01:00:00 1970
+++ firefox-140.10.2/build/rust/bindgen/Cargo.toml	Mon May 11 05:33:19 2026
@@ -0,0 +1,18 @@
+[package]
+name = "bindgen"
+version = "0.69.999"
+edition = "2018"
+license = "MPL-2.0"
+
+[lib]
+path = "lib.rs"
+
+[dependencies.bindgen]
+version = "0.72.0"
+default-features = false
+
+[features]
+logging = ["bindgen/logging"]
+runtime = ["bindgen/runtime"]
+static = ["bindgen/static"]
+which-rustfmt = ["bindgen/which-rustfmt"]
diff -rNu firefox-140.10.2.orig/build/rust/bindgen/lib.rs firefox-140.10.2/build/rust/bindgen/lib.rs
--- firefox-140.10.2.orig/build/rust/bindgen/lib.rs	Thu Jan  1 01:00:00 1970
+++ firefox-140.10.2/build/rust/bindgen/lib.rs	Mon May 11 04:49:32 2026
@@ -0,0 +1,5 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pub use bindgen::*;
diff -rNu firefox-140.10.2.orig/layout/style/ServoBindings.toml firefox-140.10.2/layout/style/ServoBindings.toml
--- firefox-140.10.2.orig/layout/style/ServoBindings.toml	Wed May  6 16:54:43 2026
+++ firefox-140.10.2/layout/style/ServoBindings.toml	Mon May 11 04:51:28 2026
@@ -297,8 +297,10 @@
     "std::atomic",
     "std::.*::atomic",
     "std::atomic___base",
+    "std::function",
     "std::tuple.*", # Causes "Cannot find type _Pred in this scope" error on mac, like rust-skia#571
     "std::.*::tuple.*",
+    "mozilla::dom::FrameRequestManager",
 
     "mozilla::dom::Touch",
     "mozilla::dom::Sequence",
diff -rNu firefox-140.10.2.orig/servo/components/style/gecko/snapshot_helpers.rs firefox-140.10.2/servo/components/style/gecko/snapshot_helpers.rs
--- firefox-140.10.2.orig/servo/components/style/gecko/snapshot_helpers.rs	Wed May  6 16:54:45 2026
+++ firefox-140.10.2/servo/components/style/gecko/snapshot_helpers.rs	Mon May 11 04:49:32 2026
@@ -58,7 +58,7 @@
             .mAtomArray
             .as_ref();
         let array =
-            (*attr_array).mArray.as_ptr() as *const structs::nsTArray<structs::RefPtr<nsAtom>>;
+            (*attr_array).mArray.0.as_ptr() as *const structs::nsTArray<structs::RefPtr<nsAtom>>;
         return Class::More(&**array);
     }
     debug_assert_eq!(base_type, structs::nsAttrValue_ValueBaseType_eStringBase);
diff -rNu firefox-140.10.2.orig/supply-chain/audits.toml firefox-140.10.2/supply-chain/audits.toml
--- firefox-140.10.2.orig/supply-chain/audits.toml	Wed May  6 16:54:45 2026
+++ firefox-140.10.2/supply-chain/audits.toml	Mon May 11 04:49:32 2026
@@ -1028,6 +1028,19 @@
 criteria = "safe-to-deploy"
 delta = "0.69.2 -> 0.69.4"
 
+[[audits.bindgen]]
+who = "Emilio Cobos Álvarez <emilio@crisal.io>"
+criteria = "safe-to-deploy"
+delta = "0.69.4 -> 0.72.0"
+notes = "I'm the primary maintainer of this crate."
+
+[[audits.bindgen]]
+who = "Emilio Cobos Álvarez <emilio@crisal.io>"
+criteria = "safe-to-deploy"
+delta = "0.72.0 -> 0.72.0@git:9366e0af8da529c958b4cd4fcbe492d951c86f5c"
+importable = false
+notes = "Authored or reviewed all relevant changes upstream."
+
 [[audits.bit-set]]
 who = "Aria Beingessner <a.beingessner@gmail.com>"
 criteria = "safe-to-deploy"
diff -rNu firefox-140.10.2.orig/supply-chain/config.toml firefox-140.10.2/supply-chain/config.toml
--- firefox-140.10.2.orig/supply-chain/config.toml	Wed May  6 16:54:45 2026
+++ firefox-140.10.2/supply-chain/config.toml	Mon May 11 04:49:32 2026
@@ -31,9 +31,9 @@
 audit-as-crates-io = true
 notes = "This is the upstream code plus a few local fixes, see bug 1685697."
 
-[policy."bindgen:0.69.4"]
+[policy."bindgen:0.72.0@git:9366e0af8da529c958b4cd4fcbe492d951c86f5c"]
 audit-as-crates-io = true
-notes = "This is the upstream code plus a fix for clang trunk. See bug 1894093."
+notes = "This is the upstream code not yet released"
 
 [policy.chardetng]
 audit-as-crates-io = true
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/.cargo-checksum.json firefox-140.10.2/third_party/rust/bindgen/.cargo-checksum.json
--- firefox-140.10.2.orig/third_party/rust/bindgen/.cargo-checksum.json	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/.cargo-checksum.json	Mon May 11 04:49:32 2026
@@ -1 +1 @@
-{"files":{"Cargo.toml":"bebb685bfd8df63474c92bfb7f787573ef78eb70920aceb38a8a746968380f96","LICENSE":"c23953d9deb0a3312dbeaf6c128a657f3591acee45067612fa68405eaa4525db","README.md":"b2334e4077a9bc329516e3e0c7f89887c4f073647d95fb71b6917edf4c310ba3","build.rs":"4a9c4ac3759572e17de312a9d3f4ced3b6fd3c71811729e5a8d06bfbd1ac8f82","callbacks.rs":"cd5a1b0fc665b034d97615d0b6817cbef299dbf5276254c7e63f1c29674993ad","clang.rs":"278ca0d89251df8a6b40bdccd27827e310d16872ff86fa23b60d581615607630","codegen/bitfield_unit.rs":"fddeaeab5859f4e82081865595b7705f5c0774d997df95fa5c655b81b9cae125","codegen/bitfield_unit_tests.rs":"9df86490de5e9d66ccea583dcb686dd440375dc1a3c3cf89a89d5de3883bf28a","codegen/dyngen.rs":"6d8bed53c6de66bc658b3186041c2b75549f49b0f0363ff18b87c8dcf2f5a05b","codegen/error.rs":"0c3d198f4866ccbbcd8b1136fc5cfd2507a9eca5ab85934af29a7e2a7d8d8c2a","codegen/helpers.rs":"443a2c3495185ced2a9d68c02204bebfa8c4186f4275bf9ed3af90c3a3e159d7","codegen/impl_debug.rs":"80df6136327b1ca8c7d1c2961290b5ab00b85b49b22c02f26a590bc68fb230af","codegen/impl_partialeq.rs":"db739d7ba6f5ba4033d6bf62c276f35217c20eab27230cf07dadf59e8b2f71bb","codegen/mod.rs":"206e4e2c14cec17c13d11e568557332b51ce1e41ce8128182de44dab69221662","codegen/postprocessing/merge_extern_blocks.rs":"284457a3c75e945217bab4e5a4280fef0fcc03c31e12cc5010aab87f34c0b6c7","codegen/postprocessing/mod.rs":"160a6d6701cabf2514e23570df1bd1b648c909cc27b7c583f21d98fe0c16722e","codegen/postprocessing/sort_semantically.rs":"f465d1e8cc119082eb79c164b5cd780a370821e8bf56585b287dd3b51fc4a542","codegen/serialize.rs":"1f1eb8b04fec9655dc302442451f9622ad6365eb37bf588a119a60e79f37002c","codegen/struct_layout.rs":"922cc71fb309716879aeea4775bbc29751ca5d431083ca83d7beb0a90862a302","deps.rs":"af3dd24a7808b5abf0c4ed4b10bbceb8eef32be980ff085b8a766d8f089af1a4","diagnostics.rs":"dc40cd5e9710922422c5c9420e2351f5d976e7a1d7275e4f4ce742cad9eb53f8","extra_assertions.rs":"fb4484c0e9fcbea9ec7265f5fbd01e2b33ac022b2b17e060dce7886819d57e40","features.rs":"b27adc6bb50e9aae50fd75568a7576382c6409f585b6be0047d7a9314c98d569","ir/analysis/derive.rs":"cba290e9c4ba271e90524149ad3b874f37843bfdfab12d513cc85d2665447fd5","ir/analysis/has_destructor.rs":"e7e95c3b0989b6375cd3eabaac85a36ecc2915a1fd3700c7d26fe04e8dc83ba3","ir/analysis/has_float.rs":"a56b97bf913f132c2c63dc202b45c692c416a8c9fdc6b2baeee30362fb0d4405","ir/analysis/has_type_param_in_array.rs":"788ebb4ba2cf46a22f1e4ff3005d51f38d414b72e95355f7ff4125521e2d9525","ir/analysis/has_vtable.rs":"83efa40ae89147170eabdff1387e60aba574ca4cd4cdef22692753594f09d6c6","ir/analysis/mod.rs":"9d949c27451da4ed72994b31c04ddeb89eeb342fd23ea572d3962d4ccf774841","ir/analysis/sizedness.rs":"f0a9302f3c6ad694d76cfab11dbaf5392ecaf7f04bc7b211a5a003776b963896","ir/analysis/template_params.rs":"3ff27e2198e292a348876aa1faba39cc4b1870a24a7e173feac0b3c592001e13","ir/annotations.rs":"5ed03d025862d0d21852a76c86a993772624e123fdc3752415d588a0b4e643ab","ir/comment.rs":"4c9c20b5a3da086211e92adec0822831dbc0b7ebee98fee313edcae9ae8d55ec","ir/comp.rs":"c048866353695ac8190ab03511123be82d34ca73fb865a2578cb5a2e04390431","ir/context.rs":"03175218512c42792aae7b56a764c0237a447664dda5f1a8269a42bed46d3be2","ir/derive.rs":"c21e470bb0091f20bfa366110880d48984fc3cf7071fdf36eccfa64f3eca231c","ir/dot.rs":"75bdfd83d9e754ba726f6a5529ba1d9ff46f5bf49bf237452985eb008fed0854","ir/enum_ty.rs":"f4bfa6d18ba4977fb66f5d5e4a7674eded93b761404d91cdd6fdd50029db455a","ir/function.rs":"0ecee923382b0a49265bc970ac90a73740ec5ba3c33466b2cfe8aa462df59bd5","ir/int.rs":"601736f0ad0949e40684a9ce89bafbfefa71743df6ee6c342e44888a0f141ae0","ir/item.rs":"65f2351dd3971d8a76470a78f5b6b1ebdda067ab5bae4641246aa986d9579e29","ir/item_kind.rs":"33e21104b0bb824a696a52cd520567ae56158010a1df14777e68ac5f8ad7e8fa","ir/layout.rs":"8fbafc0eeee17abb703a18613be1066e38838d4b67f5916f714bf545e545bc1a","ir/mod.rs":"a3b98b1732111a980a795c72eaf1e09101e842ef2de76b4f2d4a7857f8d4cee4","ir/module.rs":"b2961ffa4acb0c19f084c5db084b8a17bda7158066782a73b80ee7d838789bf9","ir/objc.rs":"8f57a9180d57a690449f20ed1be80209db5f8a410bb067ae8bf5e0ecab16a5e4","ir/template.rs":"3f59efa9670ca90215d4374be869c9dbecb98a8d1041e7c6e4ab69a62bb982c2","ir/traversal.rs":"a4ec73d3533d4b93386153baf6a2ca846ee51228c76ed51105229d3ddcd74466","ir/ty.rs":"fd71d11e89e085921317349e1912ab56e7335d870c2d25df9e13a8ffbd6430c9","ir/var.rs":"40d18226706de0ee5f002d0b5617dbcba35de0605edd531c75e3a76d000f0f4f","lib.rs":"7496f72a177b5965ed56a2ab9af0f64e70abbc53cc6c196a15e6760dd6235adf","log_stubs.rs":"9f974e041e35c8c7e29985d27ae5cd0858d68f8676d1dc005c6388d7d011707f","options/as_args.rs":"76efa4e662cc7f89ef1c1fe089d03a3c1c019ffe2aa0a30a4d49ed41e987d1c7","options/helpers.rs":"f4a7681e29b2dcc3be9249478c499d685b9e29d4f4ca4ae8bff7a91668cd8f15","options/mod.rs":"1805cec86c563633b29b57292287c9efd3b5c724132ec1c13acee57858942e74","parse.rs":"fce3616e0464aa7414888e5d00d4df18c83bb3034a1c807d36a07a3c586e475a","regex_set.rs":"b411d64bc803947a3f69dcedcd7d03716aacbc7b1c5148b82de1cc469d9336d9","time.rs":"8efe317e7c6b5ba8e0865ce7b49ca775ee8a02590f4241ef62f647fa3c22b68e"},"package":"a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"}
\ No newline at end of file
+{"files":{"Cargo.toml":"a07e277ca0e2a5c37caed762a150075a651ed56a7c0a32b38f32669d2ac7c5d3","LICENSE":"c23953d9deb0a3312dbeaf6c128a657f3591acee45067612fa68405eaa4525db","build.rs":"f7a10af0a21662e104e0058da7e3471a20be328eef6c7c41988525be90fdfe92","callbacks.rs":"3f0ed344a4d27fc8f893f21b1f9cd742d85ccbc23441d745e8a147b6072469bd","clang.rs":"e991300ce9b1f0b9fb4a0b4bd32e899b6cfa546f034858f08bf57678b3d7044c","codegen/bitfield_unit.rs":"1d598b042a9ce6c2f8a2c6eb44c9ee6e2d41865f25fe34ce747a0376c4d9b951","codegen/bitfield_unit_tests.rs":"9915cb19bf37fc1013fc72753bae153f7c249280daec94b25fb461f9936dffa4","codegen/dyngen.rs":"1b42f7fa9fb65ff2fa898b289a3b934d7b21c5ba6c1b3e37aa97f0faa87769a0","codegen/error.rs":"67680c4d171d63848d9eb4ddd5f100be7463564e8c1c9203fefc0e61a19dfdec","codegen/helpers.rs":"9bcec3163826edc9b22256c9bf33dd2964809349b801fc6fa5e9158da4eb0458","codegen/impl_debug.rs":"3e55b361aa56d9b6ef2bdb96ede983385a3b1030aa0f46235cb4d218ad66b2a1","codegen/impl_partialeq.rs":"d4fb2ef354086c3dd5a4c4b69d5deab652fdef225725e28dc694e791c1573d0c","codegen/mod.rs":"b106576fce6df7a3933eaa112d805d42653c2d1287953a002a3bb70b38715f87","codegen/postprocessing/merge_extern_blocks.rs":"3e244fe62abcadcb6dae069c37d21220f5351dc7b8c33c5576a5193731933c4c","codegen/postprocessing/mod.rs":"160a6d6701cabf2514e23570df1bd1b648c909cc27b7c583f21d98fe0c16722e","codegen/postprocessing/sort_semantically.rs":"5099e8fc134a92cb72b585bd95854a52ff81e2f5307c3b83617d83e7408302ee","codegen/serialize.rs":"d57eb31ba0fda825241f886336279573050b396e52badf3886e0bc76a15110ad","codegen/struct_layout.rs":"b5f4a010d60586e5079284f7f02af53d961f02a8e6a2cf09dfab2127f20c3734","deps.rs":"297dcc2be53af1a3ea4f77e16902a641f3e6f0baad09c06a6ea26050a0281c18","diagnostics.rs":"9c80043ac9fa8f683019577f311853a0d5929e41a95b3255736f80105914cdfa","extra_assertions.rs":"1596b7e7f031714dc699ebda135e795f1ecfc971ce9de6861a3c00e77fcef011","features.rs":"cde8d530d03c2793cbbb257db3d64e345af26731b73f45b4b60a618d062443c3","ir/analysis/derive.rs":"42ef56b1adda1b4d2797c7845b909fde8c87e2bf51920b490b7129936d5c494c","ir/analysis/has_destructor.rs":"d75be0d349e744ef198d89f04274cc024e36eb255fe7fb7b660ce805c8977bae","ir/analysis/has_float.rs":"9fb88d05c5920e9000e5cb6e87775c0d1042a6b11205577e281ba281e6e6acdb","ir/analysis/has_type_param_in_array.rs":"0975d1ce43bcba97eb303635118e74d494d46ac67cf5ee53faf6f6584a556cef","ir/analysis/has_vtable.rs":"dcaf36d4d0148db3b5690166e32853a58eda7721c9ea5217723a5dba7d5295b8","ir/analysis/mod.rs":"93edca96d765dfa19ac231198027b0ba48c623502a8be1dbf799a241cd6b304b","ir/analysis/sizedness.rs":"0b78e70737e038ebdee2c3d195194a060c9287000b9059ded0686728a89b4ff2","ir/analysis/template_params.rs":"a8dfd3e02b1745a5b7c6faa16309bd0b8a88d76b7fedca27c322782cc9e77177","ir/annotations.rs":"8397ced62808fe99dfdde35792cd8b2389e7828d752a6c8aa3a70c1e14595e11","ir/comment.rs":"57863204d329ae82872ecc4829cc299969ff07da3a32a4a13d7d84429f55b84d","ir/comp.rs":"8df9d537b17994f85b3d506658c20b080d18b805ca8b73cc7af15f4d5397e8ef","ir/context.rs":"e9e1ed78f2258ff2556688d658ebf422308732924683c7860853f1c38a607066","ir/derive.rs":"09860cffec0ebecce31da0c6c9ea0cf9a0d4784262ff4eb16ea459c0d0782ac9","ir/dot.rs":"8b8f6dd13e662fcb4114949025cb43467b34fa4998a3371c101db5dd82688f44","ir/enum_ty.rs":"5d7ae2e3de172d9812425e8cc6e30d559b0743620b3b09f7d72f3b05a7e1ce98","ir/function.rs":"94bdc59bc39e043825d6cbbf5a461329462f0eb74c4c216002e1da86bf93e46b","ir/int.rs":"1bf1e4d87eca13ee2fc38ff4d56c266f303f188796f5c0d290f53162798d2d01","ir/item.rs":"6983232b2362f4d23261754f0ef242162ce66bbe9398a7707a88cb7bcee0f0fd","ir/item_kind.rs":"799fab994b5ed35045786a68003c2c12b6601cf3b07e8ccc0b9acd6f921217e0","ir/layout.rs":"7a7173efde2a9daed8562d657bad563922f798e44055e35899dd47badd46c52d","ir/mod.rs":"a3b98b1732111a980a795c72eaf1e09101e842ef2de76b4f2d4a7857f8d4cee4","ir/module.rs":"617867617ebd7e56157a9ba057441ce11a33c25138a1da64646f44ccaae7c762","ir/objc.rs":"092c7f32cec4191aa6235e4554420ab2053e0c7fec5ece016a7ed303763e8547","ir/template.rs":"1114c0924323f8b30bb32dbb3f6730dd7f5bc1f0771ad5099738e8e57111c07d","ir/traversal.rs":"3ebde94ead0fe69d51541ab61d700c7c1f6382574e4c110b8c7fe3e2c6218f19","ir/ty.rs":"6965a7678927a51c76c590aeb1d780412ad9f8cd4d11ea37e56e0a9669e5b06a","ir/var.rs":"2a94decd3adfdccd3bd0015b460d180838e3c92b122b632eed44032b80cad120","lib.rs":"805f7d4547f4e9e3ab024e98e39c6c3c2b74f2fd6cdd657915a5d0bbd7655dab","log_stubs.rs":"a636d59af2fd3745c2e416e1ab8a1e1a3888ea84cd4657a321ce22f15e0c5a87","options/as_args.rs":"a1a5e7f0dde82590371fc1a9ea5fde7f3e2252530ca74d98bb49a8ce06cc864f","options/cli.rs":"7712b6d4d3f8f4dc9a07e5e0fe21687b05c118e70e9c1952a2eebc34da20c2c4","options/helpers.rs":"f4a7681e29b2dcc3be9249478c499d685b9e29d4f4ca4ae8bff7a91668cd8f15","options/mod.rs":"2bedfdd6aa9817bdc8155ca8290e0d6055ef6d7a90353d6cb99ddc6121609693","parse.rs":"fce3616e0464aa7414888e5d00d4df18c83bb3034a1c807d36a07a3c586e475a","regex_set.rs":"d8995adb9e5cecc2d738e662a62d5081150bf967cb67e1206070e22b7265578a","time.rs":"1429af446b2b38c70ceec82c4202d4822c618cad47ba502dce72dbdc4cbb425e"},"package":null}
\ No newline at end of file
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/Cargo.toml firefox-140.10.2/third_party/rust/bindgen/Cargo.toml
--- firefox-140.10.2.orig/third_party/rust/bindgen/Cargo.toml	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/Cargo.toml	Mon May 11 04:49:32 2026
@@ -10,10 +10,10 @@
 # See Cargo.toml.orig for the original contents.
 
 [package]
-edition = "2018"
-rust-version = "1.60.0"
+edition = "2021"
+rust-version = "1.70.0"
 name = "bindgen"
-version = "0.69.4"
+version = "0.72.0"
 authors = [
     "Jyun-Yan You <jyyou.tw@gmail.com>",
     "Emilio Cobos Álvarez <emilio@crisal.io>",
@@ -21,10 +21,15 @@
     "The Servo project developers",
 ]
 build = "build.rs"
+autolib = false
+autobins = false
+autoexamples = false
+autotests = false
+autobenches = false
 description = "Automatically generates Rust FFI bindings to C and C++ libraries."
 homepage = "https://rust-lang.github.io/rust-bindgen/"
 documentation = "https://docs.rs/bindgen"
-readme = "README.md"
+readme = "../README.md"
 keywords = [
     "bindings",
     "ffi",
@@ -60,13 +65,30 @@
 # {{version}} ({{date}})"""
 search = "# Unreleased"
 
+[features]
+__cli = [
+    "dep:clap",
+    "dep:clap_complete",
+]
+__testing_only_extra_assertions = []
+__testing_only_libclang_16 = []
+__testing_only_libclang_9 = []
+default = [
+    "logging",
+    "prettyplease",
+    "runtime",
+]
+experimental = ["dep:annotate-snippets"]
+logging = ["dep:log"]
+runtime = ["clang-sys/runtime"]
+static = ["clang-sys/static"]
+
 [lib]
 name = "bindgen"
 path = "lib.rs"
 
 [dependencies.annotate-snippets]
-version = "0.9.1"
-features = ["color"]
+version = "0.11.4"
 optional = true
 
 [dependencies.bitflags]
@@ -77,18 +99,21 @@
 
 [dependencies.clang-sys]
 version = "1"
-features = ["clang_6_0"]
+features = ["clang_11_0"]
 
+[dependencies.clap]
+version = "4"
+features = ["derive"]
+optional = true
+
+[dependencies.clap_complete]
+version = "4"
+optional = true
+
 [dependencies.itertools]
-version = ">=0.10,<0.13"
+version = ">=0.10,<0.15"
 default-features = false
 
-[dependencies.lazy_static]
-version = "1"
-
-[dependencies.lazycell]
-version = "1"
-
 [dependencies.log]
 version = "0.4"
 optional = true
@@ -99,15 +124,14 @@
 optional = true
 
 [dependencies.proc-macro2]
-version = "1"
-default-features = false
+version = "1.0.80"
 
 [dependencies.quote]
 version = "1"
 default-features = false
 
 [dependencies.regex]
-version = "1.5.1"
+version = "1.5.3"
 features = [
     "std",
     "unicode-perl",
@@ -115,7 +139,7 @@
 default-features = false
 
 [dependencies.rustc-hash]
-version = "1.0.1"
+version = "2.1.0"
 
 [dependencies.shlex]
 version = "1"
@@ -128,24 +152,38 @@
     "visit-mut",
 ]
 
-[dependencies.which]
-version = "4.2.1"
-optional = true
-default-features = false
+[lints.clippy]
+cast_possible_truncation = "allow"
+cast_possible_wrap = "allow"
+cast_precision_loss = "allow"
+cast_sign_loss = "allow"
+default_trait_access = "allow"
+enum_glob_use = "allow"
+ignored_unit_patterns = "allow"
+implicit_hasher = "allow"
+items_after_statements = "allow"
+match_same_arms = "allow"
+maybe_infinite_iter = "allow"
+missing_errors_doc = "allow"
+missing_panics_doc = "allow"
+module_name_repetitions = "allow"
+must_use_candidate = "allow"
+redundant_closure_for_method_calls = "allow"
+return_self_not_must_use = "allow"
+similar_names = "allow"
+struct_excessive_bools = "allow"
+struct_field_names = "allow"
+too_many_lines = "allow"
+trivially_copy_pass_by_ref = "allow"
+unnecessary_wraps = "allow"
+unreadable_literal = "allow"
+unused_self = "allow"
+used_underscore_binding = "allow"
+wildcard_imports = "allow"
 
-[features]
-__cli = []
-__testing_only_extra_assertions = []
-__testing_only_libclang_16 = []
-__testing_only_libclang_9 = []
-default = [
-    "logging",
-    "prettyplease",
-    "runtime",
-    "which-rustfmt",
-]
-experimental = ["dep:annotate-snippets"]
-logging = ["dep:log"]
-runtime = ["clang-sys/runtime"]
-static = ["clang-sys/static"]
-which-rustfmt = ["dep:which"]
+[lints.clippy.pedantic]
+level = "warn"
+priority = -1
+
+[lints.rust]
+unused_qualifications = "warn"
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/README.md firefox-140.10.2/third_party/rust/bindgen/README.md
--- firefox-140.10.2.orig/third_party/rust/bindgen/README.md	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/README.md	Thu Jan  1 01:00:00 1970
@@ -1,89 +0,0 @@
-[![crates.io](https://img.shields.io/crates/v/bindgen.svg)](https://crates.io/crates/bindgen)
-[![docs.rs](https://docs.rs/bindgen/badge.svg)](https://docs.rs/bindgen/)
-
-# `bindgen`
-
-**`bindgen` automatically generates Rust FFI bindings to C (and some C++) libraries.**
-
-For example, given the C header `doggo.h`:
-
-```c
-typedef struct Doggo {
-    int many;
-    char wow;
-} Doggo;
-
-void eleven_out_of_ten_majestic_af(Doggo* pupper);
-```
-
-`bindgen` produces Rust FFI code allowing you to call into the `doggo` library's
-functions and use its types:
-
-```rust
-/* automatically generated by rust-bindgen 0.99.9 */
-
-#[repr(C)]
-pub struct Doggo {
-    pub many: ::std::os::raw::c_int,
-    pub wow: ::std::os::raw::c_char,
-}
-
-extern "C" {
-    pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo);
-}
-```
-
-## Users Guide
-
-[📚 Read the `bindgen` users guide here! 📚](https://rust-lang.github.io/rust-bindgen)
-
-## MSRV
-
-The `bindgen` minimum supported Rust version is **1.60.0**.
-
-The `bindgen-cli` minimum supported Rust version is **1.64.0**.
-
-No MSRV bump policy has been established yet, so MSRV may increase in any release.
-
-The MSRV is the minimum Rust version that can be used to *compile* each crate. However, `bindgen` and `bindgen-cli` can generate bindings that are compatible with Rust versions below the current MSRV.
-
-Most of the time, the `bindgen-cli` crate will have a more recent MSRV than `bindgen` as crates such as `clap` require it. 
-
-## API Reference
-
-[API reference documentation is on docs.rs](https://docs.rs/bindgen)
-
-## Environment Variables
-
-In addition to the [library API](https://docs.rs/bindgen) and [executable command-line API][bindgen-cmdline],
-`bindgen` can be controlled through environment variables.
-
-End-users should set these environment variables to modify `bindgen`'s behavior without modifying the source code of direct consumers of `bindgen`.
-
-- `BINDGEN_EXTRA_CLANG_ARGS`: extra arguments to pass to `clang`
-    - Arguments are whitespace-separated
-    - Use shell-style quoting to pass through whitespace
-    - Examples:
-        - Specify alternate sysroot: `--sysroot=/path/to/sysroot`
-        - Add include search path with spaces: `-I"/path/with spaces"`
-- `BINDGEN_EXTRA_CLANG_ARGS_<TARGET>`: similar to `BINDGEN_EXTRA_CLANG_ARGS`,
-   but used to set per-target arguments to pass to clang. Useful to set system include
-   directories in a target-specific way in cross-compilation environments with multiple targets.
-   Has precedence over `BINDGEN_EXTRA_CLANG_ARGS`.
-
-Additionally, `bindgen` uses `libclang` to parse C and C++ header files.
-To modify how `bindgen` searches for `libclang`, see the [`clang-sys` documentation][clang-sys-env].
-For more details on how `bindgen` uses `libclang`, see the [`bindgen` users guide][bindgen-book-clang].
-
-## Releases
-
-We don't follow a specific release calendar, but if you need a release please
-file an issue requesting that (ping `@emilio` for increased effectiveness).
-
-## Contributing
-
-[See `CONTRIBUTING.md` for hacking on `bindgen`!](./CONTRIBUTING.md)
-
-[bindgen-cmdline]: https://rust-lang.github.io/rust-bindgen/command-line-usage.html
-[clang-sys-env]: https://github.com/KyleMayes/clang-sys#environment-variables
-[bindgen-book-clang]: https://rust-lang.github.io/rust-bindgen/requirements.html#clang
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/build.rs firefox-140.10.2/third_party/rust/bindgen/build.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/build.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/build.rs	Mon May 11 04:49:32 2026
@@ -20,10 +20,10 @@
     println!("cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS");
     println!(
         "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}",
-        std::env::var("TARGET").unwrap()
+        env::var("TARGET").unwrap()
     );
     println!(
         "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}",
-        std::env::var("TARGET").unwrap().replace('-', "_")
+        env::var("TARGET").unwrap().replace('-', "_")
     );
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/callbacks.rs firefox-140.10.2/third_party/rust/bindgen/callbacks.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/callbacks.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/callbacks.rs	Mon May 11 04:49:32 2026
@@ -4,24 +4,21 @@
 pub use crate::ir::derive::CanDerive as ImplementsTrait;
 pub use crate::ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
 pub use crate::ir::int::IntKind;
+pub use cexpr::token::Kind as TokenKind;
+pub use cexpr::token::Token;
 use std::fmt;
 
 /// An enum to allow ignoring parsing of macros.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
 pub enum MacroParsingBehavior {
     /// Ignore the macro, generating no code for it, or anything that depends on
     /// it.
     Ignore,
     /// The default behavior bindgen would have otherwise.
+    #[default]
     Default,
 }
 
-impl Default for MacroParsingBehavior {
-    fn default() -> Self {
-        MacroParsingBehavior::Default
-    }
-}
-
 /// A trait to allow configuring different kinds of types in different
 /// situations.
 pub trait ParseCallbacks: fmt::Debug {
@@ -54,6 +51,9 @@
         None
     }
 
+    /// Modify the contents of a macro
+    fn modify_macro(&self, _name: &str, _tokens: &mut Vec<Token>) {}
+
     /// The integer kind an integer macro should have, given a name and the
     /// value of that macro, or `None` if you want the default to be chosen.
     fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
@@ -94,8 +94,8 @@
         None
     }
 
-    /// Allows to rename an item, replacing `_original_item_name`.
-    fn item_name(&self, _original_item_name: &str) -> Option<String> {
+    /// Allows to rename an item, replacing `_item_info.name`.
+    fn item_name(&self, _item_info: ItemInfo) -> Option<String> {
         None
     }
 
@@ -134,6 +134,14 @@
         vec![]
     }
 
+    /// Provide a list of custom attributes.
+    ///
+    /// If no additional attributes are wanted, this function should return an
+    /// empty `Vec`.
+    fn add_attributes(&self, _info: &AttributeInfo<'_>) -> Vec<String> {
+        vec![]
+    }
+
     /// Process a source code comment.
     fn process_comment(&self, _comment: &str) -> Option<String> {
         None
@@ -159,11 +167,94 @@
     fn wrap_as_variadic_fn(&self, _name: &str) -> Option<String> {
         None
     }
+
+    /// This will get called everytime an item (currently struct, union, and alias) is found with some information about it
+    fn new_item_found(
+        &self,
+        _id: DiscoveredItemId,
+        _item: DiscoveredItem,
+        _source_location: Option<&SourceLocation>,
+    ) {
+    }
+
+    // TODO add callback for ResolvedTypeRef
 }
 
+/// An identifier for a discovered item. Used to identify an aliased type (see [`DiscoveredItem::Alias`])
+#[derive(Ord, PartialOrd, PartialEq, Eq, Hash, Debug, Clone, Copy)]
+pub struct DiscoveredItemId(usize);
+
+impl DiscoveredItemId {
+    /// Constructor
+    pub fn new(value: usize) -> Self {
+        Self(value)
+    }
+}
+
+/// Struct passed to [`ParseCallbacks::new_item_found`] containing information about discovered
+/// items (struct, union, and alias)
+#[derive(Debug, Hash, Clone, Ord, PartialOrd, Eq, PartialEq)]
+pub enum DiscoveredItem {
+    /// Represents a struct with its original name in C and its generated binding name
+    Struct {
+        /// The original name (learnt from C) of the structure
+        /// Can be None if the union is anonymous.
+        original_name: Option<String>,
+
+        /// The name of the generated binding
+        final_name: String,
+    },
+
+    /// Represents a union with its original name in C and its generated binding name
+    Union {
+        /// The original name (learnt from C) of the structure.
+        /// Can be None if the union is anonymous.
+        original_name: Option<String>,
+
+        /// The name of the generated binding
+        final_name: String,
+    },
+
+    /// Represents an alias like a typedef
+    /// ```c
+    ///     typedef struct MyStruct {
+    ///         ...
+    ///     } StructAlias;
+    /// ```
+    /// Here, the name of the alias is `StructAlias` and it's an alias for `MyStruct`
+    Alias {
+        /// The name of the alias in C (`StructAlias`)
+        alias_name: String,
+
+        /// The identifier of the discovered type
+        alias_for: DiscoveredItemId,
+    },
+
+    /// Represents an enum.
+    Enum {
+        /// The final name of the generated binding
+        final_name: String,
+    },
+
+    /// A function or method.
+    Function {
+        /// The final name used.
+        final_name: String,
+    },
+
+    /// A method.
+    Method {
+        /// The final name used.
+        final_name: String,
+
+        /// Type to which this method belongs.
+        parent: DiscoveredItemId,
+    }, // modules, etc.
+}
+
 /// Relevant information about a type to which new derive attributes will be added using
 /// [`ParseCallbacks::add_derives`].
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[non_exhaustive]
 pub struct DeriveInfo<'a> {
     /// The name of the type.
@@ -172,7 +263,18 @@
     pub kind: TypeKind,
 }
 
+/// Relevant information about a type to which new attributes will be added using
+/// [`ParseCallbacks::add_attributes`].
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[non_exhaustive]
+pub struct AttributeInfo<'a> {
+    /// The name of the type.
+    pub name: &'a str,
+    /// The kind of the type.
+    pub kind: TypeKind,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 /// The kind of the current type.
 pub enum TypeKind {
     /// The type is a Rust `struct`.
@@ -184,6 +286,7 @@
 }
 
 /// A struct providing information about the item being passed to [`ParseCallbacks::generated_name_override`].
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[non_exhaustive]
 pub struct ItemInfo<'a> {
     /// The name of the item
@@ -192,9 +295,14 @@
     pub kind: ItemKind,
 }
 
-/// An enum indicating the kind of item for an ItemInfo.
+/// An enum indicating the kind of item for an `ItemInfo`.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[non_exhaustive]
 pub enum ItemKind {
+    /// A module
+    Module,
+    /// A type
+    Type,
     /// A Function
     Function,
     /// A Variable
@@ -203,11 +311,27 @@
 
 /// Relevant information about a field for which visibility can be determined using
 /// [`ParseCallbacks::field_visibility`].
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 #[non_exhaustive]
 pub struct FieldInfo<'a> {
     /// The name of the type.
     pub type_name: &'a str,
     /// The name of the field.
     pub field_name: &'a str,
+    /// The name of the type of the field.
+    pub field_type_name: Option<&'a str>,
+}
+
+/// Location in the source code. Roughly equivalent to the same type
+/// within `clang_sys`.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct SourceLocation {
+    /// Line number.
+    pub line: usize,
+    /// Column number within line.
+    pub col: usize,
+    /// Byte offset within file.
+    pub byte_offset: usize,
+    /// Filename, if known.
+    pub file_name: Option<String>,
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/clang.rs firefox-140.10.2/third_party/rust/bindgen/clang.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/clang.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/clang.rs	Mon May 11 04:49:32 2026
@@ -10,9 +10,11 @@
 
 use std::ffi::{CStr, CString};
 use std::fmt;
+use std::fs::OpenOptions;
 use std::hash::Hash;
 use std::hash::Hasher;
 use std::os::raw::{c_char, c_int, c_longlong, c_uint, c_ulong, c_ulonglong};
+use std::sync::OnceLock;
 use std::{mem, ptr, slice};
 
 /// Type representing a clang attribute.
@@ -214,10 +216,10 @@
             })
             .or_else(|| {
                 let canonical = self.canonical();
-                if canonical != *self {
-                    canonical.num_template_args()
-                } else {
+                if canonical == *self {
                     None
+                } else {
+                    canonical.num_template_args()
                 }
             })
     }
@@ -492,7 +494,7 @@
     where
         Visitor: FnMut(Cursor) -> CXChildVisitResult,
     {
-        let data = &mut visitor as *mut Visitor;
+        let data = ptr::addr_of_mut!(visitor);
         unsafe {
             clang_visitChildren(self.x, visit_children::<Visitor>, data.cast());
         }
@@ -786,7 +788,7 @@
                 let found_attr = &mut found_attrs[idx];
                 if !*found_attr {
                     // `attr.name` and` attr.token_kind` are checked against unexposed attributes only.
-                    if attr.kind.map_or(false, |k| k == kind) ||
+                    if attr.kind == Some(kind) ||
                         (kind == CXCursor_UnexposedAttr &&
                             cur.tokens().iter().any(|t| {
                                 t.kind == attr.token_kind &&
@@ -874,9 +876,9 @@
         unsafe { clang_getCXXAccessSpecifier(self.x) }
     }
 
-    /// Is the cursor's referrent publically accessible in C++?
+    /// Is the cursor's referent publicly accessible in C++?
     ///
-    /// Returns true if self.access_specifier() is `CX_CXXPublic` or
+    /// Returns true if `self.access_specifier()` is `CX_CXXPublic` or
     /// `CX_CXXInvalidAccessSpecifier`.
     pub(crate) fn public_accessible(&self) -> bool {
         let access = self.access_specifier();
@@ -943,7 +945,7 @@
     }
 
     /// Gets the tokens that correspond to that cursor.
-    pub(crate) fn tokens(&self) -> RawTokens {
+    pub(crate) fn tokens(&self) -> RawTokens<'_> {
         RawTokens::new(self)
     }
 
@@ -955,19 +957,22 @@
             .collect()
     }
 
-    /// Obtain the real path name of a cursor of InclusionDirective kind.
+    /// Obtain the real path name of a cursor of `InclusionDirective` kind.
     ///
     /// Returns None if the cursor does not include a file, otherwise the file's full name
     pub(crate) fn get_included_file_name(&self) -> Option<String> {
-        let file = unsafe { clang_sys::clang_getIncludedFile(self.x) };
+        let file = unsafe { clang_getIncludedFile(self.x) };
         if file.is_null() {
             None
         } else {
-            Some(unsafe {
-                cxstring_into_string(clang_sys::clang_getFileName(file))
-            })
+            Some(unsafe { cxstring_into_string(clang_getFileName(file)) })
         }
     }
+
+    /// Is this cursor's referent a namespace that is inline?
+    pub(crate) fn is_inline_namespace(&self) -> bool {
+        unsafe { clang_Cursor_isInlineNamespace(self.x) != 0 }
+    }
 }
 
 /// A struct that owns the tokenizer result from a given cursor.
@@ -1001,7 +1006,7 @@
     }
 
     /// Get an iterator over these tokens.
-    pub(crate) fn iter(&self) -> ClangTokenIterator {
+    pub(crate) fn iter(&self) -> ClangTokenIterator<'_> {
         ClangTokenIterator {
             tu: self.tu,
             raw: self.as_slice().iter(),
@@ -1009,7 +1014,7 @@
     }
 }
 
-impl<'a> Drop for RawTokens<'a> {
+impl Drop for RawTokens<'_> {
     fn drop(&mut self) {
         if !self.tokens.is_null() {
             unsafe {
@@ -1040,13 +1045,11 @@
 impl ClangToken {
     /// Get the token spelling, without being converted to utf-8.
     pub(crate) fn spelling(&self) -> &[u8] {
-        let c_str = unsafe {
-            CStr::from_ptr(clang_getCString(self.spelling) as *const _)
-        };
+        let c_str = unsafe { CStr::from_ptr(clang_getCString(self.spelling)) };
         c_str.to_bytes()
     }
 
-    /// Converts a ClangToken to a `cexpr` token if possible.
+    /// Converts a `ClangToken` to a `cexpr` token if possible.
     pub(crate) fn as_cexpr_token(&self) -> Option<cexpr::token::Token> {
         use cexpr::token;
 
@@ -1059,7 +1062,7 @@
             // expressions, so we strip them down here.
             CXToken_Comment => return None,
             _ => {
-                warn!("Found unexpected token kind: {:?}", self);
+                warn!("Found unexpected token kind: {self:?}");
                 return None;
             }
         };
@@ -1083,7 +1086,7 @@
     raw: slice::Iter<'a, CXToken>,
 }
 
-impl<'a> Iterator for ClangTokenIterator<'a> {
+impl Iterator for ClangTokenIterator<'_> {
     type Item = ClangToken;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -1093,9 +1096,9 @@
             let spelling = clang_getTokenSpelling(self.tu, *raw);
             let extent = clang_getTokenExtent(self.tu, *raw);
             Some(ClangToken {
-                kind,
-                extent,
                 spelling,
+                extent,
+                kind,
             })
         }
     }
@@ -1105,10 +1108,8 @@
 /// (including '_') and does not start with a digit.
 pub(crate) fn is_valid_identifier(name: &str) -> bool {
     let mut chars = name.chars();
-    let first_valid = chars
-        .next()
-        .map(|c| c.is_alphabetic() || c == '_')
-        .unwrap_or(false);
+    let first_valid =
+        chars.next().is_some_and(|c| c.is_alphabetic() || c == '_');
 
     first_valid && chars.all(|c| c.is_alphanumeric() || c == '_')
 }
@@ -1121,7 +1122,7 @@
 where
     Visitor: FnMut(Cursor) -> CXChildVisitResult,
 {
-    let func: &mut Visitor = unsafe { &mut *(data as *mut Visitor) };
+    let func: &mut Visitor = unsafe { &mut *data.cast::<Visitor>() };
     let child = Cursor { x: cur };
 
     (*func)(child)
@@ -1137,7 +1138,7 @@
 
 impl Hash for Cursor {
     fn hash<H: Hasher>(&self, state: &mut H) {
-        unsafe { clang_hashCursor(self.x) }.hash(state)
+        unsafe { clang_hashCursor(self.x) }.hash(state);
     }
 }
 
@@ -1210,11 +1211,11 @@
 
     /// Get a cursor pointing to this type's declaration.
     pub(crate) fn declaration(&self) -> Cursor {
-        unsafe {
-            Cursor {
-                x: clang_getTypeDeclaration(self.x),
-            }
-        }
+        let decl = Cursor {
+            x: unsafe { clang_getTypeDeclaration(self.x) },
+        };
+        // Prior to clang 22, the declaration pointed to the definition.
+        decl.definition().unwrap_or(decl)
     }
 
     /// Get the canonical declaration of this type, if it is available.
@@ -1440,10 +1441,10 @@
     /// elements.
     pub(crate) fn num_elements(&self) -> Option<usize> {
         let num_elements_returned = unsafe { clang_getNumElements(self.x) };
-        if num_elements_returned != -1 {
-            Some(num_elements_returned as usize)
-        } else {
+        if num_elements_returned == -1 {
             None
+        } else {
+            Some(num_elements_returned as usize)
         }
     }
 
@@ -1491,6 +1492,15 @@
         }
     }
 
+    /// For atomic types, get the underlying type.
+    pub(crate) fn atomic_value_type(&self) -> Type {
+        unsafe {
+            Type {
+                x: clang_Type_getValueType(self.x),
+            }
+        }
+    }
+
     /// Is this a valid type?
     pub(crate) fn is_valid(&self) -> bool {
         self.kind() != CXType_Invalid
@@ -1506,7 +1516,7 @@
         // Yep, the spelling of this containing type-parameter is extremely
         // nasty... But can happen in <type_traits>. Unfortunately I couldn't
         // reduce it enough :(
-        self.template_args().map_or(false, |args| args.len() > 0) &&
+        self.template_args().is_some_and(|args| args.len() > 0) &&
             !matches!(
                 self.declaration().kind(),
                 CXCursor_ClassTemplatePartialSpecialization |
@@ -1527,13 +1537,13 @@
     pub(crate) fn is_associated_type(&self) -> bool {
         // This is terrible :(
         fn hacky_parse_associated_type<S: AsRef<str>>(spelling: S) -> bool {
-            lazy_static! {
-                static ref ASSOC_TYPE_RE: regex::Regex = regex::Regex::new(
-                    r"typename type\-parameter\-\d+\-\d+::.+"
-                )
-                .unwrap();
-            }
-            ASSOC_TYPE_RE.is_match(spelling.as_ref())
+            static ASSOC_TYPE_RE: OnceLock<regex::Regex> = OnceLock::new();
+            ASSOC_TYPE_RE
+                .get_or_init(|| {
+                    regex::Regex::new(r"typename type\-parameter\-\d+\-\d+::.+")
+                        .unwrap()
+                })
+                .is_match(spelling.as_ref())
         }
 
         self.kind() == CXType_Unexposed &&
@@ -1620,7 +1630,7 @@
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let (file, line, col, _) = self.location();
         if let Some(name) = file.name() {
-            write!(f, "{}:{}:{}", name, line, col)
+            write!(f, "{name}:{line}:{col}")
         } else {
             "builtin definitions".fmt(f)
         }
@@ -1629,7 +1639,7 @@
 
 impl fmt::Debug for SourceLocation {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", self)
+        write!(f, "{self}")
     }
 }
 
@@ -1749,9 +1759,9 @@
 
 fn cxstring_to_string_leaky(s: CXString) -> String {
     if s.data.is_null() {
-        return "".to_owned();
+        return String::new();
     }
-    let c_str = unsafe { CStr::from_ptr(clang_getCString(s) as *const _) };
+    let c_str = unsafe { CStr::from_ptr(clang_getCString(s)) };
     c_str.to_string_lossy().into_owned()
 }
 
@@ -1777,7 +1787,7 @@
     pub(crate) fn new(pch: bool, diag: bool) -> Index {
         unsafe {
             Index {
-                x: clang_createIndex(pch as c_int, diag as c_int),
+                x: clang_createIndex(c_int::from(pch), c_int::from(diag)),
             }
         }
     }
@@ -1868,6 +1878,25 @@
         }
     }
 
+    /// Save a translation unit to the given file.
+    pub(crate) fn save(&mut self, file: &str) -> Result<(), CXSaveError> {
+        let Ok(file) = CString::new(file) else {
+            return Err(CXSaveError_Unknown);
+        };
+        let ret = unsafe {
+            clang_saveTranslationUnit(
+                self.x,
+                file.as_ptr(),
+                clang_defaultSaveOptions(self.x),
+            )
+        };
+        if ret != 0 {
+            Err(ret)
+        } else {
+            Ok(())
+        }
+    }
+
     /// Is this the null translation unit?
     pub(crate) fn is_null(&self) -> bool {
         self.x.is_null()
@@ -1882,6 +1911,87 @@
     }
 }
 
+/// Translation unit used for macro fallback parsing
+pub(crate) struct FallbackTranslationUnit {
+    file_path: String,
+    pch_path: String,
+    idx: Box<Index>,
+    tu: TranslationUnit,
+}
+
+impl fmt::Debug for FallbackTranslationUnit {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "FallbackTranslationUnit {{ }}")
+    }
+}
+
+impl FallbackTranslationUnit {
+    /// Create a new fallback translation unit
+    pub(crate) fn new(
+        file: String,
+        pch_path: String,
+        c_args: &[Box<str>],
+    ) -> Option<Self> {
+        // Create empty file
+        OpenOptions::new()
+            .write(true)
+            .create(true)
+            .truncate(true)
+            .open(&file)
+            .ok()?;
+
+        let f_index = Box::new(Index::new(true, false));
+        let f_translation_unit = TranslationUnit::parse(
+            &f_index,
+            &file,
+            c_args,
+            &[],
+            CXTranslationUnit_None,
+        )?;
+        Some(FallbackTranslationUnit {
+            file_path: file,
+            pch_path,
+            tu: f_translation_unit,
+            idx: f_index,
+        })
+    }
+
+    /// Get reference to underlying translation unit.
+    pub(crate) fn translation_unit(&self) -> &TranslationUnit {
+        &self.tu
+    }
+
+    /// Reparse a translation unit.
+    pub(crate) fn reparse(
+        &mut self,
+        unsaved_contents: &str,
+    ) -> Result<(), CXErrorCode> {
+        let unsaved = &[UnsavedFile::new(&self.file_path, unsaved_contents)];
+        let mut c_unsaved: Vec<CXUnsavedFile> =
+            unsaved.iter().map(|f| f.x).collect();
+        let ret = unsafe {
+            clang_reparseTranslationUnit(
+                self.tu.x,
+                unsaved.len() as c_uint,
+                c_unsaved.as_mut_ptr(),
+                clang_defaultReparseOptions(self.tu.x),
+            )
+        };
+        if ret != 0 {
+            Err(ret)
+        } else {
+            Ok(())
+        }
+    }
+}
+
+impl Drop for FallbackTranslationUnit {
+    fn drop(&mut self) {
+        let _ = std::fs::remove_file(&self.file_path);
+        let _ = std::fs::remove_file(&self.pch_path);
+    }
+}
+
 /// A diagnostic message generated while parsing a translation unit.
 pub(crate) struct Diagnostic {
     x: CXDiagnostic,
@@ -1968,26 +2078,25 @@
         let prefix = prefix.as_ref();
         print_indent(
             depth,
-            format!(" {}kind = {}", prefix, kind_to_str(c.kind())),
+            format!(" {prefix}kind = {}", kind_to_str(c.kind())),
         );
         print_indent(
             depth,
-            format!(" {}spelling = \"{}\"", prefix, c.spelling()),
+            format!(" {prefix}spelling = \"{}\"", c.spelling()),
         );
-        print_indent(depth, format!(" {}location = {}", prefix, c.location()));
+        print_indent(depth, format!(" {prefix}location = {}", c.location()));
         print_indent(
             depth,
-            format!(" {}is-definition? {}", prefix, c.is_definition()),
+            format!(" {prefix}is-definition? {}", c.is_definition()),
         );
         print_indent(
             depth,
-            format!(" {}is-declaration? {}", prefix, c.is_declaration()),
+            format!(" {prefix}is-declaration? {}", c.is_declaration()),
         );
         print_indent(
             depth,
             format!(
-                " {}is-inlined-function? {}",
-                prefix,
+                " {prefix}is-inlined-function? {}",
                 c.is_inlined_function()
             ),
         );
@@ -1996,23 +2105,19 @@
         if templ_kind != CXCursor_NoDeclFound {
             print_indent(
                 depth,
-                format!(
-                    " {}template-kind = {}",
-                    prefix,
-                    kind_to_str(templ_kind)
-                ),
+                format!(" {prefix}template-kind = {}", kind_to_str(templ_kind)),
             );
         }
         if let Some(usr) = c.usr() {
-            print_indent(depth, format!(" {}usr = \"{}\"", prefix, usr));
+            print_indent(depth, format!(" {prefix}usr = \"{usr}\""));
         }
         if let Ok(num) = c.num_args() {
-            print_indent(depth, format!(" {}number-of-args = {}", prefix, num));
+            print_indent(depth, format!(" {prefix}number-of-args = {num}"));
         }
         if let Some(num) = c.num_template_args() {
             print_indent(
                 depth,
-                format!(" {}number-of-template-args = {}", prefix, num),
+                format!(" {prefix}number-of-template-args = {num}"),
             );
         }
 
@@ -2021,28 +2126,28 @@
                 Some(w) => w.to_string(),
                 None => "<unevaluable>".to_string(),
             };
-            print_indent(depth, format!(" {}bit-width = {}", prefix, width));
+            print_indent(depth, format!(" {prefix}bit-width = {width}"));
         }
 
         if let Some(ty) = c.enum_type() {
             print_indent(
                 depth,
-                format!(" {}enum-type = {}", prefix, type_to_str(ty.kind())),
+                format!(" {prefix}enum-type = {}", type_to_str(ty.kind())),
             );
         }
         if let Some(val) = c.enum_val_signed() {
-            print_indent(depth, format!(" {}enum-val = {}", prefix, val));
+            print_indent(depth, format!(" {prefix}enum-val = {val}"));
         }
         if let Some(ty) = c.typedef_type() {
             print_indent(
                 depth,
-                format!(" {}typedef-type = {}", prefix, type_to_str(ty.kind())),
+                format!(" {prefix}typedef-type = {}", type_to_str(ty.kind())),
             );
         }
         if let Some(ty) = c.ret_type() {
             print_indent(
                 depth,
-                format!(" {}ret-type = {}", prefix, type_to_str(ty.kind())),
+                format!(" {prefix}ret-type = {}", type_to_str(ty.kind())),
             );
         }
 
@@ -2092,16 +2197,16 @@
         let prefix = prefix.as_ref();
 
         let kind = ty.kind();
-        print_indent(depth, format!(" {}kind = {}", prefix, type_to_str(kind)));
+        print_indent(depth, format!(" {prefix}kind = {}", type_to_str(kind)));
         if kind == CXType_Invalid {
             return;
         }
 
-        print_indent(depth, format!(" {}cconv = {}", prefix, ty.call_conv()));
+        print_indent(depth, format!(" {prefix}cconv = {}", ty.call_conv()));
 
         print_indent(
             depth,
-            format!(" {}spelling = \"{}\"", prefix, ty.spelling()),
+            format!(" {prefix}spelling = \"{}\"", ty.spelling()),
         );
         let num_template_args =
             unsafe { clang_Type_getNumTemplateArguments(ty.x) };
@@ -2109,20 +2214,16 @@
             print_indent(
                 depth,
                 format!(
-                    " {}number-of-template-args = {}",
-                    prefix, num_template_args
+                    " {prefix}number-of-template-args = {num_template_args}"
                 ),
             );
         }
         if let Some(num) = ty.num_elements() {
-            print_indent(
-                depth,
-                format!(" {}number-of-elements = {}", prefix, num),
-            );
+            print_indent(depth, format!(" {prefix}number-of-elements = {num}"));
         }
         print_indent(
             depth,
-            format!(" {}is-variadic? {}", prefix, ty.is_variadic()),
+            format!(" {prefix}is-variadic? {}", ty.is_variadic()),
         );
 
         let canonical = ty.canonical_type();
@@ -2250,7 +2351,7 @@
 
         if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 {
             let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) };
-            if value > i64::max_value() as c_ulonglong {
+            if value > i64::MAX as c_ulonglong {
                 return None;
             }
 
@@ -2258,10 +2359,10 @@
         }
 
         let value = unsafe { clang_EvalResult_getAsLongLong(self.x) };
-        if value > i64::max_value() as c_longlong {
+        if value > i64::MAX as c_longlong {
             return None;
         }
-        if value < i64::min_value() as c_longlong {
+        if value < i64::MIN as c_longlong {
             return None;
         }
         #[allow(clippy::unnecessary_cast)]
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/bitfield_unit.rs firefox-140.10.2/third_party/rust/bindgen/codegen/bitfield_unit.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/bitfield_unit.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/bitfield_unit.rs	Mon May 11 04:49:32 2026
@@ -16,12 +16,7 @@
     Storage: AsRef<[u8]> + AsMut<[u8]>,
 {
     #[inline]
-    pub fn get_bit(&self, index: usize) -> bool {
-        debug_assert!(index / 8 < self.storage.as_ref().len());
-
-        let byte_index = index / 8;
-        let byte = self.storage.as_ref()[byte_index];
-
+    fn extract_bit(byte: u8, index: usize) -> bool {
         let bit_index = if cfg!(target_endian = "big") {
             7 - (index % 8)
         } else {
@@ -34,12 +29,30 @@
     }
 
     #[inline]
-    pub fn set_bit(&mut self, index: usize, val: bool) {
+    pub fn get_bit(&self, index: usize) -> bool {
         debug_assert!(index / 8 < self.storage.as_ref().len());
 
         let byte_index = index / 8;
-        let byte = &mut self.storage.as_mut()[byte_index];
+        let byte = self.storage.as_ref()[byte_index];
 
+        Self::extract_bit(byte, index)
+    }
+
+    #[inline]
+    pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool {
+        debug_assert!(index / 8 < core::mem::size_of::<Storage>());
+
+        let byte_index = index / 8;
+        let byte = unsafe {
+            *(core::ptr::addr_of!((*this).storage) as *const u8)
+                .offset(byte_index as isize)
+        };
+
+        Self::extract_bit(byte, index)
+    }
+
+    #[inline]
+    fn change_bit(byte: u8, index: usize, val: bool) -> u8 {
         let bit_index = if cfg!(target_endian = "big") {
             7 - (index % 8)
         } else {
@@ -48,13 +61,36 @@
 
         let mask = 1 << bit_index;
         if val {
-            *byte |= mask;
+            byte | mask
         } else {
-            *byte &= !mask;
+            byte & !mask
         }
     }
 
     #[inline]
+    pub fn set_bit(&mut self, index: usize, val: bool) {
+        debug_assert!(index / 8 < self.storage.as_ref().len());
+
+        let byte_index = index / 8;
+        let byte = &mut self.storage.as_mut()[byte_index];
+
+        *byte = Self::change_bit(*byte, index, val);
+    }
+
+    #[inline]
+    pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) {
+        debug_assert!(index / 8 < core::mem::size_of::<Storage>());
+
+        let byte_index = index / 8;
+        let byte = unsafe {
+            (core::ptr::addr_of_mut!((*this).storage) as *mut u8)
+                .offset(byte_index as isize)
+        };
+
+        unsafe { *byte = Self::change_bit(*byte, index, val) };
+    }
+
+    #[inline]
     pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
         debug_assert!(bit_width <= 64);
         debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
@@ -80,6 +116,35 @@
     }
 
     #[inline]
+    pub unsafe fn raw_get(
+        this: *const Self,
+        bit_offset: usize,
+        bit_width: u8,
+    ) -> u64 {
+        debug_assert!(bit_width <= 64);
+        debug_assert!(bit_offset / 8 < core::mem::size_of::<Storage>());
+        debug_assert!(
+            (bit_offset + (bit_width as usize)) / 8 <=
+                core::mem::size_of::<Storage>()
+        );
+
+        let mut val = 0;
+
+        for i in 0..(bit_width as usize) {
+            if unsafe { Self::raw_get_bit(this, i + bit_offset) } {
+                let index = if cfg!(target_endian = "big") {
+                    bit_width as usize - 1 - i
+                } else {
+                    i
+                };
+                val |= 1 << index;
+            }
+        }
+
+        val
+    }
+
+    #[inline]
     pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
         debug_assert!(bit_width <= 64);
         debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
@@ -97,6 +162,34 @@
                 i
             };
             self.set_bit(index + bit_offset, val_bit_is_set);
+        }
+    }
+
+    #[inline]
+    pub unsafe fn raw_set(
+        this: *mut Self,
+        bit_offset: usize,
+        bit_width: u8,
+        val: u64,
+    ) {
+        debug_assert!(bit_width <= 64);
+        debug_assert!(bit_offset / 8 < core::mem::size_of::<Storage>());
+        debug_assert!(
+            (bit_offset + (bit_width as usize)) / 8 <=
+                core::mem::size_of::<Storage>()
+        );
+
+        for i in 0..(bit_width as usize) {
+            let mask = 1 << i;
+            let val_bit_is_set = val & mask == mask;
+            let index = if cfg!(target_endian = "big") {
+                bit_width as usize - 1 - i
+            } else {
+                i
+            };
+            unsafe {
+                Self::raw_set_bit(this, index + bit_offset, val_bit_is_set)
+            };
         }
     }
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/bitfield_unit_tests.rs firefox-140.10.2/third_party/rust/bindgen/codegen/bitfield_unit_tests.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/bitfield_unit_tests.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/bitfield_unit_tests.rs	Mon May 11 04:49:32 2026
@@ -33,7 +33,7 @@
     }
 
     println!();
-    println!("bits = {:?}", bits);
+    println!("bits = {bits:?}");
     assert_eq!(
         bits,
         &[
@@ -88,8 +88,8 @@
                 let actual = unit.get($start, $len);
 
                 println!();
-                println!("expected = {:064b}", expected);
-                println!("actual   = {:064b}", actual);
+                println!("expected = {expected:064b}");
+                println!("actual   = {actual:064b}");
 
                 assert_eq!(expected, actual);
             })*
@@ -191,7 +191,7 @@
                 println!();
                 println!("set({}, {}, {:032b}", $start, $len, $val);
                 println!("expected = {:064b}", $expected);
-                println!("actual   = {:064b}", actual);
+                println!("actual   = {actual:064b}");
 
                 assert_eq!($expected, actual);
             )*
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/dyngen.rs firefox-140.10.2/third_party/rust/bindgen/codegen/dyngen.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/dyngen.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/dyngen.rs	Mon May 11 04:49:32 2026
@@ -1,7 +1,7 @@
 use crate::codegen;
 use crate::ir::context::BindgenContext;
 use crate::ir::function::ClangAbi;
-use proc_macro2::Ident;
+use proc_macro2::{Ident, TokenStream};
 
 /// Used to build the output tokens for dynamic bindings.
 #[derive(Default)]
@@ -14,7 +14,7 @@
     ///    ...
     /// }
     /// ```
-    struct_members: Vec<proc_macro2::TokenStream>,
+    struct_members: Vec<TokenStream>,
 
     /// Tracks the tokens that will appear inside the library struct's implementation, e.g.:
     ///
@@ -26,7 +26,7 @@
     ///     }
     /// }
     /// ```
-    struct_implementation: Vec<proc_macro2::TokenStream>,
+    struct_implementation: Vec<TokenStream>,
 
     /// Tracks the initialization of the fields inside the `::new` constructor of the library
     /// struct, e.g.:
@@ -45,7 +45,7 @@
     ///     ...
     /// }
     /// ```
-    constructor_inits: Vec<proc_macro2::TokenStream>,
+    constructor_inits: Vec<TokenStream>,
 
     /// Tracks the information that is passed to the library struct at the end of the `::new`
     /// constructor, e.g.:
@@ -65,7 +65,7 @@
     ///     }
     /// }
     /// ```
-    init_fields: Vec<proc_macro2::TokenStream>,
+    init_fields: Vec<TokenStream>,
 }
 
 impl DynamicItems {
@@ -75,14 +75,20 @@
 
     pub(crate) fn get_tokens(
         &self,
-        lib_ident: Ident,
+        lib_ident: &Ident,
         ctx: &BindgenContext,
-    ) -> proc_macro2::TokenStream {
+    ) -> TokenStream {
         let struct_members = &self.struct_members;
         let constructor_inits = &self.constructor_inits;
         let init_fields = &self.init_fields;
         let struct_implementation = &self.struct_implementation;
 
+        let library_new = if ctx.options().wrap_unsafe_ops {
+            quote!(unsafe { ::libloading::Library::new(path) })
+        } else {
+            quote!(::libloading::Library::new(path))
+        };
+
         let from_library = if ctx.options().wrap_unsafe_ops {
             quote!(unsafe { Self::from_library(library) })
         } else {
@@ -90,8 +96,6 @@
         };
 
         quote! {
-            extern crate libloading;
-
             pub struct #lib_ident {
                 __library: ::libloading::Library,
                 #(#struct_members)*
@@ -102,7 +106,7 @@
                     path: P
                 ) -> Result<Self, ::libloading::Error>
                 where P: AsRef<::std::ffi::OsStr> {
-                    let library = ::libloading::Library::new(path)?;
+                    let library = #library_new?;
                     #from_library
                 }
 
@@ -124,17 +128,18 @@
     }
 
     #[allow(clippy::too_many_arguments)]
-    pub(crate) fn push(
+    pub(crate) fn push_func(
         &mut self,
-        ident: Ident,
+        ident: &Ident,
+        symbol: &str,
         abi: ClangAbi,
         is_variadic: bool,
         is_required: bool,
-        args: Vec<proc_macro2::TokenStream>,
-        args_identifiers: Vec<proc_macro2::TokenStream>,
-        ret: proc_macro2::TokenStream,
-        ret_ty: proc_macro2::TokenStream,
-        attributes: Vec<proc_macro2::TokenStream>,
+        args: &[TokenStream],
+        args_identifiers: &[TokenStream],
+        ret: &TokenStream,
+        ret_ty: &TokenStream,
+        attributes: &[TokenStream],
         ctx: &BindgenContext,
     ) {
         if !is_variadic {
@@ -177,11 +182,12 @@
         }
 
         // N.B: Unwrap the signature upon construction if it is required to be resolved.
-        let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
+        let symbol_cstr =
+            codegen::helpers::ast_ty::cstr_expr(symbol.to_string());
         let library_get = if ctx.options().wrap_unsafe_ops {
-            quote!(unsafe { __library.get(#ident_str) })
+            quote!(unsafe { __library.get(#symbol_cstr) })
         } else {
-            quote!(__library.get(#ident_str))
+            quote!(__library.get(#symbol_cstr))
         };
 
         self.constructor_inits.push(if is_required {
@@ -193,6 +199,57 @@
                 let #ident = #library_get.map(|sym| *sym);
             }
         });
+
+        self.init_fields.push(quote! {
+            #ident
+        });
+    }
+
+    pub fn push_var(
+        &mut self,
+        ident: &Ident,
+        symbol: &str,
+        ty: &TokenStream,
+        is_required: bool,
+        wrap_unsafe_ops: bool,
+    ) {
+        let member = if is_required {
+            quote! { *mut #ty }
+        } else {
+            quote! { Result<*mut #ty, ::libloading::Error> }
+        };
+
+        self.struct_members.push(quote! {
+            pub #ident: #member,
+        });
+
+        let deref = if is_required {
+            quote! { self.#ident }
+        } else {
+            quote! { *self.#ident.as_ref().expect("Expected variable, got error.") }
+        };
+        self.struct_implementation.push(quote! {
+            pub unsafe fn #ident (&self) -> *mut #ty {
+                #deref
+            }
+        });
+
+        let symbol_cstr =
+            codegen::helpers::ast_ty::cstr_expr(symbol.to_string());
+
+        let library_get = if wrap_unsafe_ops {
+            quote!(unsafe { __library.get::<*mut #ty>(#symbol_cstr) })
+        } else {
+            quote!(__library.get::<*mut #ty>(#symbol_cstr))
+        };
+
+        let qmark = if is_required { quote!(?) } else { quote!() };
+
+        let var_get = quote! {
+            let #ident = #library_get.map(|sym| *sym)#qmark;
+        };
+
+        self.constructor_inits.push(var_get);
 
         self.init_fields.push(quote! {
             #ident
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/error.rs firefox-140.10.2/third_party/rust/bindgen/codegen/error.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/error.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/error.rs	Mon May 11 04:49:32 2026
@@ -36,12 +36,11 @@
             Error::UnsupportedAbi(abi) => {
                  write!(
                     f,
-                    "{} ABI is not supported by the configured Rust target.",
-                    abi
+                    "{abi} ABI is not supported by the configured Rust target."
                 )
             }
             Error::InvalidPointerSize { ty_name, ty_size, ptr_size } => {
-                write!(f, "The {} pointer type has size {} but the current target's pointer size is {}.", ty_name, ty_size, ptr_size)
+                write!(f, "The {ty_name} pointer type has size {ty_size} but the current target's pointer size is {ptr_size}.")
             }
         }
     }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/helpers.rs firefox-140.10.2/third_party/rust/bindgen/codegen/helpers.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/helpers.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/helpers.rs	Mon May 11 04:49:32 2026
@@ -1,7 +1,10 @@
 //! Helpers for code generation that don't need macro expansion.
 
+use proc_macro2::{Ident, Span};
+
 use crate::ir::context::BindgenContext;
 use crate::ir::layout::Layout;
+use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
 
 pub(crate) mod attributes {
     use proc_macro2::{Ident, Span, TokenStream};
@@ -17,7 +20,6 @@
     pub(crate) fn repr_list(which_ones: &[&str]) -> TokenStream {
         let which_ones = which_ones
             .iter()
-            .cloned()
             .map(|one| TokenStream::from_str(one).expect("repr to be valid"));
         quote! {
             #[repr( #( #which_ones ),* )]
@@ -27,7 +29,6 @@
     pub(crate) fn derives(which_ones: &[&str]) -> TokenStream {
         let which_ones = which_ones
             .iter()
-            .cloned()
             .map(|one| TokenStream::from_str(one).expect("derive to be valid"));
         quote! {
             #[derive( #( #which_ones ),* )]
@@ -52,7 +53,7 @@
         }
     }
 
-    pub(crate) fn doc(comment: String) -> TokenStream {
+    pub(crate) fn doc(comment: &str) -> TokenStream {
         if comment.is_empty() {
             quote!()
         } else {
@@ -66,7 +67,7 @@
         let name: Cow<'_, str> = if MANGLE {
             name.into()
         } else {
-            format!("\u{1}{}", name).into()
+            format!("\u{1}{name}").into()
         };
 
         quote! {
@@ -75,44 +76,58 @@
     }
 }
 
-/// Generates a proper type for a field or type with a given `Layout`, that is,
-/// a type with the correct size and alignment restrictions.
-pub(crate) fn blob(ctx: &BindgenContext, layout: Layout) -> syn::Type {
-    let opaque = layout.opaque();
+/// The `ffi_safe` argument should be true if this is a type that the user might
+/// reasonably use, e.g. not struct padding, where the `__BindgenOpaqueArray` is
+/// just noise.
+/// TODO: Should this be `MaybeUninit`, since padding bytes are effectively
+/// uninitialized?
+pub(crate) fn blob(
+    ctx: &BindgenContext,
+    layout: Layout,
+    ffi_safe: bool,
+) -> syn::Type {
+    let align = layout.align.max(1);
+    // For alignments <= 4, it holds that the integer type of the same size aligns to that same
+    // size. For bigger alignments that's not guaranteed, e.g. on x86 u64 is aligned to 4 bytes.
+    if align <= 4 {
+        let ty = Layout::known_type_for_size(align).unwrap();
+        let len = layout.size / align;
+        return if len == 1 {
+            ty
+        } else if !ffi_safe && len <= RUST_DERIVE_IN_ARRAY_LIMIT {
+            syn::parse_quote! { [#ty; #len] }
+        } else {
+            ctx.generated_opaque_array(1);
+            if ctx.options().enable_cxx_namespaces {
+                syn::parse_quote! { root::__BindgenOpaqueArray<[#ty; #len]> }
+            } else {
+                syn::parse_quote! { __BindgenOpaqueArray<[#ty; #len]> }
+            }
+        };
+    }
 
-    // FIXME(emilio, #412): We fall back to byte alignment, but there are
-    // some things that legitimately are more than 8-byte aligned.
-    //
-    // Eventually we should be able to `unwrap` here, but...
-    let ty = match opaque.known_rust_type_for_array(ctx) {
-        Some(ty) => ty,
-        None => {
-            warn!("Found unknown alignment on code generation!");
-            syn::parse_quote! { u8 }
-        }
-    };
-
-    let data_len = opaque.array_size(ctx).unwrap_or(layout.size);
-
-    if data_len == 1 {
-        ty
+    ctx.generated_opaque_array(align);
+    let ident = format_ident!("__BindgenOpaqueArray{}", align);
+    let size = layout.size;
+    if ctx.options().enable_cxx_namespaces {
+        syn::parse_quote! { root::#ident<[u8; #size]> }
     } else {
-        syn::parse_quote! { [ #ty ; #data_len ] }
+        syn::parse_quote! { #ident<[u8; #size]> }
     }
 }
 
 /// Integer type of the same size as the given `Layout`.
-pub(crate) fn integer_type(
-    ctx: &BindgenContext,
-    layout: Layout,
-) -> Option<syn::Type> {
-    Layout::known_type_for_size(ctx, layout.size)
+pub(crate) fn integer_type(layout: Layout) -> Option<syn::Type> {
+    Layout::known_type_for_size(layout.size)
 }
 
+pub(crate) const BITFIELD_UNIT: &str = "__BindgenBitfieldUnit";
+
 /// Generates a bitfield allocation unit type for a type with the given `Layout`.
 pub(crate) fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> syn::Type {
     let size = layout.size;
-    let ty = syn::parse_quote! { __BindgenBitfieldUnit<[u8; #size]> };
+    let bitfield_unit_name = Ident::new(BITFIELD_UNIT, Span::call_site());
+    let ty = syn::parse_quote! { #bitfield_unit_name<[u8; #size]> };
 
     if ctx.options().enable_cxx_namespaces {
         return syn::parse_quote! { root::#ty };
@@ -126,7 +141,7 @@
     use crate::ir::function::FunctionSig;
     use crate::ir::layout::Layout;
     use crate::ir::ty::{FloatKind, IntKind};
-    use proc_macro2::{self, TokenStream};
+    use proc_macro2::TokenStream;
     use std::str::FromStr;
 
     pub(crate) fn c_void(ctx: &BindgenContext) -> syn::Type {
@@ -137,9 +152,7 @@
                 syn::parse_quote! { #prefix::c_void }
             }
             None => {
-                if ctx.options().use_core &&
-                    ctx.options().rust_features.core_ffi_c_void
-                {
+                if ctx.options().use_core {
                     syn::parse_quote! { ::core::ffi::c_void }
                 } else {
                     syn::parse_quote! { ::std::os::raw::c_void }
@@ -175,6 +188,12 @@
         match ik {
             IntKind::Bool => syn::parse_quote! { bool },
             IntKind::Char { .. } => raw_type(ctx, "c_char"),
+            // The following is used only when an unusual command-line
+            // argument is used. bindgen_cchar16_t is not a real type;
+            // but this allows downstream postprocessors to distinguish
+            // this case and do something special for C++ bindings
+            // containing the C++ type char16_t.
+            IntKind::Char16 => syn::parse_quote! { bindgen_cchar16_t },
             IntKind::SChar => raw_type(ctx, "c_schar"),
             IntKind::UChar => raw_type(ctx, "c_uchar"),
             IntKind::Short => raw_type(ctx, "c_short"),
@@ -188,7 +207,7 @@
             IntKind::WChar => {
                 let layout =
                     layout.expect("Couldn't compute wchar_t's layout?");
-                Layout::known_type_for_size(ctx, layout.size)
+                Layout::known_type_for_size(layout.size)
                     .expect("Non-representable wchar_t?")
             }
 
@@ -204,7 +223,7 @@
                 syn::parse_str(name).expect("Invalid integer type.")
             }
             IntKind::U128 => {
-                if ctx.options().rust_features.i128_and_u128 {
+                if true {
                     syn::parse_quote! { u128 }
                 } else {
                     // Best effort thing, but wrong alignment
@@ -213,7 +232,7 @@
                 }
             }
             IntKind::I128 => {
-                if ctx.options().rust_features.i128_and_u128 {
+                if true {
                     syn::parse_quote! { i128 }
                 } else {
                     syn::parse_quote! { [u64; 2] }
@@ -246,28 +265,25 @@
             (FloatKind::Float, false) => raw_type(ctx, "c_float"),
             (FloatKind::Double, false) => raw_type(ctx, "c_double"),
             (FloatKind::LongDouble, _) => {
-                match layout {
-                    Some(layout) => {
-                        match layout.size {
-                            4 => syn::parse_quote! { f32 },
-                            8 => syn::parse_quote! { f64 },
-                            // TODO(emilio): If rust ever gains f128 we should
-                            // use it here and below.
-                            _ => super::integer_type(ctx, layout)
-                                .unwrap_or(syn::parse_quote! { f64 }),
-                        }
+                if let Some(layout) = layout {
+                    match layout.size {
+                        4 => syn::parse_quote! { f32 },
+                        8 => syn::parse_quote! { f64 },
+                        // TODO(emilio): If rust ever gains f128 we should
+                        // use it here and below.
+                        _ => super::integer_type(layout)
+                            .unwrap_or(syn::parse_quote! { f64 }),
                     }
-                    None => {
-                        debug_assert!(
-                            false,
-                            "How didn't we know the layout for a primitive type?"
-                        );
-                        syn::parse_quote! { f64 }
-                    }
+                } else {
+                    debug_assert!(
+                        false,
+                        "How didn't we know the layout for a primitive type?"
+                    );
+                    syn::parse_quote! { f64 }
                 }
             }
             (FloatKind::Float128, _) => {
-                if ctx.options().rust_features.i128_and_u128 {
+                if true {
                     syn::parse_quote! { u128 }
                 } else {
                     syn::parse_quote! { [u64; 2] }
@@ -296,37 +312,27 @@
         }
     }
 
-    pub(crate) fn float_expr(
-        ctx: &BindgenContext,
-        f: f64,
-    ) -> Result<TokenStream, ()> {
+    pub(crate) fn float_expr(f: f64) -> Result<TokenStream, ()> {
         if f.is_finite() {
             let val = proc_macro2::Literal::f64_unsuffixed(f);
 
             return Ok(quote!(#val));
         }
 
-        let prefix = ctx.trait_prefix();
-
         if f.is_nan() {
-            return Ok(quote! {
-                ::#prefix::f64::NAN
-            });
+            return Ok(quote! { f64::NAN });
         }
 
         if f.is_infinite() {
-            return Ok(if f.is_sign_positive() {
-                quote! {
-                    ::#prefix::f64::INFINITY
-                }
+            let tokens = if f.is_sign_positive() {
+                quote! { f64::INFINITY }
             } else {
-                quote! {
-                    ::#prefix::f64::NEG_INFINITY
-                }
-            });
+                quote! { f64::NEG_INFINITY }
+            };
+            return Ok(tokens);
         }
 
-        warn!("Unknown non-finite float number: {:?}", f);
+        warn!("Unknown non-finite float number: {f:?}");
         Err(())
     }
 
@@ -338,17 +344,14 @@
         signature
             .argument_types()
             .iter()
-            .map(|&(ref name, _ty)| match *name {
-                Some(ref name) => {
-                    let name = ctx.rust_ident(name);
-                    quote! { #name }
-                }
-                None => {
+            .map(|&(ref name, _ty)| {
+                let name = if let Some(ref name) = *name {
+                    ctx.rust_ident(name)
+                } else {
                     unnamed_arguments += 1;
-                    let name =
-                        ctx.rust_ident(format!("arg{}", unnamed_arguments));
-                    quote! { #name }
-                }
+                    ctx.rust_ident(format!("arg{unnamed_arguments}"))
+                };
+                quote! { #name }
             })
             .collect()
     }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/impl_debug.rs firefox-140.10.2/third_party/rust/bindgen/codegen/impl_debug.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/impl_debug.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/impl_debug.rs	Mon May 11 04:49:32 2026
@@ -1,7 +1,8 @@
 use crate::ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods};
 use crate::ir::context::BindgenContext;
 use crate::ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName};
-use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
+use crate::ir::ty::TypeKind;
+use std::fmt::Write as _;
 
 pub(crate) fn gen_debug_impl(
     ctx: &BindgenContext,
@@ -10,7 +11,7 @@
     kind: CompKind,
 ) -> proc_macro2::TokenStream {
     let struct_name = item.canonical_name(ctx);
-    let mut format_string = format!("{} {{{{ ", struct_name);
+    let mut format_string = format!("{struct_name} {{{{ ");
     let mut tokens = vec![];
 
     if item.is_opaque(ctx, &()) {
@@ -64,7 +65,7 @@
     ) -> Option<(String, Vec<proc_macro2::TokenStream>)>;
 }
 
-impl<'a> ImplDebug<'a> for FieldData {
+impl ImplDebug<'_> for FieldData {
     type Extra = ();
 
     fn impl_debug(
@@ -80,7 +81,7 @@
     }
 }
 
-impl<'a> ImplDebug<'a> for BitfieldUnit {
+impl ImplDebug<'_> for BitfieldUnit {
     type Extra = ();
 
     fn impl_debug(
@@ -96,7 +97,7 @@
             }
 
             if let Some(bitfield_name) = bitfield.name() {
-                format_string.push_str(&format!("{} : {{:?}}", bitfield_name));
+                let _ = write!(format_string, "{bitfield_name} : {{:?}}");
                 let getter_name = bitfield.getter_name();
                 let name_ident = ctx.rust_ident_raw(getter_name);
                 tokens.push(quote! {
@@ -125,19 +126,14 @@
             return None;
         }
 
-        let ty = match self.as_type() {
-            Some(ty) => ty,
-            None => {
-                return None;
-            }
-        };
+        let ty = self.as_type()?;
 
         fn debug_print(
             name: &str,
-            name_ident: proc_macro2::TokenStream,
+            name_ident: &proc_macro2::TokenStream,
         ) -> Option<(String, Vec<proc_macro2::TokenStream>)> {
             Some((
-                format!("{}: {{:?}}", name),
+                format!("{name}: {{:?}}"),
                 vec![quote! {
                     self.#name_ident
                 }],
@@ -158,60 +154,39 @@
             TypeKind::ObjCInterface(..) |
             TypeKind::ObjCId |
             TypeKind::Comp(..) |
-            TypeKind::ObjCSel => debug_print(name, quote! { #name_ident }),
+            TypeKind::ObjCSel => debug_print(name, &quote! { #name_ident }),
 
             TypeKind::TemplateInstantiation(ref inst) => {
                 if inst.is_opaque(ctx, self) {
-                    Some((format!("{}: opaque", name), vec![]))
+                    Some((format!("{name}: opaque"), vec![]))
                 } else {
-                    debug_print(name, quote! { #name_ident })
+                    debug_print(name, &quote! { #name_ident })
                 }
             }
 
             // The generic is not required to implement Debug, so we can not debug print that type
             TypeKind::TypeParam => {
-                Some((format!("{}: Non-debuggable generic", name), vec![]))
+                Some((format!("{name}: Non-debuggable generic"), vec![]))
             }
 
             TypeKind::Array(_, len) => {
                 // Generics are not required to implement Debug
                 if self.has_type_param_in_array(ctx) {
-                    Some((
-                        format!("{}: Array with length {}", name, len),
-                        vec![],
-                    ))
-                } else if len < RUST_DERIVE_IN_ARRAY_LIMIT ||
-                    ctx.options().rust_features().larger_arrays
-                {
-                    // The simple case
-                    debug_print(name, quote! { #name_ident })
-                } else if ctx.options().use_core {
-                    // There is no String in core; reducing field visibility to avoid breaking
-                    // no_std setups.
-                    Some((format!("{}: [...]", name), vec![]))
+                    Some((format!("{name}: Array with length {len}"), vec![]))
                 } else {
-                    // Let's implement our own print function
-                    Some((
-                        format!("{}: [{{}}]", name),
-                        vec![quote! {
-                            self.#name_ident
-                                .iter()
-                                .enumerate()
-                                .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v))
-                                .collect::<String>()
-                        }],
-                    ))
+                    // The simple case
+                    debug_print(name, &quote! { #name_ident })
                 }
             }
             TypeKind::Vector(_, len) => {
                 if ctx.options().use_core {
                     // There is no format! in core; reducing field visibility to avoid breaking
                     // no_std setups.
-                    Some((format!("{}(...)", name), vec![]))
+                    Some((format!("{name}(...)"), vec![]))
                 } else {
                     let self_ids = 0..len;
                     Some((
-                        format!("{}({{}})", name),
+                        format!("{name}({{}})"),
                         vec![quote! {
                             #(format!("{:?}", self.#self_ids)),*
                         }],
@@ -233,9 +208,9 @@
                     TypeKind::Function(ref sig)
                         if !sig.function_pointers_can_derive() =>
                     {
-                        Some((format!("{}: FunctionPointer", name), vec![]))
+                        Some((format!("{name}: FunctionPointer"), vec![]))
                     }
-                    _ => debug_print(name, quote! { #name_ident }),
+                    _ => debug_print(name, &quote! { #name_ident }),
                 }
             }
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/impl_partialeq.rs firefox-140.10.2/third_party/rust/bindgen/codegen/impl_partialeq.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/impl_partialeq.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/impl_partialeq.rs	Mon May 11 04:49:32 2026
@@ -1,7 +1,7 @@
 use crate::ir::comp::{CompInfo, CompKind, Field, FieldMethods};
 use crate::ir::context::BindgenContext;
 use crate::ir::item::{IsOpaque, Item};
-use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
+use crate::ir::ty::TypeKind;
 
 /// Generate a manual implementation of `PartialEq` trait for the
 /// specified compound type.
@@ -23,22 +23,14 @@
             &self.bindgen_union_field[..] == &other.bindgen_union_field[..]
         });
     } else {
-        for base in comp_info.base_members().iter() {
+        for base in comp_info.base_members() {
             if !base.requires_storage(ctx) {
                 continue;
             }
 
             let ty_item = ctx.resolve_item(base.ty);
             let field_name = &base.field_name;
-
-            if ty_item.is_opaque(ctx, &()) {
-                let field_name = ctx.rust_ident(field_name);
-                tokens.push(quote! {
-                    &self. #field_name [..] == &other. #field_name [..]
-                });
-            } else {
-                tokens.push(gen_field(ctx, ty_item, field_name));
-            }
+            tokens.push(gen_field(ctx, ty_item, field_name));
         }
 
         for field in comp_info.fields() {
@@ -76,7 +68,7 @@
     name: &str,
 ) -> proc_macro2::TokenStream {
     fn quote_equals(
-        name_ident: proc_macro2::Ident,
+        name_ident: &proc_macro2::Ident,
     ) -> proc_macro2::TokenStream {
         quote! { self.#name_ident == other.#name_ident }
     }
@@ -100,29 +92,9 @@
         TypeKind::Comp(..) |
         TypeKind::Pointer(_) |
         TypeKind::Function(..) |
-        TypeKind::Opaque => quote_equals(name_ident),
-
-        TypeKind::TemplateInstantiation(ref inst) => {
-            if inst.is_opaque(ctx, ty_item) {
-                quote! {
-                    &self. #name_ident [..] == &other. #name_ident [..]
-                }
-            } else {
-                quote_equals(name_ident)
-            }
-        }
-
-        TypeKind::Array(_, len) => {
-            if len <= RUST_DERIVE_IN_ARRAY_LIMIT ||
-                ctx.options().rust_features().larger_arrays
-            {
-                quote_equals(name_ident)
-            } else {
-                quote! {
-                    &self. #name_ident [..] == &other. #name_ident [..]
-                }
-            }
-        }
+        TypeKind::Array(..) |
+        TypeKind::TemplateInstantiation(..) |
+        TypeKind::Opaque => quote_equals(&name_ident),
         TypeKind::Vector(_, len) => {
             let self_ids = 0..len;
             let other_ids = 0..len;
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/mod.rs firefox-140.10.2/third_party/rust/bindgen/codegen/mod.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/mod.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/mod.rs	Mon May 11 04:49:32 2026
@@ -20,7 +20,10 @@
 
 use super::BindgenOptions;
 
-use crate::callbacks::{DeriveInfo, FieldInfo, TypeKind as DeriveTypeKind};
+use crate::callbacks::{
+    AttributeInfo, DeriveInfo, DiscoveredItem, DiscoveredItemId, FieldInfo,
+    TypeKind as DeriveTypeKind,
+};
 use crate::codegen::error::Error;
 use crate::ir::analysis::{HasVtable, Sizedness};
 use crate::ir::annotations::{
@@ -52,8 +55,8 @@
 use crate::ir::ty::{Type, TypeKind};
 use crate::ir::var::Var;
 
-use proc_macro2::{self, Ident, Span};
-use quote::TokenStreamExt;
+use proc_macro2::{Ident, Span};
+use quote::{ToTokens, TokenStreamExt};
 
 use crate::{Entry, HashMap, HashSet};
 use std::borrow::Cow;
@@ -80,7 +83,7 @@
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             Self::Serialize { msg, loc } => {
-                write!(f, "serialization error at {}: {}", loc, msg)
+                write!(f, "serialization error at {loc}: {msg}")
             }
             Self::Io(err) => err.fmt(f),
         }
@@ -149,22 +152,16 @@
 ) -> DerivableTraits {
     let mut derivable_traits = DerivableTraits::empty();
 
-    let all_template_params = item.all_template_params(ctx);
-
     if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
         derivable_traits |= DerivableTraits::COPY;
 
-        if ctx.options().rust_features().builtin_clone_impls ||
-            !all_template_params.is_empty()
-        {
-            // FIXME: This requires extra logic if you have a big array in a
-            // templated struct. The reason for this is that the magic:
-            //     fn clone(&self) -> Self { *self }
-            // doesn't work for templates.
-            //
-            // It's not hard to fix though.
-            derivable_traits |= DerivableTraits::CLONE;
-        }
+        // FIXME: This requires extra logic if you have a big array in a
+        // templated struct. The reason for this is that the magic:
+        //     fn clone(&self) -> Self { *self }
+        // doesn't work for templates.
+        //
+        // It's not hard to fix though.
+        derivable_traits |= DerivableTraits::CLONE;
     } else if packed {
         // If the struct or union is packed, deriving from Copy is required for
         // deriving from any other trait.
@@ -376,7 +373,7 @@
     }
 }
 
-impl<'a> ops::Deref for CodegenResult<'a> {
+impl ops::Deref for CodegenResult<'_> {
     type Target = Vec<proc_macro2::TokenStream>;
 
     fn deref(&self) -> &Self::Target {
@@ -384,7 +381,7 @@
     }
 }
 
-impl<'a> ops::DerefMut for CodegenResult<'a> {
+impl ops::DerefMut for CodegenResult<'_> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.items
     }
@@ -497,8 +494,7 @@
         if self.is_blocklisted(ctx) || result.seen(self.id()) {
             debug!(
                 "<Item as CodeGenerator>::process_before_codegen: Ignoring hidden or seen: \
-                 self = {:?}",
-                self
+                 self = {self:?}"
             );
             return false;
         }
@@ -507,7 +503,7 @@
             // TODO(emilio, #453): Figure out what to do when this happens
             // legitimately, we could track the opaque stuff and disable the
             // assertion there I guess.
-            warn!("Found non-allowlisted item in code generation: {:?}", self);
+            warn!("Found non-allowlisted item in code generation: {self:?}");
         }
 
         result.set_seen(self.id());
@@ -525,7 +521,7 @@
         result: &mut CodegenResult<'_>,
         _extra: &(),
     ) {
-        debug!("<Item as CodeGenerator>::codegen: self = {:?}", self);
+        debug!("<Item as CodeGenerator>::codegen: self = {self:?}");
         if !self.process_before_codegen(ctx, result) {
             return;
         }
@@ -557,7 +553,7 @@
         result: &mut CodegenResult<'_>,
         item: &Item,
     ) {
-        debug!("<Module as CodeGenerator>::codegen: item = {:?}", item);
+        debug!("<Module as CodeGenerator>::codegen: item = {item:?}");
 
         let codegen_self = |result: &mut CodegenResult,
                             found_any: &mut bool| {
@@ -584,6 +580,7 @@
                 if ctx.need_bindgen_complex_type() {
                     utils::prepend_complex_type(&mut *result);
                 }
+                utils::prepend_opaque_array_types(ctx, &mut *result);
                 if result.saw_objc {
                     utils::prepend_objc_header(ctx, &mut *result);
                 }
@@ -656,7 +653,7 @@
         item: &Item,
     ) {
         use crate::ir::var::VarType;
-        debug!("<Var as CodeGenerator>::codegen: item = {:?}", item);
+        debug!("<Var as CodeGenerator>::codegen: item = {item:?}");
         debug_assert!(item.is_enabled_for_codegen(ctx));
 
         let canonical_name = item.canonical_name(ctx);
@@ -677,7 +674,7 @@
 
         let mut attrs = vec![];
         if let Some(comment) = item.comment(ctx) {
-            attrs.push(attributes::doc(comment));
+            attrs.push(attributes::doc(&comment));
         }
 
         let var_ty = self.ty();
@@ -721,33 +718,40 @@
                     let len = proc_macro2::Literal::usize_unsuffixed(
                         cstr_bytes.len(),
                     );
-
-                    // TODO: Here we ignore the type we just made up, probably
-                    // we should refactor how the variable type and ty ID work.
-                    let array_ty = quote! { [u8; #len] };
-                    let cstr_ty = quote! { ::#prefix::ffi::CStr };
-
-                    let bytes = proc_macro2::Literal::byte_string(&cstr_bytes);
-
-                    if options.generate_cstr &&
-                        rust_features.const_cstr &&
-                        CStr::from_bytes_with_nul(&cstr_bytes).is_ok()
-                    {
-                        result.push(quote! {
-                            #(#attrs)*
-                            #[allow(unsafe_code)]
-                            pub const #canonical_ident: &#cstr_ty = unsafe {
-                                #cstr_ty::from_bytes_with_nul_unchecked(#bytes)
-                            };
-                        });
-                    } else {
-                        let lifetime = if rust_features.static_lifetime_elision
-                        {
+                    let cstr =
+                        if options.generate_cstr && rust_features.const_cstr {
+                            CStr::from_bytes_with_nul(&cstr_bytes).ok()
+                        } else {
                             None
+                        };
+                    if let Some(cstr) = cstr {
+                        let cstr_ty = quote! { ::#prefix::ffi::CStr };
+                        if rust_features.literal_cstr {
+                            let cstr = proc_macro2::Literal::c_string(cstr);
+                            result.push(quote! {
+                                #(#attrs)*
+                                pub const #canonical_ident: &#cstr_ty = #cstr;
+                            });
                         } else {
-                            Some(quote! { 'static })
+                            let bytes =
+                                proc_macro2::Literal::byte_string(&cstr_bytes);
+                            result.push(quote! {
+                                #(#attrs)*
+                                #[allow(unsafe_code)]
+                                pub const #canonical_ident: &#cstr_ty = unsafe {
+                                    #cstr_ty::from_bytes_with_nul_unchecked(#bytes)
+                                };
+                            });
                         }
-                        .into_iter();
+                    } else {
+                        // TODO: Here we ignore the type we just made up, probably
+                        // we should refactor how the variable type and ty ID work.
+                        let array_ty = quote! { [u8; #len] };
+                        let bytes =
+                            proc_macro2::Literal::byte_string(&cstr_bytes);
+                        let lifetime =
+                            if true { None } else { Some(quote! { 'static }) }
+                                .into_iter();
 
                         result.push(quote! {
                             #(#attrs)*
@@ -756,7 +760,7 @@
                     }
                 }
                 VarType::Float(f) => {
-                    if let Ok(expr) = helpers::ast_ty::float_expr(ctx, f) {
+                    if let Ok(expr) = helpers::ast_ty::float_expr(f) {
                         result.push(quote! {
                             #(#attrs)*
                             pub const #canonical_ident : #ty = #expr ;
@@ -771,20 +775,20 @@
                 }
             }
         } else {
-            // If necessary, apply a `#[link_name]` attribute
-            if let Some(link_name) = self.link_name() {
-                attrs.push(attributes::link_name::<false>(link_name));
-            } else {
+            let symbol: &str = self.link_name().unwrap_or_else(|| {
                 let link_name =
                     self.mangled_name().unwrap_or_else(|| self.name());
-                if !utils::names_will_be_identical_after_mangling(
+                if utils::names_will_be_identical_after_mangling(
                     &canonical_name,
                     link_name,
                     None,
                 ) {
+                    canonical_name.as_str()
+                } else {
                     attrs.push(attributes::link_name::<false>(link_name));
+                    link_name
                 }
-            }
+            });
 
             let maybe_mut = if self.is_const() {
                 quote! {}
@@ -792,14 +796,33 @@
                 quote! { mut }
             };
 
+            let safety = ctx
+                .options()
+                .rust_features
+                .unsafe_extern_blocks
+                .then(|| quote!(unsafe));
+
             let tokens = quote!(
-                extern "C" {
+                #safety extern "C" {
                     #(#attrs)*
                     pub static #maybe_mut #canonical_ident: #ty;
                 }
             );
 
-            result.push(tokens);
+            if ctx.options().dynamic_library_name.is_some() {
+                result.dynamic_items().push_var(
+                    &canonical_ident,
+                    symbol,
+                    &self
+                        .ty()
+                        .to_rust_ty_or_opaque(ctx, &())
+                        .into_token_stream(),
+                    ctx.options().dynamic_link_require_all,
+                    ctx.options().wrap_unsafe_ops,
+                );
+            } else {
+                result.push(tokens);
+            }
         }
     }
 }
@@ -814,7 +837,7 @@
         result: &mut CodegenResult<'_>,
         item: &Item,
     ) {
-        debug!("<Type as CodeGenerator>::codegen: item = {:?}", item);
+        debug!("<Type as CodeGenerator>::codegen: item = {item:?}");
         debug_assert!(item.is_enabled_for_codegen(ctx));
 
         match *self.kind() {
@@ -837,7 +860,7 @@
                 // it to BindgenContext::compute_allowlisted_and_codegen_items.
             }
             TypeKind::TemplateInstantiation(ref inst) => {
-                inst.codegen(ctx, result, item)
+                inst.codegen(ctx, result, item);
             }
             TypeKind::BlockPointer(inner) => {
                 if !ctx.options().generate_block {
@@ -854,14 +877,14 @@
                     {
                         utils::fnsig_block(ctx, fnsig)
                     } else {
-                        panic!("invalid block typedef: {:?}", inner_item)
+                        panic!("invalid block typedef: {inner_item:?}")
                     }
                 };
 
                 let rust_name = ctx.rust_ident(name);
 
                 let mut tokens = if let Some(comment) = item.comment(ctx) {
-                    attributes::doc(comment)
+                    attributes::doc(&comment)
                 } else {
                     quote! {}
                 };
@@ -912,16 +935,14 @@
                         assert_eq!(
                             layout.size,
                             ctx.target_pointer_size(),
-                            "Target platform requires `--no-size_t-is-usize`. The size of `{}` ({}) does not match the target pointer size ({})",
-                            spelling,
+                            "Target platform requires `--no-size_t-is-usize`. The size of `{spelling}` ({}) does not match the target pointer size ({})",
                             layout.size,
                             ctx.target_pointer_size(),
                             );
                         assert_eq!(
                             layout.align,
                             ctx.target_pointer_size(),
-                            "Target platform requires `--no-size_t-is-usize`. The alignment of `{}` ({}) does not match the target pointer size ({})",
-                            spelling,
+                            "Target platform requires `--no-size_t-is-usize`. The alignment of `{spelling}` ({}) does not match the target pointer size ({})",
                             layout.align,
                             ctx.target_pointer_size(),
                         );
@@ -961,8 +982,7 @@
                     if inner_canon_type.is_invalid_type_param() {
                         warn!(
                             "Item contained invalid named type, skipping: \
-                             {:?}, {:?}",
-                            item, inner_item
+                             {item:?}, {inner_item:?}"
                         );
                         return;
                     }
@@ -970,8 +990,17 @@
 
                 let rust_name = ctx.rust_ident(&name);
 
+                utils::call_discovered_item_callback(ctx, item, || {
+                    DiscoveredItem::Alias {
+                        alias_name: rust_name.to_string(),
+                        alias_for: DiscoveredItemId::new(
+                            inner_item.id().as_usize(),
+                        ),
+                    }
+                });
+
                 let mut tokens = if let Some(comment) = item.comment(ctx) {
-                    attributes::doc(comment)
+                    attributes::doc(&comment)
                 } else {
                     quote! {}
                 };
@@ -1011,22 +1040,39 @@
                         pub type #rust_name
                     },
                     AliasVariation::NewType | AliasVariation::NewTypeDeref => {
-                        assert!(
-                            ctx.options().rust_features().repr_transparent,
-                            "repr_transparent feature is required to use {:?}",
-                            alias_style
-                        );
-
                         let mut attributes =
                             vec![attributes::repr("transparent")];
                         let packed = false; // Types can't be packed in Rust.
                         let derivable_traits =
                             derives_of_item(item, ctx, packed);
-                        if !derivable_traits.is_empty() {
-                            let derives: Vec<_> = derivable_traits.into();
-                            attributes.push(attributes::derives(&derives))
-                        }
+                        let mut derives: Vec<_> = derivable_traits.into();
+                        // The custom derives callback may return a list of derive attributes;
+                        // add them to the end of the list.
+                        let custom_derives =
+                            ctx.options().all_callbacks(|cb| {
+                                cb.add_derives(&DeriveInfo {
+                                    name: &name,
+                                    kind: DeriveTypeKind::Struct,
+                                })
+                            });
+                        // In most cases this will be a no-op, since custom_derives will be empty.
+                        derives
+                            .extend(custom_derives.iter().map(|s| s.as_str()));
+                        attributes.push(attributes::derives(&derives));
 
+                        let custom_attributes =
+                            ctx.options().all_callbacks(|cb| {
+                                cb.add_attributes(&AttributeInfo {
+                                    name: &name,
+                                    kind: DeriveTypeKind::Struct,
+                                })
+                            });
+                        attributes.extend(
+                            custom_attributes
+                                .iter()
+                                .map(|s| s.parse().unwrap()),
+                        );
+
                         quote! {
                             #( #attributes )*
                             pub struct #rust_name
@@ -1044,8 +1090,7 @@
                 {
                     warn!(
                         "Item contained invalid template \
-                         parameter: {:?}",
-                        item
+                         parameter: {item:?}"
                     );
                     return;
                 }
@@ -1064,13 +1109,24 @@
                     });
                 }
 
-                let access_spec =
-                    access_specifier(ctx.options().default_visibility);
                 tokens.append_all(match alias_style {
                     AliasVariation::TypeAlias => quote! {
                         = #inner_rust_type ;
                     },
                     AliasVariation::NewType | AliasVariation::NewTypeDeref => {
+                        let visibility = ctx
+                            .options()
+                            .last_callback(|cb| {
+                                cb.field_visibility(FieldInfo {
+                                    type_name: &item.canonical_name(ctx),
+                                    field_name: "0",
+                                    field_type_name: inner_item
+                                        .expect_type()
+                                        .name(),
+                                })
+                            })
+                            .unwrap_or(ctx.options().default_visibility);
+                        let access_spec = access_specifier(visibility);
                         quote! {
                             (#access_spec #inner_rust_type) ;
                         }
@@ -1103,10 +1159,10 @@
                 result.saw_objc();
             }
             TypeKind::ObjCInterface(ref interface) => {
-                interface.codegen(ctx, result, item)
+                interface.codegen(ctx, result, item);
             }
             ref u @ TypeKind::UnresolvedTypeRef(..) => {
-                unreachable!("Should have been resolved after parsing {:?}!", u)
+                unreachable!("Should have been resolved after parsing {u:?}!")
             }
         }
     }
@@ -1125,7 +1181,7 @@
     }
 }
 
-impl<'a> CodeGenerator for Vtable<'a> {
+impl CodeGenerator for Vtable<'_> {
     type Extra = Item;
     type Return = ();
 
@@ -1160,10 +1216,7 @@
                     let function_item = ctx.resolve_item(m.signature());
                     let function = function_item.expect_function();
                     let signature_item = ctx.resolve_item(function.signature());
-                    let signature = match signature_item.expect_type().kind() {
-                        TypeKind::Function(ref sig) => sig,
-                        _ => panic!("Function signature type mismatch"),
-                    };
+                    let TypeKind::Function(ref signature) = signature_item.expect_type().kind() else { panic!("Function signature type mismatch") };
 
                     // FIXME: Is there a canonical name without the class prepended?
                     let function_name = function_item.canonical_name(ctx);
@@ -1190,7 +1243,7 @@
                 pub struct #name {
                     #( #methods ),*
                 }
-            })
+            });
         } else {
             // For the cases we don't support, simply generate an empty struct.
             let void = helpers::ast_ty::c_void(ctx);
@@ -1203,13 +1256,13 @@
     }
 }
 
-impl<'a> ItemCanonicalName for Vtable<'a> {
+impl ItemCanonicalName for Vtable<'_> {
     fn canonical_name(&self, ctx: &BindgenContext) -> String {
         format!("{}__bindgen_vtable", self.item_id.canonical_name(ctx))
     }
 }
 
-impl<'a> TryToRustTy for Vtable<'a> {
+impl TryToRustTy for Vtable<'_> {
     type Extra = ();
 
     fn try_to_rust_ty(
@@ -1244,6 +1297,9 @@
             return;
         }
 
+        // For consistency with other layout tests, gate this on offset_of.
+        let compile_time = ctx.options().rust_features().offset_of;
+
         // If there are any unbound type parameters, then we can't generate a
         // layout test because we aren't dealing with a concrete type with a
         // concrete size and alignment.
@@ -1258,15 +1314,18 @@
             let align = layout.align;
 
             let name = item.full_disambiguated_name(ctx);
-            let mut fn_name =
-                format!("__bindgen_test_layout_{}_instantiation", name);
-            let times_seen = result.overload_number(&fn_name);
-            if times_seen > 0 {
-                write!(&mut fn_name, "_{}", times_seen).unwrap();
-            }
+            let fn_name = if compile_time {
+                None
+            } else {
+                let mut fn_name =
+                    format!("__bindgen_test_layout_{name}_instantiation");
+                let times_seen = result.overload_number(&fn_name);
+                if times_seen > 0 {
+                    write!(&mut fn_name, "_{times_seen}").unwrap();
+                }
+                Some(ctx.rust_ident_raw(fn_name))
+            };
 
-            let fn_name = ctx.rust_ident_raw(fn_name);
-
             let prefix = ctx.trait_prefix();
             let ident = item.to_rust_ty_or_opaque(ctx, &());
             let size_of_expr = quote! {
@@ -1275,20 +1334,33 @@
             let align_of_expr = quote! {
                 ::#prefix::mem::align_of::<#ident>()
             };
+            let size_of_err =
+                format!("Size of template specialization: {name}");
+            let align_of_err =
+                format!("Align of template specialization: {name}");
 
-            let item = quote! {
-                #[test]
-                fn #fn_name() {
-                    assert_eq!(#size_of_expr, #size,
-                               concat!("Size of template specialization: ",
-                                       stringify!(#ident)));
-                    assert_eq!(#align_of_expr, #align,
-                               concat!("Alignment of template specialization: ",
-                                       stringify!(#ident)));
-                }
-            };
-
-            result.push(item);
+            if compile_time {
+                // In an ideal world this would be assert_eq!, but that is not
+                // supported in const fn due to the need for string formatting.
+                // If #size_of_expr > #size, this will index OOB, and if
+                // #size_of_expr < #size, the subtraction will overflow, both
+                // of which print enough information to see what has gone wrong.
+                result.push(quote! {
+                    #[allow(clippy::unnecessary_operation, clippy::identity_op)]
+                    const _: () = {
+                        [#size_of_err][#size_of_expr - #size];
+                        [#align_of_err][#align_of_expr - #align];
+                    };
+                });
+            } else {
+                result.push(quote! {
+                    #[test]
+                    fn #fn_name() {
+                        assert_eq!(#size_of_expr, #size, #size_of_err);
+                        assert_eq!(#align_of_expr, #align, #align_of_err);
+                    }
+                });
+            }
         }
     }
 }
@@ -1305,6 +1377,7 @@
         accessor_kind: FieldAccessorKind,
         parent: &CompInfo,
         parent_item: &Item,
+        last_field: bool,
         result: &mut CodegenResult,
         struct_layout: &mut StructLayoutTracker,
         fields: &mut F,
@@ -1315,7 +1388,7 @@
         M: Extend<proc_macro2::TokenStream>;
 }
 
-impl<'a> FieldCodegen<'a> for Field {
+impl FieldCodegen<'_> for Field {
     type Extra = ();
 
     fn codegen<F, M>(
@@ -1325,6 +1398,7 @@
         accessor_kind: FieldAccessorKind,
         parent: &CompInfo,
         parent_item: &Item,
+        last_field: bool,
         result: &mut CodegenResult,
         struct_layout: &mut StructLayoutTracker,
         fields: &mut F,
@@ -1342,6 +1416,7 @@
                     accessor_kind,
                     parent,
                     parent_item,
+                    last_field,
                     result,
                     struct_layout,
                     fields,
@@ -1356,6 +1431,7 @@
                     accessor_kind,
                     parent,
                     parent_item,
+                    last_field,
                     result,
                     struct_layout,
                     fields,
@@ -1390,7 +1466,7 @@
     }
 }
 
-impl<'a> FieldCodegen<'a> for FieldData {
+impl FieldCodegen<'_> for FieldData {
     type Extra = ();
 
     fn codegen<F, M>(
@@ -1400,6 +1476,7 @@
         accessor_kind: FieldAccessorKind,
         parent: &CompInfo,
         parent_item: &Item,
+        last_field: bool,
         result: &mut CodegenResult,
         struct_layout: &mut StructLayoutTracker,
         fields: &mut F,
@@ -1425,14 +1502,20 @@
         let ty = if parent.is_union() {
             wrap_union_field_if_needed(ctx, struct_layout, ty, result)
         } else if let Some(item) = field_ty.is_incomplete_array(ctx) {
-            result.saw_incomplete_array();
+            // Only FAM if its the last field
+            if ctx.options().flexarray_dst && last_field {
+                struct_layout.saw_flexible_array();
+                syn::parse_quote! { FAM }
+            } else {
+                result.saw_incomplete_array();
 
-            let inner = item.to_rust_ty_or_opaque(ctx, &());
+                let inner = item.to_rust_ty_or_opaque(ctx, &());
 
-            if ctx.options().enable_cxx_namespaces {
-                syn::parse_quote! { root::__IncompleteArrayField<#inner> }
-            } else {
-                syn::parse_quote! { __IncompleteArrayField<#inner> }
+                if ctx.options().enable_cxx_namespaces {
+                    syn::parse_quote! { root::__IncompleteArrayField<#inner> }
+                } else {
+                    syn::parse_quote! { __IncompleteArrayField<#inner> }
+                }
             }
         } else {
             ty
@@ -1442,7 +1525,7 @@
         if ctx.options().generate_comments {
             if let Some(raw_comment) = self.comment() {
                 let comment = ctx.options().process_comment(raw_comment);
-                field = attributes::doc(comment);
+                field = attributes::doc(&comment);
             }
         }
 
@@ -1466,6 +1549,7 @@
                 cb.field_visibility(FieldInfo {
                     type_name: &parent_item.canonical_name(ctx),
                     field_name,
+                    field_type_name: field_ty.name(),
                 })
             }),
             self.annotations(),
@@ -1499,9 +1583,9 @@
             return;
         }
 
-        let getter_name = ctx.rust_ident_raw(format!("get_{}", field_name));
+        let getter_name = ctx.rust_ident_raw(format!("get_{field_name}"));
         let mutable_getter_name =
-            ctx.rust_ident_raw(format!("get_{}_mut", field_name));
+            ctx.rust_ident_raw(format!("get_{field_name}_mut"));
 
         methods.extend(Some(match accessor_kind {
             FieldAccessorKind::None => unreachable!(),
@@ -1563,18 +1647,17 @@
     fn extend_ctor_impl(
         &self,
         ctx: &BindgenContext,
-        param_name: proc_macro2::TokenStream,
+        param_name: &proc_macro2::TokenStream,
         mut ctor_impl: proc_macro2::TokenStream,
     ) -> proc_macro2::TokenStream {
         let bitfield_ty = ctx.resolve_type(self.ty());
         let bitfield_ty_layout = bitfield_ty
             .layout(ctx)
             .expect("Bitfield without layout? Gah!");
-        let bitfield_int_ty = helpers::integer_type(ctx, bitfield_ty_layout)
-            .expect(
-                "Should already have verified that the bitfield is \
+        let bitfield_int_ty = helpers::integer_type(bitfield_ty_layout).expect(
+            "Should already have verified that the bitfield is \
                  representable as an int",
-            );
+        );
 
         let offset = self.offset_into_unit();
         let width = self.width() as u8;
@@ -1609,13 +1692,13 @@
 
 /// Compute a fields or structs visibility based on multiple conditions.
 /// 1. If the element was declared public, and we respect such CXX accesses specs
-/// (context option) => By default Public, but this can be overruled by an `annotation`.
+///    (context option) => By default Public, but this can be overruled by an `annotation`.
 ///
 /// 2. If the element was declared private, and we respect such CXX accesses specs
-/// (context option) => By default Private, but this can be overruled by an `annotation`.
+///    (context option) => By default Private, but this can be overruled by an `annotation`.
 ///
 /// 3. If we do not respect visibility modifiers, the result depends on the `annotation`,
-/// if any, or the passed `default_kind`.
+///    if any, or the passed `default_kind`.
 ///
 fn compute_visibility(
     ctx: &BindgenContext,
@@ -1644,7 +1727,7 @@
         })
 }
 
-impl<'a> FieldCodegen<'a> for BitfieldUnit {
+impl FieldCodegen<'_> for BitfieldUnit {
     type Extra = ();
 
     fn codegen<F, M>(
@@ -1654,6 +1737,7 @@
         accessor_kind: FieldAccessorKind,
         parent: &CompInfo,
         parent_item: &Item,
+        last_field: bool,
         result: &mut CodegenResult,
         struct_layout: &mut StructLayoutTracker,
         fields: &mut F,
@@ -1683,22 +1767,6 @@
             }
         };
 
-        {
-            let align_field_name = format!("_bitfield_align_{}", self.nth());
-            let align_field_ident = ctx.rust_ident(align_field_name);
-            let align_ty = match self.layout().align {
-                n if n >= 8 => quote! { u64 },
-                4 => quote! { u32 },
-                2 => quote! { u16 },
-                _ => quote! { u8  },
-            };
-            let access_spec = access_specifier(visibility_kind);
-            let align_field = quote! {
-                #access_spec #align_field_ident: [#align_ty; 0],
-            };
-            fields.extend(Some(align_field));
-        }
-
         let unit_field_name = format!("_bitfield_{}", self.nth());
         let unit_field_ident = ctx.rust_ident(&unit_field_name);
 
@@ -1714,18 +1782,13 @@
         let mut generate_ctor = layout.size <= RUST_DERIVE_IN_ARRAY_LIMIT;
 
         let mut unit_visibility = visibility_kind;
-        for bf in self.bitfields() {
+        let bfields = self.bitfields();
+        for (idx, bf) in bfields.iter().enumerate() {
             // Codegen not allowed for anonymous bitfields
             if bf.name().is_none() {
                 continue;
             }
 
-            if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT &&
-                !ctx.options().rust_features().larger_arrays
-            {
-                continue;
-            }
-
             let mut bitfield_representable_as_int = true;
             let mut bitfield_visibility = visibility_kind;
             bf.codegen(
@@ -1734,12 +1797,14 @@
                 accessor_kind,
                 parent,
                 parent_item,
+                last_field && idx == bfields.len() - 1,
                 result,
                 struct_layout,
                 fields,
                 methods,
                 (
                     &unit_field_name,
+                    &unit_field_ty,
                     &mut bitfield_representable_as_int,
                     &mut bitfield_visibility,
                 ),
@@ -1763,7 +1828,7 @@
             ctor_params.push(quote! {
                 #param_name : #bitfield_ty
             });
-            ctor_impl = bf.extend_ctor_impl(ctx, param_name, ctor_impl);
+            ctor_impl = bf.extend_ctor_impl(ctx, &param_name, ctor_impl);
         }
 
         let access_spec = access_specifier(unit_visibility);
@@ -1797,6 +1862,15 @@
     quote! { #name }
 }
 
+fn bitfield_raw_getter_name(
+    ctx: &BindgenContext,
+    bitfield: &Bitfield,
+) -> proc_macro2::TokenStream {
+    let name = bitfield.getter_name();
+    let name = ctx.rust_ident_raw(format!("{name}_raw"));
+    quote! { #name }
+}
+
 fn bitfield_setter_name(
     ctx: &BindgenContext,
     bitfield: &Bitfield,
@@ -1806,8 +1880,22 @@
     quote! { #setter }
 }
 
+fn bitfield_raw_setter_name(
+    ctx: &BindgenContext,
+    bitfield: &Bitfield,
+) -> proc_macro2::TokenStream {
+    let setter = bitfield.setter_name();
+    let setter = ctx.rust_ident_raw(format!("{setter}_raw"));
+    quote! { #setter }
+}
+
 impl<'a> FieldCodegen<'a> for Bitfield {
-    type Extra = (&'a str, &'a mut bool, &'a mut FieldVisibilityKind);
+    type Extra = (
+        &'a str,
+        &'a syn::Type,
+        &'a mut bool,
+        &'a mut FieldVisibilityKind,
+    );
 
     fn codegen<F, M>(
         &self,
@@ -1816,12 +1904,19 @@
         _accessor_kind: FieldAccessorKind,
         parent: &CompInfo,
         parent_item: &Item,
+        _last_field: bool,
         _result: &mut CodegenResult,
         struct_layout: &mut StructLayoutTracker,
         _fields: &mut F,
         methods: &mut M,
-        (unit_field_name, bitfield_representable_as_int, bitfield_visibility): (
+        (
+            unit_field_name,
+            unit_field_ty,
+            bitfield_representable_as_int,
+            bitfield_visibility,
+        ): (
             &'a str,
+            &'a syn::Type,
             &mut bool,
             &'a mut FieldVisibilityKind,
         ),
@@ -1832,24 +1927,24 @@
         let prefix = ctx.trait_prefix();
         let getter_name = bitfield_getter_name(ctx, self);
         let setter_name = bitfield_setter_name(ctx, self);
+        let raw_getter_name = bitfield_raw_getter_name(ctx, self);
+        let raw_setter_name = bitfield_raw_setter_name(ctx, self);
         let unit_field_ident = Ident::new(unit_field_name, Span::call_site());
 
         let bitfield_ty_item = ctx.resolve_item(self.ty());
         let bitfield_ty = bitfield_ty_item.expect_type();
+        let bitfield_ty_ident = bitfield_ty.name();
 
         let bitfield_ty_layout = bitfield_ty
             .layout(ctx)
             .expect("Bitfield without layout? Gah!");
         let bitfield_int_ty =
-            match helpers::integer_type(ctx, bitfield_ty_layout) {
-                Some(int_ty) => {
-                    *bitfield_representable_as_int = true;
-                    int_ty
-                }
-                None => {
-                    *bitfield_representable_as_int = false;
-                    return;
-                }
+            if let Some(int_ty) = helpers::integer_type(bitfield_ty_layout) {
+                *bitfield_representable_as_int = true;
+                int_ty
+            } else {
+                *bitfield_representable_as_int = false;
+                return;
             };
 
         let bitfield_ty =
@@ -1863,6 +1958,7 @@
                 cb.field_visibility(FieldInfo {
                     type_name: &parent_item.canonical_name(ctx),
                     field_name,
+                    field_type_name: bitfield_ty_ident,
                 })
             })
         });
@@ -1899,6 +1995,32 @@
                     }
                 }
             }));
+
+            methods.extend(Some(quote! {
+                #[inline]
+                #access_spec unsafe fn #raw_getter_name(this: *const Self) -> #bitfield_ty {
+                    unsafe {
+                        ::#prefix::mem::transmute(<#unit_field_ty>::raw_get(
+                            (*::#prefix::ptr::addr_of!((*this).#unit_field_ident)).as_ref() as *const _,
+                            #offset,
+                            #width,
+                        ) as #bitfield_int_ty)
+                    }
+                }
+
+                #[inline]
+                #access_spec unsafe fn #raw_setter_name(this: *mut Self, val: #bitfield_ty) {
+                    unsafe {
+                        let val: #bitfield_int_ty = ::#prefix::mem::transmute(val);
+                        <#unit_field_ty>::raw_set(
+                            (*::#prefix::ptr::addr_of_mut!((*this).#unit_field_ident)).as_mut() as *mut _,
+                            #offset,
+                            #width,
+                            val as u64,
+                        )
+                    }
+                }
+            }));
         } else {
             methods.extend(Some(quote! {
                 #[inline]
@@ -1923,6 +2045,32 @@
                     }
                 }
             }));
+
+            methods.extend(Some(quote! {
+                #[inline]
+                #access_spec unsafe fn #raw_getter_name(this: *const Self) -> #bitfield_ty {
+                    unsafe {
+                        ::#prefix::mem::transmute(<#unit_field_ty>::raw_get(
+                            ::#prefix::ptr::addr_of!((*this).#unit_field_ident),
+                            #offset,
+                            #width,
+                        ) as #bitfield_int_ty)
+                    }
+                }
+
+                #[inline]
+                #access_spec unsafe fn #raw_setter_name(this: *mut Self, val: #bitfield_ty) {
+                    unsafe {
+                        let val: #bitfield_int_ty = ::#prefix::mem::transmute(val);
+                        <#unit_field_ty>::raw_set(
+                            ::#prefix::ptr::addr_of_mut!((*this).#unit_field_ident),
+                            #offset,
+                            #width,
+                            val as u64,
+                        )
+                    }
+                }
+            }));
         }
     }
 }
@@ -1937,7 +2085,7 @@
         result: &mut CodegenResult<'_>,
         item: &Item,
     ) {
-        debug!("<CompInfo as CodeGenerator>::codegen: item = {:?}", item);
+        debug!("<CompInfo as CodeGenerator>::codegen: item = {item:?}");
         debug_assert!(item.is_enabled_for_codegen(ctx));
 
         // Don't output classes with template parameters that aren't types, and
@@ -1980,6 +2128,23 @@
             packed,
         );
 
+        let mut generic_param_names = vec![];
+
+        for (idx, ty) in item.used_template_params(ctx).iter().enumerate() {
+            let param = ctx.resolve_type(*ty);
+            let name = param.name().unwrap();
+            let ident = ctx.rust_ident(name);
+            generic_param_names.push(ident.clone());
+
+            let prefix = ctx.trait_prefix();
+            let field_name = ctx.rust_ident(format!("_phantom_{idx}"));
+            fields.push(quote! {
+                pub #field_name : ::#prefix::marker::PhantomData<
+                    ::#prefix::cell::UnsafeCell<#ident>
+                > ,
+            });
+        }
+
         if !is_opaque {
             if item.has_vtable_ptr(ctx) {
                 let vtable = Vtable::new(item.id(), self);
@@ -2032,13 +2197,15 @@
                 .annotations()
                 .accessor_kind()
                 .unwrap_or(FieldAccessorKind::None);
-            for field in self.fields() {
+            let field_decls = self.fields();
+            for (idx, field) in field_decls.iter().enumerate() {
                 field.codegen(
                     ctx,
                     visibility,
                     struct_accessor_kind,
                     self,
                     item,
+                    idx == field_decls.len() - 1,
                     result,
                     &mut struct_layout,
                     &mut fields,
@@ -2090,14 +2257,13 @@
 
             if has_address {
                 let layout = Layout::new(1, 1);
-                let ty = helpers::blob(ctx, Layout::new(1, 1));
                 struct_layout.saw_field_with_layout(
                     "_address",
                     layout,
                     /* offset = */ Some(0),
                 );
                 fields.push(quote! {
-                    pub _address: #ty,
+                    pub _address: u8,
                 });
             }
         }
@@ -2106,14 +2272,15 @@
             match layout {
                 Some(l) => {
                     explicit_align = Some(l.align);
-
-                    let ty = helpers::blob(ctx, l);
+                    let ty = helpers::blob(ctx, l, false);
                     fields.push(quote! {
                         pub _bindgen_opaque_blob: #ty ,
                     });
                 }
                 None => {
-                    warn!("Opaque type without layout! Expect dragons!");
+                    if !forward_decl {
+                        warn!("Opaque type without layout! Expect dragons!");
+                    }
                 }
             }
         } else if !is_union && !zero_sized {
@@ -2129,32 +2296,22 @@
                         packed = true;
                     } else {
                         explicit_align = Some(layout.align);
-                        if !ctx.options().rust_features.repr_align {
-                            let ty = helpers::blob(
-                                ctx,
-                                Layout::new(0, layout.align),
-                            );
-                            fields.push(quote! {
-                                pub __bindgen_align: #ty ,
-                            });
-                        }
                     }
                 }
             }
         } else if is_union && !forward_decl {
-            // TODO(emilio): It'd be nice to unify this with the struct path
-            // above somehow.
-            let layout = layout.expect("Unable to get layout information?");
-            if struct_layout.requires_explicit_align(layout) {
-                explicit_align = Some(layout.align);
+            if let Some(layout) = layout {
+                // TODO(emilio): It'd be nice to unify this with the struct path above somehow.
+                if struct_layout.requires_explicit_align(layout) {
+                    explicit_align = Some(layout.align);
+                }
+                if !struct_layout.is_rust_union() {
+                    let ty = helpers::blob(ctx, layout, false);
+                    fields.push(quote! {
+                        pub bindgen_union_field: #ty,
+                    });
+                }
             }
-
-            if !struct_layout.is_rust_union() {
-                let ty = helpers::blob(ctx, layout);
-                fields.push(quote! {
-                    pub bindgen_union_field: #ty ,
-                })
-            }
         }
 
         if forward_decl {
@@ -2163,39 +2320,62 @@
             });
         }
 
-        let mut generic_param_names = vec![];
-
-        for (idx, ty) in item.used_template_params(ctx).iter().enumerate() {
-            let param = ctx.resolve_type(*ty);
-            let name = param.name().unwrap();
-            let ident = ctx.rust_ident(name);
-            generic_param_names.push(ident.clone());
-
-            let prefix = ctx.trait_prefix();
-            let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
-            fields.push(quote! {
-                pub #field_name : ::#prefix::marker::PhantomData<
-                    ::#prefix::cell::UnsafeCell<#ident>
-                > ,
-            });
-        }
-
-        let generics = if !generic_param_names.is_empty() {
-            let generic_param_names = generic_param_names.clone();
-            quote! {
-                < #( #generic_param_names ),* >
+        let (flex_array_generic, flex_inner_ty) = if ctx.options().flexarray_dst
+        {
+            match self.flex_array_member(ctx) {
+                Some(ty) => {
+                    let inner = ty.to_rust_ty_or_opaque(ctx, &());
+                    (
+                        Some(quote! { FAM: ?Sized = [ #inner; 0 ] }),
+                        Some(quote! { #inner }),
+                    )
+                }
+                None => (None, None),
             }
         } else {
-            quote! {}
+            (None, None)
         };
 
+        // Generics, including the flexible array member.
+        //
+        // generics - generic parameters for the struct declaration
+        // impl_generics_labels - generic parameters for `impl<...>`
+        // impl_generics_params - generic parameters for `impl structname<...>`
+        //
+        // `impl` blocks are for non-FAM related impls like Default, etc
+        let (generics, impl_generics_labels, impl_generics_params) =
+            if !generic_param_names.is_empty() || flex_array_generic.is_some() {
+                let (flex_sized, flex_fam) = match flex_inner_ty.as_ref() {
+                    None => (None, None),
+                    Some(ty) => (
+                        Some(quote! { [ #ty; 0 ] }),
+                        Some(quote! { FAM: ?Sized = [ #ty; 0 ] }),
+                    ),
+                };
+
+                (
+                    quote! {
+                        < #( #generic_param_names , )* #flex_fam >
+                    },
+                    quote! {
+                        < #( #generic_param_names , )* >
+                    },
+                    quote! {
+                        < #( #generic_param_names , )* #flex_sized >
+                    },
+                )
+            } else {
+                (quote! {}, quote! {}, quote! {})
+            };
+
         let mut attributes = vec![];
         let mut needs_clone_impl = false;
         let mut needs_default_impl = false;
         let mut needs_debug_impl = false;
         let mut needs_partialeq_impl = false;
+        let needs_flexarray_impl = flex_array_generic.is_some();
         if let Some(comment) = item.comment(ctx) {
-            attributes.push(attributes::doc(comment));
+            attributes.push(attributes::doc(&comment));
         }
 
         // if a type has both a "packed" attribute and an "align(N)" attribute, then check if the
@@ -2206,21 +2386,34 @@
                 self.already_packed(ctx).unwrap_or(false))
         {
             let n = layout.map_or(1, |l| l.align);
-            assert!(ctx.options().rust_features().repr_packed_n || n == 1);
             let packed_repr = if n == 1 {
                 "packed".to_string()
             } else {
-                format!("packed({})", n)
+                format!("packed({n})")
             };
             attributes.push(attributes::repr_list(&["C", &packed_repr]));
         } else {
             attributes.push(attributes::repr("C"));
         }
 
-        if ctx.options().rust_features().repr_align {
-            if let Some(explicit) = explicit_align {
-                // Ensure that the struct has the correct alignment even in
-                // presence of alignas.
+        // Ensure that the struct has the correct alignment even in presence of alignas and co.
+        if let Some(explicit) = explicit_align {
+            // If we need explicit alignment and can do it, we prefer to insert a dummy field at
+            // the beginning of the struct. This avoids hitting
+            // https://github.com/rust-lang/rust-bindgen/issues/2179
+            // Do it for bitfields only for now for backwards compat.
+            if self.has_bitfields() && explicit <= 8 {
+                let align_ty = match explicit {
+                    8 => quote! { u64 },
+                    4 => quote! { u32 },
+                    2 => quote! { u16 },
+                    _ => quote! { u8  },
+                };
+                let align_field = quote! {
+                    pub _bindgen_align: [#align_ty; 0],
+                };
+                fields.insert(0, align_field);
+            } else {
                 let explicit = helpers::ast_ty::int_expr(explicit as i64);
                 attributes.push(quote! {
                     #[repr(align(#explicit))]
@@ -2263,6 +2456,25 @@
 
         let is_rust_union = is_union && struct_layout.is_rust_union();
 
+        utils::call_discovered_item_callback(ctx, item, || match self.kind() {
+            CompKind::Struct => DiscoveredItem::Struct {
+                original_name: item
+                    .kind()
+                    .expect_type()
+                    .name()
+                    .map(String::from),
+                final_name: canonical_ident.to_string(),
+            },
+            CompKind::Union => DiscoveredItem::Union {
+                original_name: item
+                    .kind()
+                    .expect_type()
+                    .name()
+                    .map(String::from),
+                final_name: canonical_ident.to_string(),
+            },
+        });
+
         // The custom derives callback may return a list of derive attributes;
         // add them to the end of the list.
         let custom_derives = ctx.options().all_callbacks(|cb| {
@@ -2279,9 +2491,28 @@
         derives.extend(custom_derives.iter().map(|s| s.as_str()));
 
         if !derives.is_empty() {
-            attributes.push(attributes::derives(&derives))
+            attributes.push(attributes::derives(&derives));
         }
 
+        attributes.extend(
+            item.annotations()
+                .attributes()
+                .iter()
+                .map(|s| s.parse().unwrap()),
+        );
+
+        let custom_attributes = ctx.options().all_callbacks(|cb| {
+            cb.add_attributes(&AttributeInfo {
+                name: &canonical_name,
+                kind: if is_rust_union {
+                    DeriveTypeKind::Union
+                } else {
+                    DeriveTypeKind::Struct
+                },
+            })
+        });
+        attributes.extend(custom_attributes.iter().map(|s| s.parse().unwrap()));
+
         if item.must_use(ctx) {
             attributes.push(attributes::must_use());
         }
@@ -2319,10 +2550,7 @@
         // affect layout, so we're bad and pray to the gods for avoid sending
         // all the tests to shit when parsing things like max_align_t.
         if self.found_unknown_attr() {
-            warn!(
-                "Type {} has an unknown attribute that may affect layout",
-                canonical_ident
-            );
+            warn!("Type {canonical_ident} has an unknown attribute that may affect layout");
         }
 
         if all_template_params.is_empty() {
@@ -2334,9 +2562,14 @@
 
             if ctx.options().layout_tests && !self.is_forward_declaration() {
                 if let Some(layout) = layout {
-                    let fn_name =
-                        format!("bindgen_test_layout_{}", canonical_ident);
-                    let fn_name = ctx.rust_ident_raw(fn_name);
+                    let compile_time = ctx.options().rust_features().offset_of;
+                    let fn_name = if compile_time {
+                        None
+                    } else {
+                        let fn_name =
+                            format!("bindgen_test_layout_{canonical_ident}");
+                        Some(ctx.rust_ident_raw(fn_name))
+                    };
                     let prefix = ctx.trait_prefix();
                     let size_of_expr = quote! {
                         ::#prefix::mem::size_of::<#canonical_ident>()
@@ -2346,19 +2579,18 @@
                     };
                     let size = layout.size;
                     let align = layout.align;
+                    let size_of_err = format!("Size of {canonical_ident}");
+                    let align_of_err =
+                        format!("Alignment of {canonical_ident}");
 
-                    let check_struct_align = if align >
-                        ctx.target_pointer_size() &&
-                        !ctx.options().rust_features().repr_align
-                    {
-                        None
+                    let check_struct_align = if compile_time {
+                        quote! {
+                            [#align_of_err][#align_of_expr - #align];
+                        }
                     } else {
-                        Some(quote! {
-                            assert_eq!(#align_of_expr,
-                                   #align,
-                                   concat!("Alignment of ", stringify!(#canonical_ident)));
-
-                        })
+                        quote! {
+                            assert_eq!(#align_of_expr, #align, #align_of_err);
+                        }
                     };
 
                     let should_skip_field_offset_checks = is_opaque;
@@ -2369,30 +2601,40 @@
                     } else {
                         self.fields()
                             .iter()
-                            .filter_map(|field| match *field {
-                                Field::DataMember(ref f) if f.name().is_some() => Some(f),
-                                _ => None,
-                            })
-                            .flat_map(|field| {
-                                let name = field.name().unwrap();
+                            .filter_map(|field| {
+                                let Field::DataMember(field) = field else { return None };
+                                let name = field.name()?;
                                 field.offset().map(|offset| {
                                     let field_offset = offset / 8;
                                     let field_name = ctx.rust_ident(name);
-                                    quote! {
-                                        assert_eq!(
-                                            unsafe {
-                                                ::#prefix::ptr::addr_of!((*ptr).#field_name) as usize - ptr as usize
-                                            },
-                                            #field_offset,
-                                            concat!("Offset of field: ", stringify!(#canonical_ident), "::", stringify!(#field_name))
-                                        );
+                                    let offset_of_err = format!("Offset of field: {canonical_ident}::{field_name}");
+                                    if compile_time {
+                                        quote! {
+                                            [#offset_of_err][
+                                                ::#prefix::mem::offset_of!(#canonical_ident, #field_name) - #field_offset
+                                            ];
+                                        }
+                                    } else {
+                                        quote! {
+                                            assert_eq!(
+                                                unsafe {
+                                                    ::#prefix::ptr::addr_of!((*ptr).#field_name) as usize - ptr as usize
+                                                },
+                                                #field_offset,
+                                                #offset_of_err
+                                            );
+                                        }
                                     }
                                 })
                             })
                             .collect()
                     };
 
-                    let uninit_decl = if !check_field_offset.is_empty() {
+                    let uninit_decl = if check_field_offset.is_empty() ||
+                        compile_time
+                    {
+                        None
+                    } else {
                         // FIXME: When MSRV >= 1.59.0, we can use
                         // > const PTR: *const #canonical_ident = ::#prefix::mem::MaybeUninit::uninit().as_ptr();
                         Some(quote! {
@@ -2402,35 +2644,43 @@
                             const UNINIT: ::#prefix::mem::MaybeUninit<#canonical_ident> = ::#prefix::mem::MaybeUninit::uninit();
                             let ptr = UNINIT.as_ptr();
                         })
-                    } else {
-                        None
                     };
 
-                    let item = quote! {
-                        #[test]
-                        fn #fn_name() {
-                            #uninit_decl
-                            assert_eq!(#size_of_expr,
-                                       #size,
-                                       concat!("Size of: ", stringify!(#canonical_ident)));
-                            #check_struct_align
-                            #( #check_field_offset )*
-                        }
-                    };
-                    result.push(item);
+                    if compile_time {
+                        result.push(quote! {
+                            #[allow(clippy::unnecessary_operation, clippy::identity_op)]
+                            const _: () = {
+                                [#size_of_err][#size_of_expr - #size];
+                                #check_struct_align
+                                #( #check_field_offset )*
+                            };
+                        });
+                    } else {
+                        result.push(quote! {
+                            #[test]
+                            fn #fn_name() {
+                                #uninit_decl
+                                assert_eq!(#size_of_expr, #size, #size_of_err);
+                                #check_struct_align
+                                #( #check_field_offset )*
+                            }
+                        });
+                    }
                 }
             }
 
             let mut method_names = Default::default();
+            let discovered_id = DiscoveredItemId::new(item.id().as_usize());
             if ctx.options().codegen_config.methods() {
                 for method in self.methods() {
-                    assert!(method.kind() != MethodKind::Constructor);
+                    assert_ne!(method.kind(), MethodKind::Constructor);
                     method.codegen_method(
                         ctx,
                         &mut methods,
                         &mut method_names,
                         result,
                         self,
+                        discovered_id,
                     );
                 }
             }
@@ -2449,6 +2699,7 @@
                         &mut method_names,
                         result,
                         self,
+                        discovered_id,
                     );
                 }
             }
@@ -2462,6 +2713,7 @@
                         &mut method_names,
                         result,
                         self,
+                        discovered_id,
                     );
                 }
             }
@@ -2470,42 +2722,42 @@
         // NB: We can't use to_rust_ty here since for opaque types this tries to
         // use the specialization knowledge to generate a blob field.
         let ty_for_impl = quote! {
-            #canonical_ident #generics
+            #canonical_ident #impl_generics_params
         };
 
         if needs_clone_impl {
             result.push(quote! {
-                impl #generics Clone for #ty_for_impl {
+                impl #impl_generics_labels Clone for #ty_for_impl {
                     fn clone(&self) -> Self { *self }
                 }
             });
         }
 
+        if needs_flexarray_impl {
+            result.push(self.generate_flexarray(
+                ctx,
+                &canonical_ident,
+                flex_inner_ty.as_ref(),
+                &generic_param_names,
+                &impl_generics_labels,
+            ));
+        }
+
         if needs_default_impl {
             let prefix = ctx.trait_prefix();
-            let body = if ctx.options().rust_features().maybe_uninit {
-                quote! {
-                    let mut s = ::#prefix::mem::MaybeUninit::<Self>::uninit();
-                    unsafe {
-                        ::#prefix::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
-                        s.assume_init()
-                    }
+            let body = quote! {
+                let mut s = ::#prefix::mem::MaybeUninit::<Self>::uninit();
+                unsafe {
+                    ::#prefix::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
+                    s.assume_init()
                 }
-            } else {
-                quote! {
-                    unsafe {
-                        let mut s: Self = ::#prefix::mem::uninitialized();
-                        ::#prefix::ptr::write_bytes(&mut s, 0, 1);
-                        s
-                    }
-                }
             };
             // Note we use `ptr::write_bytes()` instead of `mem::zeroed()` because the latter does
             // not necessarily ensure padding bytes are zeroed. Some C libraries are sensitive to
-            // non-zero padding bytes, especially when forwards/backwards compatability is
+            // non-zero padding bytes, especially when forwards/backwards compatibility is
             // involved.
             result.push(quote! {
-                impl #generics Default for #ty_for_impl {
+                impl #impl_generics_labels Default for #ty_for_impl {
                     fn default() -> Self {
                         #body
                     }
@@ -2524,7 +2776,7 @@
             let prefix = ctx.trait_prefix();
 
             result.push(quote! {
-                impl #generics ::#prefix::fmt::Debug for #ty_for_impl {
+                impl #impl_generics_labels ::#prefix::fmt::Debug for #ty_for_impl {
                     #impl_
                 }
             });
@@ -2537,18 +2789,18 @@
                 item,
                 &ty_for_impl,
             ) {
-                let partialeq_bounds = if !generic_param_names.is_empty() {
+                let partialeq_bounds = if generic_param_names.is_empty() {
+                    quote! {}
+                } else {
                     let bounds = generic_param_names.iter().map(|t| {
                         quote! { #t: PartialEq }
                     });
                     quote! { where #( #bounds ),* }
-                } else {
-                    quote! {}
                 };
 
                 let prefix = ctx.trait_prefix();
                 result.push(quote! {
-                    impl #generics ::#prefix::cmp::PartialEq for #ty_for_impl #partialeq_bounds {
+                    impl #impl_generics_labels ::#prefix::cmp::PartialEq for #ty_for_impl #partialeq_bounds {
                         #impl_
                     }
                 });
@@ -2557,7 +2809,7 @@
 
         if !methods.is_empty() {
             result.push(quote! {
-                impl #generics #ty_for_impl {
+                impl #impl_generics_labels #ty_for_impl {
                     #( #methods )*
                 }
             });
@@ -2565,6 +2817,142 @@
     }
 }
 
+impl CompInfo {
+    fn generate_flexarray(
+        &self,
+        ctx: &BindgenContext,
+        canonical_ident: &Ident,
+        flex_inner_ty: Option<&proc_macro2::TokenStream>,
+        generic_param_names: &[Ident],
+        impl_generics_labels: &proc_macro2::TokenStream,
+    ) -> proc_macro2::TokenStream {
+        let prefix = ctx.trait_prefix();
+
+        let flex_array = flex_inner_ty.as_ref().map(|ty| quote! { [ #ty ] });
+
+        let dst_ty_for_impl = quote! {
+            #canonical_ident < #( #generic_param_names , )* #flex_array >
+
+        };
+        let sized_ty_for_impl = quote! {
+            #canonical_ident < #( #generic_param_names , )* [ #flex_inner_ty; 0 ] >
+        };
+
+        let layout = if ctx.options().rust_features().layout_for_ptr {
+            quote! {
+                pub fn layout(len: usize) -> ::#prefix::alloc::Layout {
+                    // SAFETY: Null pointers are OK if we don't deref them
+                    unsafe {
+                        let p: *const Self = ::#prefix::ptr::from_raw_parts(::#prefix::ptr::null::<()>(), len);
+                        ::#prefix::alloc::Layout::for_value_raw(p)
+                    }
+                }
+            }
+        } else {
+            quote!()
+        };
+
+        let (from_ptr_dst, from_ptr_sized) = if ctx
+            .options()
+            .rust_features()
+            .ptr_metadata
+        {
+            let flex_ref_inner = ctx.wrap_unsafe_ops(quote! {
+                Self::flex_ptr(self, len)
+            });
+            let flex_ref_mut_inner = ctx.wrap_unsafe_ops(quote! {
+                Self::flex_ptr_mut(self, len).assume_init()
+            });
+            let flex_ptr_inner = ctx.wrap_unsafe_ops(quote! {
+                &*::#prefix::ptr::from_raw_parts(ptr as *const (), len)
+            });
+            let flex_ptr_mut_inner = ctx.wrap_unsafe_ops(quote! {
+                // Initialize reference without ever exposing it, as its possibly uninitialized
+                let mut uninit = ::#prefix::mem::MaybeUninit::<&mut #dst_ty_for_impl>::uninit();
+                (uninit.as_mut_ptr() as *mut *mut #dst_ty_for_impl)
+                    .write(::#prefix::ptr::from_raw_parts_mut(ptr as *mut (), len));
+
+                uninit
+            });
+
+            (
+                quote! {
+                    #[inline]
+                    pub fn fixed(&self) -> (& #sized_ty_for_impl, usize) {
+                        unsafe {
+                            let (ptr, len) = (self as *const Self).to_raw_parts();
+                            (&*(ptr as *const #sized_ty_for_impl), len)
+                        }
+                    }
+
+                    #[inline]
+                    pub fn fixed_mut(&mut self) -> (&mut #sized_ty_for_impl, usize) {
+                        unsafe {
+                            let (ptr, len) = (self as *mut Self).to_raw_parts();
+                            (&mut *(ptr as *mut #sized_ty_for_impl), len)
+                        }
+                    }
+                },
+                quote! {
+                    /// Convert a sized prefix to an unsized structure with the given length.
+                    ///
+                    /// SAFETY: Underlying storage is initialized up to at least `len` elements.
+                    pub unsafe fn flex_ref(&self, len: usize) -> &#dst_ty_for_impl {
+                        // SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
+                        #flex_ref_inner
+                    }
+
+                    /// Convert a mutable sized prefix to an unsized structure with the given length.
+                    ///
+                    /// SAFETY: Underlying storage is initialized up to at least `len` elements.
+                    #[inline]
+                    pub unsafe fn flex_ref_mut(&mut self, len: usize) -> &mut #dst_ty_for_impl {
+                        // SAFETY: Reference is always valid as pointer. Caller is guaranteeing `len`.
+                        #flex_ref_mut_inner
+                    }
+
+                    /// Construct DST variant from a pointer and a size.
+                    ///
+                    /// NOTE: lifetime of returned reference is not tied to any underlying storage.
+                    /// SAFETY: `ptr` is valid. Underlying storage is fully initialized up to at least `len` elements.
+                    #[inline]
+                    pub unsafe fn flex_ptr<'unbounded>(ptr: *const Self, len: usize) -> &'unbounded #dst_ty_for_impl {
+                       #flex_ptr_inner
+                    }
+
+                    /// Construct mutable DST variant from a pointer and a
+                    /// size. The returned `&mut` reference is initialized
+                    /// pointing to memory referenced by `ptr`, but there's
+                    /// no requirement that that memory be initialized.
+                    ///
+                    /// NOTE: lifetime of returned reference is not tied to any underlying storage.
+                    /// SAFETY: `ptr` is valid. Underlying storage has space for at least `len` elements.
+                    #[inline]
+                    pub unsafe fn flex_ptr_mut<'unbounded>(
+                        ptr: *mut Self,
+                        len: usize,
+                    ) -> ::#prefix::mem::MaybeUninit<&'unbounded mut #dst_ty_for_impl> {
+                        #flex_ptr_mut_inner
+                    }
+                },
+            )
+        } else {
+            (quote!(), quote!())
+        };
+
+        quote! {
+            impl #impl_generics_labels #dst_ty_for_impl {
+                #layout
+                #from_ptr_dst
+            }
+
+            impl #impl_generics_labels #sized_ty_for_impl {
+                #from_ptr_sized
+            }
+        }
+    }
+}
+
 impl Method {
     fn codegen_method(
         &self,
@@ -2573,12 +2961,13 @@
         method_names: &mut HashSet<String>,
         result: &mut CodegenResult<'_>,
         _parent: &CompInfo,
+        parent_id: DiscoveredItemId,
     ) {
         assert!({
             let cc = &ctx.options().codegen_config;
             match self.kind() {
                 MethodKind::Constructor => cc.constructors(),
-                MethodKind::Destructor => cc.destructors(),
+                MethodKind::Destructor |
                 MethodKind::VirtualDestructor { .. } => cc.destructors(),
                 MethodKind::Static |
                 MethodKind::Normal |
@@ -2598,10 +2987,7 @@
         }
         let function = function_item.expect_function();
         let times_seen = function.codegen(ctx, result, function_item);
-        let times_seen = match times_seen {
-            Some(seen) => seen,
-            None => return,
-        };
+        let Some(times_seen) = times_seen else { return };
         let signature_item = ctx.resolve_item(function.signature());
         let mut name = match self.kind() {
             MethodKind::Constructor => "new".into(),
@@ -2609,9 +2995,10 @@
             _ => function.name().to_owned(),
         };
 
-        let signature = match *signature_item.expect_type().kind() {
-            TypeKind::Function(ref sig) => sig,
-            _ => panic!("How in the world?"),
+        let TypeKind::Function(ref signature) =
+            *signature_item.expect_type().kind()
+        else {
+            panic!("How in the world?")
         };
 
         let supported_abi = signature.abi(ctx, Some(&*name)).is_ok();
@@ -2630,7 +3017,7 @@
             let mut new_name;
 
             while {
-                new_name = format!("{}{}", name, count);
+                new_name = format!("{name}{count}");
                 method_names.contains(&new_name)
             } {
                 count += 1;
@@ -2641,9 +3028,16 @@
 
         method_names.insert(name.clone());
 
+        utils::call_discovered_item_callback(ctx, function_item, || {
+            DiscoveredItem::Method {
+                parent: parent_id,
+                final_name: name.clone(),
+            }
+        });
+
         let mut function_name = function_item.canonical_name(ctx);
         if times_seen > 0 {
-            write!(&mut function_name, "{}", times_seen).unwrap();
+            write!(&mut function_name, "{times_seen}").unwrap();
         }
         let function_name = ctx.rust_ident(function_name);
         let mut args = utils::fnsig_arguments(ctx, signature);
@@ -2676,32 +3070,19 @@
         // variable called `__bindgen_tmp` we're going to create.
         if self.is_constructor() {
             let prefix = ctx.trait_prefix();
-            let tmp_variable_decl = if ctx
-                .options()
-                .rust_features()
-                .maybe_uninit
-            {
-                exprs[0] = quote! {
-                    __bindgen_tmp.as_mut_ptr()
-                };
-                quote! {
-                    let mut __bindgen_tmp = ::#prefix::mem::MaybeUninit::uninit()
-                }
-            } else {
-                exprs[0] = quote! {
-                    &mut __bindgen_tmp
-                };
-                quote! {
-                    let mut __bindgen_tmp = ::#prefix::mem::uninitialized()
-                }
+            exprs[0] = quote! {
+                __bindgen_tmp.as_mut_ptr()
             };
+            let tmp_variable_decl = quote! {
+                let mut __bindgen_tmp = ::#prefix::mem::MaybeUninit::uninit()
+            };
             stmts.push(tmp_variable_decl);
         } else if !self.is_static() {
             assert!(!exprs.is_empty());
             exprs[0] = quote! {
                 self
             };
-        };
+        }
 
         let call = quote! {
             #function_name (#( #exprs ),* )
@@ -2710,24 +3091,16 @@
         stmts.push(call);
 
         if self.is_constructor() {
-            stmts.push(if ctx.options().rust_features().maybe_uninit {
-                quote! {
+            stmts.push(quote! {
                     __bindgen_tmp.assume_init()
-                }
-            } else {
-                quote! {
-                    __bindgen_tmp
-                }
-            })
+            });
         }
 
         let block = ctx.wrap_unsafe_ops(quote! ( #( #stmts );*));
 
         let mut attrs = vec![attributes::inline()];
 
-        if signature.must_use() &&
-            ctx.options().rust_features().must_use_function
-        {
+        if signature.must_use() {
             attrs.push(attributes::must_use());
         }
 
@@ -2742,11 +3115,11 @@
 }
 
 /// A helper type that represents different enum variations.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
 pub enum EnumVariation {
     /// The code for this enum will use a Rust enum. Note that creating this in unsafe code
     /// (including FFI) with an invalid value will invoke undefined behaviour, whether or not
-    /// its marked as non_exhaustive.
+    /// its marked as `#[non_exhaustive]`.
     Rust {
         /// Indicates whether the generated struct should be `#[non_exhaustive]`
         non_exhaustive: bool,
@@ -2759,29 +3132,24 @@
         is_global: bool,
     },
     /// The code for this enum will use consts
+    #[default]
     Consts,
     /// The code for this enum will use a module containing consts
     ModuleConsts,
 }
 
 impl EnumVariation {
-    fn is_rust(&self) -> bool {
-        matches!(*self, EnumVariation::Rust { .. })
+    fn is_rust(self) -> bool {
+        matches!(self, EnumVariation::Rust { .. })
     }
 
     /// Both the `Const` and `ModuleConsts` variants will cause this to return
     /// true.
-    fn is_const(&self) -> bool {
-        matches!(*self, EnumVariation::Consts | EnumVariation::ModuleConsts)
+    fn is_const(self) -> bool {
+        matches!(self, EnumVariation::Consts | EnumVariation::ModuleConsts)
     }
 }
 
-impl Default for EnumVariation {
-    fn default() -> EnumVariation {
-        EnumVariation::Consts
-    }
-}
-
 impl fmt::Display for EnumVariation {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let s = match self {
@@ -2811,7 +3179,7 @@
     }
 }
 
-impl std::str::FromStr for EnumVariation {
+impl FromStr for EnumVariation {
     type Err = std::io::Error;
 
     /// Create a `EnumVariation` from a string.
@@ -2849,313 +3217,355 @@
     }
 }
 
+struct EnumBuilder {
+    /// Type identifier of the enum.
+    ///
+    /// This is the base name, i.e. for `ModuleConst` enums, this does not include the module name.
+    enum_type: Ident,
+    /// Attributes applying to the enum type
+    attrs: Vec<proc_macro2::TokenStream>,
+    /// The representation of the enum, e.g. `u32`.
+    repr: syn::Type,
+    /// The enum kind we are generating
+    kind: EnumBuilderKind,
+    /// A list of all variants this enum has.
+    enum_variants: Vec<EnumVariantInfo>,
+}
+
 /// A helper type to construct different enum variations.
-enum EnumBuilder<'a> {
+enum EnumBuilderKind {
     Rust {
-        attrs: Vec<proc_macro2::TokenStream>,
-        ident: Ident,
-        tokens: proc_macro2::TokenStream,
-        emitted_any_variants: bool,
+        non_exhaustive: bool,
     },
     NewType {
-        canonical_name: &'a str,
-        tokens: proc_macro2::TokenStream,
         is_bitfield: bool,
         is_global: bool,
+        /// if the enum is named or not.
+        is_anonymous: bool,
     },
     Consts {
-        variants: Vec<proc_macro2::TokenStream>,
+        needs_typedef: bool,
     },
     ModuleConsts {
-        module_name: &'a str,
-        module_items: Vec<proc_macro2::TokenStream>,
+        module_name: Ident,
     },
 }
 
-impl<'a> EnumBuilder<'a> {
+impl EnumBuilder {
     /// Returns true if the builder is for a rustified enum.
     fn is_rust_enum(&self) -> bool {
-        matches!(*self, EnumBuilder::Rust { .. })
+        matches!(self.kind, EnumBuilderKind::Rust { .. })
     }
 
     /// Create a new enum given an item builder, a canonical name, a name for
     /// the representation, and which variation it should be generated as.
     fn new(
-        name: &'a str,
-        mut attrs: Vec<proc_macro2::TokenStream>,
-        repr: syn::Type,
+        name: &str,
+        attrs: Vec<proc_macro2::TokenStream>,
+        repr: &syn::Type,
         enum_variation: EnumVariation,
         has_typedef: bool,
+        enum_is_anonymous: bool,
     ) -> Self {
         let ident = Ident::new(name, Span::call_site());
+        // For most variants this is the same
+        let mut enum_ty = ident.clone();
 
-        match enum_variation {
+        let kind = match enum_variation {
             EnumVariation::NewType {
                 is_bitfield,
                 is_global,
-            } => EnumBuilder::NewType {
-                canonical_name: name,
-                tokens: quote! {
-                    #( #attrs )*
-                    pub struct #ident (pub #repr);
-                },
+            } => EnumBuilderKind::NewType {
                 is_bitfield,
                 is_global,
+                is_anonymous: enum_is_anonymous,
             },
 
-            EnumVariation::Rust { .. } => {
-                // `repr` is guaranteed to be Rustified in Enum::codegen
-                attrs.insert(0, quote! { #[repr( #repr )] });
-                let tokens = quote!();
-                EnumBuilder::Rust {
-                    attrs,
-                    ident,
-                    tokens,
-                    emitted_any_variants: false,
-                }
+            EnumVariation::Rust { non_exhaustive } => {
+                EnumBuilderKind::Rust { non_exhaustive }
             }
 
-            EnumVariation::Consts => {
-                let mut variants = Vec::new();
+            EnumVariation::Consts => EnumBuilderKind::Consts {
+                needs_typedef: !has_typedef,
+            },
 
-                if !has_typedef {
-                    variants.push(quote! {
-                        #( #attrs )*
-                        pub type #ident = #repr;
-                    });
-                }
-
-                EnumBuilder::Consts { variants }
-            }
-
             EnumVariation::ModuleConsts => {
-                let ident = Ident::new(
+                enum_ty = Ident::new(
                     CONSTIFIED_ENUM_MODULE_REPR_NAME,
                     Span::call_site(),
                 );
-                let type_definition = quote! {
-                    #( #attrs )*
-                    pub type #ident = #repr;
-                };
 
-                EnumBuilder::ModuleConsts {
-                    module_name: name,
-                    module_items: vec![type_definition],
+                EnumBuilderKind::ModuleConsts {
+                    module_name: ident.clone(),
                 }
             }
+        };
+        EnumBuilder {
+            enum_type: enum_ty,
+            attrs,
+            repr: repr.clone(),
+            kind,
+            enum_variants: vec![],
         }
     }
 
     /// Add a variant to this enum.
     fn with_variant(
-        self,
+        mut self,
         ctx: &BindgenContext,
         variant: &EnumVariant,
+        variant_doc: proc_macro2::TokenStream,
         mangling_prefix: Option<&str>,
-        rust_ty: syn::Type,
-        result: &mut CodegenResult<'_>,
+        rust_ty: &syn::Type,
         is_ty_named: bool,
     ) -> Self {
         let variant_name = ctx.rust_mangle(variant.name());
         let is_rust_enum = self.is_rust_enum();
         let expr = match variant.val() {
             EnumVariantValue::Boolean(v) if is_rust_enum => {
-                helpers::ast_ty::uint_expr(v as u64)
+                helpers::ast_ty::uint_expr(u64::from(v))
             }
             EnumVariantValue::Boolean(v) => quote!(#v),
             EnumVariantValue::Signed(v) => helpers::ast_ty::int_expr(v),
             EnumVariantValue::Unsigned(v) => helpers::ast_ty::uint_expr(v),
         };
 
-        let mut doc = quote! {};
-        if ctx.options().generate_comments {
-            if let Some(raw_comment) = variant.comment() {
-                let comment = ctx.options().process_comment(raw_comment);
-                doc = attributes::doc(comment);
-            }
-        }
-
-        match self {
-            EnumBuilder::Rust {
-                attrs,
-                ident,
-                tokens,
-                emitted_any_variants: _,
-            } => {
+        match self.kind {
+            EnumBuilderKind::Rust { .. } => {
                 let name = ctx.rust_ident(variant_name);
-                EnumBuilder::Rust {
-                    attrs,
-                    ident,
-                    tokens: quote! {
-                        #tokens
-                        #doc
-                        #name = #expr,
-                    },
-                    emitted_any_variants: true,
-                }
+                self.enum_variants.push(EnumVariantInfo {
+                    variant_name: name,
+                    variant_doc,
+                    value: expr,
+                });
+                self
             }
 
-            EnumBuilder::NewType {
-                canonical_name,
-                is_global,
-                ..
-            } => {
-                if ctx.options().rust_features().associated_const &&
-                    is_ty_named &&
-                    !is_global
-                {
-                    let enum_ident = ctx.rust_ident(canonical_name);
-                    let variant_ident = ctx.rust_ident(variant_name);
-
-                    result.push(quote! {
-                        impl #enum_ident {
-                            #doc
-                            pub const #variant_ident : #rust_ty = #rust_ty ( #expr );
-                        }
-                    });
+            EnumBuilderKind::NewType { is_global, .. } => {
+                let variant_ident = if is_ty_named && !is_global {
+                    ctx.rust_ident(variant_name)
                 } else {
-                    let ident = ctx.rust_ident(match mangling_prefix {
+                    ctx.rust_ident(match mangling_prefix {
                         Some(prefix) => {
-                            Cow::Owned(format!("{}_{}", prefix, variant_name))
+                            Cow::Owned(format!("{prefix}_{variant_name}"))
                         }
                         None => variant_name,
-                    });
-                    result.push(quote! {
-                        #doc
-                        pub const #ident : #rust_ty = #rust_ty ( #expr );
-                    });
-                }
+                    })
+                };
+                self.enum_variants.push(EnumVariantInfo {
+                    variant_name: variant_ident,
+                    variant_doc,
+                    value: quote! { #rust_ty ( #expr )},
+                });
 
                 self
             }
 
-            EnumBuilder::Consts { .. } => {
+            EnumBuilderKind::Consts { .. } => {
                 let constant_name = match mangling_prefix {
                     Some(prefix) => {
-                        Cow::Owned(format!("{}_{}", prefix, variant_name))
+                        Cow::Owned(format!("{prefix}_{variant_name}"))
                     }
                     None => variant_name,
                 };
 
                 let ident = ctx.rust_ident(constant_name);
-                result.push(quote! {
-                    #doc
-                    pub const #ident : #rust_ty = #expr ;
+                self.enum_variants.push(EnumVariantInfo {
+                    variant_name: ident,
+                    variant_doc,
+                    value: quote! { #expr },
                 });
 
                 self
             }
-            EnumBuilder::ModuleConsts {
-                module_name,
-                mut module_items,
-            } => {
+            EnumBuilderKind::ModuleConsts { .. } => {
                 let name = ctx.rust_ident(variant_name);
-                let ty = ctx.rust_ident(CONSTIFIED_ENUM_MODULE_REPR_NAME);
-                module_items.push(quote! {
-                    #doc
-                    pub const #name : #ty = #expr ;
+                self.enum_variants.push(EnumVariantInfo {
+                    variant_name: name,
+                    variant_doc,
+                    value: quote! { #expr },
                 });
+                self
+            }
+        }
+    }
 
-                EnumBuilder::ModuleConsts {
-                    module_name,
-                    module_items,
+    fn newtype_bitfield_impl(
+        prefix: &Ident,
+        rust_ty: &syn::Type,
+    ) -> proc_macro2::TokenStream {
+        let rust_ty_name = &rust_ty;
+        quote! {
+            impl ::#prefix::ops::BitOr<#rust_ty> for #rust_ty {
+                type Output = Self;
+
+                #[inline]
+                fn bitor(self, other: Self) -> Self {
+                    #rust_ty_name(self.0 | other.0)
                 }
             }
+            impl ::#prefix::ops::BitOrAssign for #rust_ty {
+                #[inline]
+                fn bitor_assign(&mut self, rhs: #rust_ty) {
+                    self.0 |= rhs.0;
+                }
+            }
+            impl ::#prefix::ops::BitAnd<#rust_ty> for #rust_ty {
+                type Output = Self;
+
+                #[inline]
+                fn bitand(self, other: Self) -> Self {
+                    #rust_ty_name(self.0 & other.0)
+                }
+            }
+            impl ::#prefix::ops::BitAndAssign for #rust_ty {
+                #[inline]
+                fn bitand_assign(&mut self, rhs: #rust_ty) {
+                    self.0 &= rhs.0;
+                }
+            }
         }
     }
 
     fn build(
         self,
         ctx: &BindgenContext,
-        rust_ty: syn::Type,
-        result: &mut CodegenResult<'_>,
+        rust_ty: &syn::Type,
     ) -> proc_macro2::TokenStream {
-        match self {
-            EnumBuilder::Rust {
-                attrs,
-                ident,
-                tokens,
-                emitted_any_variants,
-                ..
-            } => {
-                let variants = if !emitted_any_variants {
-                    quote!(__bindgen_cannot_repr_c_on_empty_enum = 0)
-                } else {
-                    tokens
-                };
+        let enum_ident = self.enum_type;
 
+        // 1. Construct a list of the enum variants
+        let variants = match self.kind {
+            EnumBuilderKind::Rust { .. } => {
+                let mut variants = vec![];
+
+                for v in self.enum_variants {
+                    let variant_doc = &v.variant_doc;
+                    let variant_ident = &v.variant_name;
+                    let variant_value = &v.value;
+
+                    variants.push(quote! {
+                        #variant_doc
+                        #variant_ident = #variant_value,
+                    });
+                }
+
+                if variants.is_empty() {
+                    variants.push(
+                        quote! {__bindgen_cannot_repr_c_on_empty_enum = 0,},
+                    );
+                }
+                variants
+            }
+            EnumBuilderKind::NewType { .. } => {
+                let mut variants = vec![];
+
+                for v in self.enum_variants {
+                    let variant_doc = &v.variant_doc;
+                    let variant_ident = &v.variant_name;
+                    let variant_value = &v.value;
+
+                    variants.push(quote! {
+                        #variant_doc
+                        pub const #variant_ident: #enum_ident = #variant_value;
+                    });
+                }
+                variants
+            }
+            EnumBuilderKind::Consts { .. } |
+            EnumBuilderKind::ModuleConsts { .. } => {
+                let mut variants = vec![];
+
+                for v in self.enum_variants {
+                    let variant_doc = &v.variant_doc;
+                    let variant_ident = &v.variant_name;
+                    let variant_value = &v.value;
+
+                    variants.push(quote! {
+                        #variant_doc
+                        pub const #variant_ident: #enum_ident = #variant_value;
+                    });
+                }
+                variants
+            }
+        };
+        let attrs = self.attrs;
+        let enum_repr = &self.repr;
+
+        // 2. Generate the enum representation
+        match self.kind {
+            EnumBuilderKind::Rust { non_exhaustive } => {
+                let non_exhaustive_opt =
+                    non_exhaustive.then(attributes::non_exhaustive);
+
                 quote! {
+                    // Note: repr is on top of attrs to keep the test expectations diff small.
+                    // a future commit could move it further down.
+                    #[repr(#enum_repr)]
+                    #non_exhaustive_opt
                     #( #attrs )*
-                    pub enum #ident {
-                        #variants
+                    pub enum #enum_ident {
+                        #( #variants )*
                     }
                 }
             }
-            EnumBuilder::NewType {
-                canonical_name,
-                tokens,
+            EnumBuilderKind::NewType {
                 is_bitfield,
-                ..
+                is_global,
+                is_anonymous,
             } => {
-                if !is_bitfield {
-                    return tokens;
-                }
-
-                let rust_ty_name = ctx.rust_ident_raw(canonical_name);
-                let prefix = ctx.trait_prefix();
-
-                result.push(quote! {
-                    impl ::#prefix::ops::BitOr<#rust_ty> for #rust_ty {
-                        type Output = Self;
-
-                        #[inline]
-                        fn bitor(self, other: Self) -> Self {
-                            #rust_ty_name(self.0 | other.0)
-                        }
+                // There doesn't seem to be a technical reason why we generate
+                // anon enum variants as global constants.
+                // We keep this behavior to avoid breaking changes in the bindings.
+                let impl_variants = if is_anonymous || is_global {
+                    quote! {
+                        #( #variants )*
                     }
-                });
-
-                result.push(quote! {
-                    impl ::#prefix::ops::BitOrAssign for #rust_ty {
-                        #[inline]
-                        fn bitor_assign(&mut self, rhs: #rust_ty) {
-                            self.0 |= rhs.0;
+                } else {
+                    quote! {
+                        impl #enum_ident {
+                            #( #variants )*
                         }
                     }
-                });
+                };
 
-                result.push(quote! {
-                    impl ::#prefix::ops::BitAnd<#rust_ty> for #rust_ty {
-                        type Output = Self;
+                let prefix = ctx.trait_prefix();
+                let bitfield_impl_opt = is_bitfield
+                    .then(|| Self::newtype_bitfield_impl(&prefix, rust_ty));
 
-                        #[inline]
-                        fn bitand(self, other: Self) -> Self {
-                            #rust_ty_name(self.0 & other.0)
-                        }
-                    }
-                });
+                quote! {
+                    // Previously variant impls where before the enum definition.
+                    // lets keep this as is for now, to reduce the diff in generated bindings.
+                    #impl_variants
 
-                result.push(quote! {
-                    impl ::#prefix::ops::BitAndAssign for #rust_ty {
-                        #[inline]
-                        fn bitand_assign(&mut self, rhs: #rust_ty) {
-                            self.0 &= rhs.0;
-                        }
+                    #bitfield_impl_opt
+
+                    #[repr(transparent)]
+                    #( #attrs )*
+                    pub struct #enum_ident (pub #enum_repr);
+                }
+            }
+            EnumBuilderKind::Consts { needs_typedef } => {
+                let typedef_opt = needs_typedef.then(|| {
+                    quote! {
+                        #( #attrs )*
+                        pub type #enum_ident = #enum_repr;
                     }
                 });
+                quote! {
+                    #( #variants )*
 
-                tokens
+                    #typedef_opt
+                }
             }
-            EnumBuilder::Consts { variants, .. } => quote! { #( #variants )* },
-            EnumBuilder::ModuleConsts {
-                module_items,
-                module_name,
-                ..
-            } => {
-                let ident = ctx.rust_ident(module_name);
+            EnumBuilderKind::ModuleConsts { module_name, .. } => {
                 quote! {
-                    pub mod #ident {
-                        #( #module_items )*
+                    // todo: Probably some attributes, e.g. `cfg` should apply to the `mod`.
+                    pub mod #module_name {
+                        #( #attrs )*
+                        pub type #enum_ident = #enum_repr;
+
+                        #( #variants )*
                     }
                 }
             }
@@ -3173,7 +3583,7 @@
         result: &mut CodegenResult<'_>,
         item: &Item,
     ) {
-        debug!("<Enum as CodeGenerator>::codegen: item = {:?}", item);
+        debug!("<Enum as CodeGenerator>::codegen: item = {item:?}");
         debug_assert!(item.is_enabled_for_codegen(ctx));
 
         let name = item.canonical_name(ctx);
@@ -3198,18 +3608,17 @@
                 // * the representation couldn't be determined from the C source
                 // * it was explicitly requested as a bindgen option
 
-                let kind = match repr {
-                    Some(repr) => match *repr.canonical_type(ctx).kind() {
+                let kind = if let Some(repr) = repr {
+                    match *repr.canonical_type(ctx).kind() {
                         TypeKind::Int(int_kind) => int_kind,
                         _ => panic!("Unexpected type as enum repr"),
-                    },
-                    None => {
-                        warn!(
-                            "Guessing type of enum! Forward declarations of enums \
-                             shouldn't be legal!"
-                        );
-                        IntKind::Int
                     }
+                } else {
+                    warn!(
+                        "Guessing type of enum! Forward declarations of enums \
+                         shouldn't be legal!"
+                    );
+                    IntKind::Int
                 };
 
                 let signed = kind.is_signed();
@@ -3229,8 +3638,7 @@
                     (false, 8) => IntKind::U64,
                     _ => {
                         warn!(
-                            "invalid enum decl: signed: {}, size: {}",
-                            signed, size
+                            "invalid enum decl: signed: {signed}, size: {size}"
                         );
                         IntKind::I32
                     }
@@ -3244,31 +3652,8 @@
 
         let mut attrs = vec![];
 
-        // TODO(emilio): Delegate this to the builders?
-        match variation {
-            EnumVariation::Rust { non_exhaustive } => {
-                if non_exhaustive &&
-                    ctx.options().rust_features().non_exhaustive
-                {
-                    attrs.push(attributes::non_exhaustive());
-                } else if non_exhaustive &&
-                    !ctx.options().rust_features().non_exhaustive
-                {
-                    panic!("The rust target you're using doesn't seem to support non_exhaustive enums");
-                }
-            }
-            EnumVariation::NewType { .. } => {
-                if ctx.options().rust_features.repr_transparent {
-                    attrs.push(attributes::repr("transparent"));
-                } else {
-                    attrs.push(attributes::repr("C"));
-                }
-            }
-            _ => {}
-        };
-
         if let Some(comment) = item.comment(ctx) {
-            attrs.push(attributes::doc(comment));
+            attrs.push(attributes::doc(&comment));
         }
 
         if item.must_use(ctx) {
@@ -3288,7 +3673,7 @@
                     DerivableTraits::EQ,
             );
             let mut derives: Vec<_> = derives.into();
-            for derive in item.annotations().derives().iter() {
+            for derive in item.annotations().derives() {
                 if !derives.contains(&derive.as_str()) {
                     derives.push(derive);
                 }
@@ -3305,6 +3690,23 @@
             // In most cases this will be a no-op, since custom_derives will be empty.
             derives.extend(custom_derives.iter().map(|s| s.as_str()));
 
+            attrs.extend(
+                item.annotations()
+                    .attributes()
+                    .iter()
+                    .map(|s| s.parse().unwrap()),
+            );
+
+            // The custom attribute callback may return a list of attributes;
+            // add them to the end of the list.
+            let custom_attributes = ctx.options().all_callbacks(|cb| {
+                cb.add_attributes(&AttributeInfo {
+                    name: &name,
+                    kind: DeriveTypeKind::Enum,
+                })
+            });
+            attrs.extend(custom_attributes.iter().map(|s| s.parse().unwrap()));
+
             attrs.push(attributes::derives(&derives));
         }
 
@@ -3318,17 +3720,17 @@
             // value.
             variant_name: &Ident,
             referenced_name: &Ident,
-            enum_rust_ty: syn::Type,
+            enum_rust_ty: &syn::Type,
             result: &mut CodegenResult<'_>,
         ) {
             let constant_name = if enum_.name().is_some() {
                 if ctx.options().prepend_enum_name {
-                    format!("{}_{}", enum_canonical_name, variant_name)
+                    format!("{enum_canonical_name}_{variant_name}")
                 } else {
-                    format!("{}", variant_name)
+                    format!("{variant_name}")
                 }
             } else {
-                format!("{}", variant_name)
+                format!("{variant_name}")
             };
             let constant_name = ctx.rust_ident(constant_name);
 
@@ -3341,9 +3743,21 @@
         let repr = repr.to_rust_ty_or_opaque(ctx, item);
         let has_typedef = ctx.is_enum_typedef_combo(item.id());
 
-        let mut builder =
-            EnumBuilder::new(&name, attrs, repr, variation, has_typedef);
+        utils::call_discovered_item_callback(ctx, item, || {
+            DiscoveredItem::Enum {
+                final_name: name.clone(),
+            }
+        });
 
+        let mut builder = EnumBuilder::new(
+            &name,
+            attrs,
+            &repr,
+            variation,
+            has_typedef,
+            enum_ty.name().is_none(),
+        );
+
         // A map where we keep a value -> variant relation.
         let mut seen_values = HashMap::<_, Ident>::default();
         let enum_rust_ty = item.to_rust_ty_or_opaque(ctx, &());
@@ -3384,28 +3798,33 @@
                 continue;
             }
 
+            let mut variant_doc = quote! {};
+            if ctx.options().generate_comments {
+                if let Some(raw_comment) = variant.comment() {
+                    let processed_comment =
+                        ctx.options().process_comment(raw_comment);
+                    variant_doc = attributes::doc(&processed_comment);
+                }
+            }
+
             match seen_values.entry(variant.val()) {
                 Entry::Occupied(ref entry) => {
                     if variation.is_rust() {
                         let variant_name = ctx.rust_mangle(variant.name());
-                        let mangled_name =
-                            if is_toplevel || enum_ty.name().is_some() {
-                                variant_name
-                            } else {
-                                let parent_name =
-                                    parent_canonical_name.as_ref().unwrap();
+                        let mangled_name = if is_toplevel ||
+                            enum_ty.name().is_some()
+                        {
+                            variant_name
+                        } else {
+                            let parent_name =
+                                parent_canonical_name.as_ref().unwrap();
 
-                                Cow::Owned(format!(
-                                    "{}_{}",
-                                    parent_name, variant_name
-                                ))
-                            };
+                            Cow::Owned(format!("{parent_name}_{variant_name}"))
+                        };
 
                         let existing_variant_name = entry.get();
                         // Use associated constants for named enums.
-                        if enum_ty.name().is_some() &&
-                            ctx.options().rust_features().associated_const
-                        {
+                        if enum_ty.name().is_some() {
                             let enum_canonical_name = &ident;
                             let variant_name =
                                 ctx.rust_ident_raw(&*mangled_name);
@@ -3422,7 +3841,7 @@
                                 &ident,
                                 &Ident::new(&mangled_name, Span::call_site()),
                                 existing_variant_name,
-                                enum_rust_ty.clone(),
+                                &enum_rust_ty,
                                 result,
                             );
                         }
@@ -3430,9 +3849,9 @@
                         builder = builder.with_variant(
                             ctx,
                             variant,
+                            variant_doc,
                             constant_mangling_prefix,
-                            enum_rust_ty.clone(),
-                            result,
+                            &enum_rust_ty,
                             enum_ty.name().is_some(),
                         );
                     }
@@ -3441,9 +3860,9 @@
                     builder = builder.with_variant(
                         ctx,
                         variant,
+                        variant_doc,
                         constant_mangling_prefix,
-                        enum_rust_ty.clone(),
-                        result,
+                        &enum_rust_ty,
                         enum_ty.name().is_some(),
                     );
 
@@ -3462,7 +3881,7 @@
                                 parent_canonical_name.as_ref().unwrap();
 
                             Ident::new(
-                                &format!("{}_{}", parent_name, variant_name),
+                                &format!("{parent_name}_{variant_name}"),
                                 Span::call_site(),
                             )
                         };
@@ -3473,7 +3892,7 @@
                             &ident,
                             &mangled_name,
                             &variant_name,
-                            enum_rust_ty.clone(),
+                            &enum_rust_ty,
                             result,
                         );
                     }
@@ -3483,17 +3902,24 @@
             }
         }
 
-        let item = builder.build(ctx, enum_rust_ty, result);
+        let item = builder.build(ctx, &enum_rust_ty);
         result.push(item);
     }
 }
 
+struct EnumVariantInfo {
+    variant_name: Ident,
+    variant_doc: proc_macro2::TokenStream,
+    value: proc_macro2::TokenStream,
+}
+
 /// Enum for the default type of macro constants.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
 pub enum MacroTypeVariation {
     /// Use i32 or i64
     Signed,
     /// Use u32 or u64
+    #[default]
     Unsigned,
 }
 
@@ -3507,13 +3933,7 @@
     }
 }
 
-impl Default for MacroTypeVariation {
-    fn default() -> MacroTypeVariation {
-        MacroTypeVariation::Unsigned
-    }
-}
-
-impl std::str::FromStr for MacroTypeVariation {
+impl FromStr for MacroTypeVariation {
     type Err = std::io::Error;
 
     /// Create a `MacroTypeVariation` from a string.
@@ -3533,13 +3953,14 @@
 }
 
 /// Enum for how aliases should be translated.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
 pub enum AliasVariation {
     /// Convert to regular Rust alias
+    #[default]
     TypeAlias,
     /// Create a new type by wrapping the old type in a struct and using #[repr(transparent)]
     NewType,
-    /// Same as NewStruct but also impl Deref to be able to use the methods of the wrapped type
+    /// Same as `NewType` but also impl Deref to be able to use the methods of the wrapped type
     NewTypeDeref,
 }
 
@@ -3555,13 +3976,7 @@
     }
 }
 
-impl Default for AliasVariation {
-    fn default() -> AliasVariation {
-        AliasVariation::TypeAlias
-    }
-}
-
-impl std::str::FromStr for AliasVariation {
+impl FromStr for AliasVariation {
     type Err = std::io::Error;
 
     /// Create an `AliasVariation` from a string.
@@ -3610,7 +4025,7 @@
     }
 }
 
-impl std::str::FromStr for NonCopyUnionStyle {
+impl FromStr for NonCopyUnionStyle {
     type Err = std::io::Error;
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -3650,7 +4065,7 @@
         extra: &Self::Extra,
     ) -> error::Result<syn::Type> {
         self.try_get_layout(ctx, extra)
-            .map(|layout| helpers::blob(ctx, layout))
+            .map(|layout| helpers::blob(ctx, layout, true))
     }
 }
 
@@ -3676,7 +4091,7 @@
         extra: &Self::Extra,
     ) -> syn::Type {
         let layout = self.get_layout(ctx, extra);
-        helpers::blob(ctx, layout)
+        helpers::blob(ctx, layout, true)
     }
 }
 
@@ -3727,9 +4142,9 @@
     ) -> error::Result<syn::Type> {
         self.try_to_rust_ty(ctx, extra).or_else(|_| {
             if let Ok(layout) = self.try_get_layout(ctx, extra) {
-                Ok(helpers::blob(ctx, layout))
+                Ok(helpers::blob(ctx, layout, true))
             } else {
-                Err(error::Error::NoLayoutForOpaqueBlob)
+                Err(Error::NoLayoutForOpaqueBlob)
             }
         })
     }
@@ -3744,11 +4159,11 @@
 /// ### Fallible vs. Infallible Conversions to Rust Types
 ///
 /// When should one use this infallible `ToRustTyOrOpaque` trait versus the
-/// fallible `TryTo{RustTy, Opaque, RustTyOrOpaque}` triats? All fallible trait
+/// fallible `TryTo{RustTy, Opaque, RustTyOrOpaque}` traits? All fallible trait
 /// implementations that need to convert another thing into a Rust type or
 /// opaque blob in a nested manner should also use fallible trait methods and
 /// propagate failure up the stack. Only infallible functions and methods like
-/// CodeGenerator implementations should use the infallible
+/// `CodeGenerator` implementations should use the infallible
 /// `ToRustTyOrOpaque`. The further out we push error recovery, the more likely
 /// we are to get a usable `Layout` even if we can't generate an equivalent Rust
 /// type for a C++ construct.
@@ -3840,7 +4255,7 @@
         ctx: &BindgenContext,
         _: &Item,
     ) -> error::Result<Layout> {
-        self.layout(ctx).ok_or(error::Error::NoLayoutForOpaqueBlob)
+        self.layout(ctx).ok_or(Error::NoLayoutForOpaqueBlob)
     }
 }
 
@@ -3982,7 +4397,7 @@
                 Ok(syn::parse_quote! { #name })
             }
             ref u @ TypeKind::UnresolvedTypeRef(..) => {
-                unreachable!("Should have been resolved after parsing {:?}!", u)
+                unreachable!("Should have been resolved after parsing {u:?}!")
             }
         }
     }
@@ -3998,7 +4413,7 @@
     ) -> error::Result<Layout> {
         item.expect_type()
             .layout(ctx)
-            .ok_or(error::Error::NoLayoutForOpaqueBlob)
+            .ok_or(Error::NoLayoutForOpaqueBlob)
     }
 }
 
@@ -4011,7 +4426,7 @@
         item: &Item,
     ) -> error::Result<syn::Type> {
         if self.is_opaque(ctx, item) {
-            return Err(error::Error::InstantiationOfOpaqueType);
+            return Err(Error::InstantiationOfOpaqueType);
         }
 
         let def = self
@@ -4033,7 +4448,7 @@
             // template specialization, and we've hit an instantiation of
             // that partial specialization.
             extra_assert!(def.is_opaque(ctx, &()));
-            return Err(error::Error::InstantiationOfOpaqueType);
+            return Err(Error::InstantiationOfOpaqueType);
         }
 
         // TODO: If the definition type is a template class/struct
@@ -4085,7 +4500,7 @@
                 syn::parse_quote! { unsafe extern #abi fn ( #( #arguments ),* ) #ret },
             ),
             Err(err) => {
-                if matches!(err, error::Error::UnsupportedAbi(_)) {
+                if matches!(err, Error::UnsupportedAbi(_)) {
                     unsupported_abi_diagnostic(
                         self.name(),
                         self.is_variadic(),
@@ -4114,16 +4529,15 @@
         result: &mut CodegenResult<'_>,
         item: &Item,
     ) -> Self::Return {
-        debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
+        debug!("<Function as CodeGenerator>::codegen: item = {item:?}");
         debug_assert!(item.is_enabled_for_codegen(ctx));
 
         let is_internal = matches!(self.linkage(), Linkage::Internal);
 
         let signature_item = ctx.resolve_item(self.signature());
         let signature = signature_item.kind().expect_type().canonical_type(ctx);
-        let signature = match *signature.kind() {
-            TypeKind::Function(ref sig) => sig,
-            _ => panic!("Signature kind is not a Function: {:?}", signature),
+        let TypeKind::Function(ref signature) = *signature.kind() else {
+            panic!("Signature kind is not a Function: {signature:?}")
         };
 
         if is_internal {
@@ -4141,18 +4555,24 @@
             }
         }
 
-        // Pure virtual methods have no actual symbol, so we can't generate
-        // something meaningful for them.
-        let is_dynamic_function = match self.kind() {
-            FunctionKind::Method(ref method_kind)
-                if method_kind.is_pure_virtual() =>
-            {
-                return None;
+        let is_pure_virtual = match self.kind() {
+            FunctionKind::Method(ref method_kind) => {
+                method_kind.is_pure_virtual()
             }
+            FunctionKind::Function => false,
+        };
+        if is_pure_virtual && !ctx.options().generate_pure_virtual_functions {
+            // Pure virtual methods have no actual symbol, so we can't generate
+            // something meaningful for them. Downstream code postprocessors
+            // might want to find out about them.
+            return None;
+        }
+
+        let is_dynamic_function = match self.kind() {
             FunctionKind::Function => {
                 ctx.options().dynamic_library_name.is_some()
             }
-            _ => false,
+            FunctionKind::Method(_) => false,
         };
 
         // Similar to static member variables in a class template, we can't
@@ -4180,7 +4600,7 @@
 
         let mut attributes = vec![];
 
-        if ctx.options().rust_features().must_use_function {
+        if true {
             let must_use = signature.must_use() || {
                 let ret_ty = signature
                     .return_type()
@@ -4196,12 +4616,12 @@
         }
 
         if let Some(comment) = item.comment(ctx) {
-            attributes.push(attributes::doc(comment));
+            attributes.push(attributes::doc(&comment));
         }
 
         let abi = match signature.abi(ctx, Some(name)) {
             Err(err) => {
-                if matches!(err, error::Error::UnsupportedAbi(_)) {
+                if matches!(err, Error::UnsupportedAbi(_)) {
                     unsupported_abi_diagnostic(
                         name,
                         signature.is_variadic(),
@@ -4215,8 +4635,7 @@
             }
             Ok(ClangAbi::Unknown(unknown_abi)) => {
                 panic!(
-                    "Invalid or unknown abi {:?} for function {:?} ({:?})",
-                    unknown_abi, canonical_name, self
+                    "Invalid or unknown abi {unknown_abi:?} for function {canonical_name:?} ({self:?})"
                 );
             }
             Ok(abi) => abi,
@@ -4226,24 +4645,27 @@
         // suffix.
         let times_seen = result.overload_number(&canonical_name);
         if times_seen > 0 {
-            write!(&mut canonical_name, "{}", times_seen).unwrap();
+            write!(&mut canonical_name, "{times_seen}").unwrap();
         }
+        utils::call_discovered_item_callback(ctx, item, || {
+            DiscoveredItem::Function {
+                final_name: canonical_name.clone(),
+            }
+        });
 
-        let mut has_link_name_attr = false;
-        if let Some(link_name) = self.link_name() {
-            attributes.push(attributes::link_name::<false>(link_name));
-            has_link_name_attr = true;
-        } else {
-            let link_name = mangled_name.unwrap_or(name);
-            if !is_dynamic_function &&
-                !utils::names_will_be_identical_after_mangling(
-                    &canonical_name,
-                    link_name,
-                    Some(abi),
-                )
-            {
+        let link_name_attr = self.link_name().or_else(|| {
+            let mangled_name = mangled_name.unwrap_or(name);
+            (!utils::names_will_be_identical_after_mangling(
+                &canonical_name,
+                mangled_name,
+                Some(abi),
+            ))
+            .then_some(mangled_name)
+        });
+
+        if let Some(link_name) = link_name_attr {
+            if !is_dynamic_function {
                 attributes.push(attributes::link_name::<false>(link_name));
-                has_link_name_attr = true;
             }
         }
 
@@ -4255,8 +4677,9 @@
                 quote! { #[link(wasm_import_module = #name)] }
             });
 
-        let should_wrap =
-            is_internal && ctx.options().wrap_static_fns && !has_link_name_attr;
+        let should_wrap = is_internal &&
+            ctx.options().wrap_static_fns &&
+            link_name_attr.is_none();
 
         if should_wrap {
             let name = canonical_name.clone() + ctx.wrap_static_fns_suffix();
@@ -4298,9 +4721,16 @@
         let ret = utils::fnsig_return_ty(ctx, signature);
 
         let ident = ctx.rust_ident(ident);
+
+        let safety = ctx
+            .options()
+            .rust_features
+            .unsafe_extern_blocks
+            .then(|| quote!(unsafe));
+
         let tokens = quote! {
             #wasm_link_attribute
-            extern #abi {
+            #safety extern #abi {
                 #(#attributes)*
                 pub fn #ident ( #( #args ),* ) #ret;
             }
@@ -4315,19 +4745,22 @@
 
         // If we're doing dynamic binding generation, add to the dynamic items.
         if is_dynamic_function {
+            let ident_str = ident.to_string();
+            let symbol = link_name_attr.unwrap_or(&ident_str);
             let args_identifiers =
                 utils::fnsig_argument_identifiers(ctx, signature);
             let ret_ty = utils::fnsig_return_ty(ctx, signature);
-            result.dynamic_items().push(
-                ident,
+            result.dynamic_items().push_func(
+                &ident,
+                symbol,
                 abi,
                 signature.is_variadic(),
                 ctx.options().dynamic_link_require_all,
-                args,
-                args_identifiers,
-                ret,
-                ret_ty,
-                attributes,
+                &args,
+                &args_identifiers,
+                &ret,
+                &ret_ty,
+                &attributes,
                 ctx,
             );
         } else {
@@ -4343,13 +4776,11 @@
     variadic: bool,
     location: Option<&crate::clang::SourceLocation>,
     ctx: &BindgenContext,
-    error: &error::Error,
+    error: &Error,
 ) {
     warn!(
-        "Skipping {}function `{}` because the {}",
+        "Skipping {}function `{fn_name}` because the {error}",
         if variadic { "variadic " } else { "" },
-        fn_name,
-        error
     );
 
     #[cfg(feature = "experimental")]
@@ -4359,16 +4790,14 @@
         let mut diag = Diagnostic::default();
         diag.with_title(
             format!(
-                "Skipping {}function `{}` because the {}",
+                "Skipping {}function `{fn_name}` because the {error}",
                 if variadic { "variadic " } else { "" },
-                fn_name,
-                error
             ),
-            Level::Warn,
+            Level::Warning,
         )
         .add_annotation(
             "No code will be generated for this function.",
-            Level::Warn,
+            Level::Warning,
         )
         .add_annotation(
             format!(
@@ -4392,7 +4821,7 @@
             }
         }
 
-        diag.display()
+        diag.display();
     }
 }
 
@@ -4402,8 +4831,7 @@
     _ctx: &BindgenContext,
 ) {
     warn!(
-        "Cannot generate wrapper for the static variadic function `{}`.",
-        fn_name,
+        "Cannot generate wrapper for the static variadic function `{fn_name}`."
     );
 
     #[cfg(feature = "experimental")]
@@ -4412,7 +4840,7 @@
 
         let mut diag = Diagnostic::default();
 
-        diag.with_title(format!("Cannot generate wrapper for the static function `{}`.", fn_name), Level::Warn)
+        diag.with_title(format!("Cannot generate wrapper for the static function `{fn_name}`."), Level::Warning)
             .add_annotation("The `--wrap-static-fns` feature does not support variadic functions.", Level::Note)
             .add_annotation("No code will be generated for this function.", Level::Note);
 
@@ -4430,7 +4858,7 @@
             }
         }
 
-        diag.display()
+        diag.display();
     }
 }
 
@@ -4445,7 +4873,7 @@
     // This would ideally resolve the method into an Item, and use
     // Item::process_before_codegen; however, ObjC methods are not currently
     // made into function items.
-    let name = format!("{}::{}{}", rust_class_name, prefix, method.rust_name());
+    let name = format!("{rust_class_name}::{prefix}{}", method.rust_name());
     if ctx.options().blocklisted_items.matches(name) {
         return;
     }
@@ -4482,8 +4910,7 @@
         ctx.wrap_unsafe_ops(body)
     };
 
-    let method_name =
-        ctx.rust_ident(format!("{}{}", prefix, method.rust_name()));
+    let method_name = ctx.rust_ident(format!("{prefix}{}", method.rust_name()));
 
     methods.push(quote! {
         unsafe fn #method_name #sig where <Self as std::ops::Deref>::Target: objc::Message + Sized {
@@ -4584,7 +5011,7 @@
             };
             result.push(struct_block);
             let mut protocol_set: HashSet<ItemId> = Default::default();
-            for protocol_id in self.conforms_to.iter() {
+            for protocol_id in &self.conforms_to {
                 protocol_set.insert(*protocol_id);
                 let protocol_name = ctx.rust_ident(
                     ctx.resolve_type(protocol_id.expect_type_id(ctx))
@@ -4606,9 +5033,8 @@
                     .expect_type()
                     .kind();
 
-                let parent = match parent {
-                    TypeKind::ObjCInterface(ref parent) => parent,
-                    _ => break,
+                let TypeKind::ObjCInterface(parent) = parent else {
+                    break;
                 };
                 parent_class = parent.parent_class;
 
@@ -4629,7 +5055,7 @@
                     }
                 };
                 result.push(impl_trait);
-                for protocol_id in parent.conforms_to.iter() {
+                for protocol_id in &parent.conforms_to {
                     if protocol_set.insert(*protocol_id) {
                         let protocol_name = ctx.rust_ident(
                             ctx.resolve_type(protocol_id.expect_type_id(ctx))
@@ -4656,8 +5082,7 @@
                     result.push(from_block);
 
                     let error_msg = format!(
-                        "This {} cannot be downcasted to {}",
-                        parent_struct_name, child_struct_name
+                        "This {parent_struct_name} cannot be downcasted to {child_struct_name}"
                     );
                     let try_into_block = quote! {
                         impl std::convert::TryFrom<#parent_struct> for #class_name {
@@ -4716,7 +5141,7 @@
             let codegen_items = context.codegen_items();
             for (id, item) in context.items() {
                 if codegen_items.contains(&id) {
-                    println!("ir: {:?} = {:#?}", id, item);
+                    println!("ir: {id:?} = {item:#?}");
                 }
             }
         }
@@ -4724,10 +5149,9 @@
         if let Some(path) = context.options().emit_ir_graphviz.as_ref() {
             match dot::write_dot_file(context, path) {
                 Ok(()) => info!(
-                    "Your dot file was generated successfully into: {}",
-                    path
+                    "Your dot file was generated successfully into: {path}"
                 ),
-                Err(e) => warn!("{}", e),
+                Err(e) => warn!("{e}"),
             }
         }
 
@@ -4737,7 +5161,7 @@
                     "Your depfile was generated successfully into: {}",
                     spec.depfile_path.display()
                 ),
-                Err(e) => warn!("{}", e),
+                Err(e) => warn!("{e}"),
             }
         }
 
@@ -4750,7 +5174,7 @@
         if let Some(ref lib_name) = context.options().dynamic_library_name {
             let lib_ident = context.rust_ident(lib_name);
             let dynamic_items_tokens =
-                result.dynamic_items().get_tokens(lib_ident, context);
+                result.dynamic_items().get_tokens(&lib_ident, context);
             result.push(dynamic_items_tokens);
         }
 
@@ -4764,8 +5188,10 @@
 }
 
 pub(crate) mod utils {
+    use super::helpers::BITFIELD_UNIT;
     use super::serialize::CSerialize;
     use super::{error, CodegenError, CodegenResult, ToRustTyOrOpaque};
+    use crate::callbacks::DiscoveredItemId;
     use crate::ir::context::BindgenContext;
     use crate::ir::context::TypeId;
     use crate::ir::function::{Abi, ClangAbi, FunctionSig};
@@ -4786,14 +5212,10 @@
             return Ok(());
         }
 
-        let path = context
-            .options()
-            .wrap_static_fns_path
-            .as_ref()
-            .map(PathBuf::from)
-            .unwrap_or_else(|| {
-                std::env::temp_dir().join("bindgen").join("extern")
-            });
+        let path = context.options().wrap_static_fns_path.as_ref().map_or_else(
+            || std::env::temp_dir().join("bindgen").join("extern"),
+            PathBuf::from,
+        );
 
         let dir = path.parent().unwrap();
 
@@ -4814,7 +5236,7 @@
 
         if !context.options().input_headers.is_empty() {
             for header in &context.options().input_headers {
-                writeln!(code, "#include \"{}\"", header)?;
+                writeln!(code, "#include \"{header}\"")?;
             }
 
             writeln!(code)?;
@@ -4822,7 +5244,7 @@
 
         if !context.options().input_header_contents.is_empty() {
             for (name, contents) in &context.options().input_header_contents {
-                writeln!(code, "// {}\n{}", name, contents)?;
+                writeln!(code, "// {name}\n{contents}")?;
             }
 
             writeln!(code)?;
@@ -4862,10 +5284,10 @@
                     }
                     match ty.kind() {
                         TypeKind::Alias(type_id_alias) => {
-                            type_id = *type_id_alias
+                            type_id = *type_id_alias;
                         }
                         TypeKind::ResolvedTypeRef(type_id_typedef) => {
-                            type_id = *type_id_typedef
+                            type_id = *type_id_typedef;
                         }
                         _ => break,
                     }
@@ -4900,8 +5322,14 @@
         ctx: &BindgenContext,
         result: &mut Vec<proc_macro2::TokenStream>,
     ) {
+        if ctx.options().blocklisted_items.matches(BITFIELD_UNIT) ||
+            ctx.options().blocklisted_types.matches(BITFIELD_UNIT)
+        {
+            return;
+        }
+
         let bitfield_unit_src = include_str!("./bitfield_unit.rs");
-        let bitfield_unit_src = if ctx.options().rust_features().min_const_fn {
+        let bitfield_unit_src = if true {
             Cow::Borrowed(bitfield_unit_src)
         } else {
             Cow::Owned(bitfield_unit_src.replace("const fn ", "fn "))
@@ -4967,7 +5395,7 @@
 
         // If the target supports `const fn`, declare eligible functions
         // as `const fn` else just `fn`.
-        let const_fn = if ctx.options().rust_features().min_const_fn {
+        let const_fn = if true {
             quote! { const fn }
         } else {
             quote! { fn }
@@ -5079,7 +5507,7 @@
 
         // If the target supports `const fn`, declare eligible functions
         // as `const fn` else just `fn`.
-        let const_fn = if ctx.options().rust_features().min_const_fn {
+        let const_fn = if true {
             quote! { const fn }
         } else {
             quote! { fn }
@@ -5178,6 +5606,39 @@
         result.extend(old_items);
     }
 
+    pub(crate) fn prepend_opaque_array_types(
+        ctx: &BindgenContext,
+        result: &mut Vec<proc_macro2::TokenStream>,
+    ) {
+        let mut tys = vec![];
+        // If Bindgen could only determine the size and alignment of a type, it is represented like
+        // this.
+        for align in ctx.opaque_array_types_needed() {
+            let ident = if align == 1 {
+                format_ident!("__BindgenOpaqueArray")
+            } else {
+                format_ident!("__BindgenOpaqueArray{}", align)
+            };
+            let repr = if align <= 1 {
+                quote! { #[repr(C)] }
+            } else {
+                let explicit = super::helpers::ast_ty::int_expr(align as i64);
+                quote! { #[repr(C, align(#explicit))] }
+            };
+            tys.push(quote! {
+                #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
+                #repr
+                pub struct #ident<T>(pub T);
+                impl<T: Copy + Default, const N: usize> Default for #ident<[T; N]> {
+                    fn default() -> Self {
+                        Self([<T as Default>::default(); N])
+                    }
+                }
+            });
+        }
+        result.splice(0..0, tys);
+    }
+
     pub(crate) fn build_path(
         item: &Item,
         ctx: &BindgenContext,
@@ -5263,7 +5724,7 @@
 
     pub(crate) fn fnsig_argument_type(
         ctx: &BindgenContext,
-        ty: &TypeId,
+        ty: TypeId,
     ) -> syn::Type {
         use super::ToPtr;
 
@@ -5285,7 +5746,8 @@
                 } else {
                     t.to_rust_ty_or_opaque(ctx, &())
                 };
-                stream.to_ptr(ctx.resolve_type(t).is_const())
+                stream
+                    .to_ptr(ctx.resolve_type(t).is_const() || arg_ty.is_const())
             }
             TypeKind::Pointer(inner) => {
                 let inner = ctx.resolve_item(inner);
@@ -5305,7 +5767,7 @@
 
     pub(crate) fn fnsig_arguments_iter<
         'a,
-        I: Iterator<Item = &'a (Option<String>, crate::ir::context::TypeId)>,
+        I: Iterator<Item = &'a (Option<String>, TypeId)>,
     >(
         ctx: &BindgenContext,
         args_iter: I,
@@ -5314,14 +5776,13 @@
         let mut unnamed_arguments = 0;
         let mut args = args_iter
             .map(|(name, ty)| {
-                let arg_ty = fnsig_argument_type(ctx, ty);
+                let arg_ty = fnsig_argument_type(ctx, *ty);
 
-                let arg_name = match *name {
-                    Some(ref name) => ctx.rust_mangle(name).into_owned(),
-                    None => {
-                        unnamed_arguments += 1;
-                        format!("arg{}", unnamed_arguments)
-                    }
+                let arg_name = if let Some(ref name) = *name {
+                    ctx.rust_mangle(name).into_owned()
+                } else {
+                    unnamed_arguments += 1;
+                    format!("arg{unnamed_arguments}")
                 };
 
                 assert!(!arg_name.is_empty());
@@ -5334,7 +5795,7 @@
             .collect::<Vec<_>>();
 
         if is_variadic {
-            args.push(quote! { ... })
+            args.push(quote! { ... });
         }
 
         args
@@ -5360,12 +5821,11 @@
             .argument_types()
             .iter()
             .map(|&(ref name, _ty)| {
-                let arg_name = match *name {
-                    Some(ref name) => ctx.rust_mangle(name).into_owned(),
-                    None => {
-                        unnamed_arguments += 1;
-                        format!("arg{}", unnamed_arguments)
-                    }
+                let arg_name = if let Some(ref name) = *name {
+                    ctx.rust_mangle(name).into_owned()
+                } else {
+                    unnamed_arguments += 1;
+                    format!("arg{unnamed_arguments}")
                 };
 
                 assert!(!arg_name.is_empty());
@@ -5415,7 +5875,7 @@
         let mangled_name = mangled_name.as_bytes();
 
         let (mangling_prefix, expect_suffix) = match call_conv {
-            Some(ClangAbi::Known(Abi::C)) |
+            Some(ClangAbi::Known(Abi::C | Abi::CUnwind)) |
             // None is the case for global variables
             None => {
                 (b'_', false)
@@ -5442,7 +5902,7 @@
 
         // Check that the mangled name contains the canonical name after the
         // prefix
-        if &mangled_name[1..canonical_name.len() + 1] != canonical_name {
+        if &mangled_name[1..=canonical_name.len()] != canonical_name {
             return false;
         }
 
@@ -5469,5 +5929,29 @@
         }
 
         true
+    }
+
+    pub(super) fn call_discovered_item_callback(
+        ctx: &BindgenContext,
+        item: &Item,
+        discovered_item_creator: impl Fn() -> crate::callbacks::DiscoveredItem,
+    ) {
+        let source_location = item.location().map(|clang_location| {
+            let (file, line, col, byte_offset) = clang_location.location();
+            let file_name = file.name();
+            crate::callbacks::SourceLocation {
+                line,
+                col,
+                byte_offset,
+                file_name,
+            }
+        });
+        ctx.options().for_each_callback(|cb| {
+            cb.new_item_found(
+                DiscoveredItemId::new(item.id().as_usize()),
+                discovered_item_creator(),
+                source_location.as_ref(),
+            );
+        });
     }
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/postprocessing/merge_extern_blocks.rs firefox-140.10.2/third_party/rust/bindgen/codegen/postprocessing/merge_extern_blocks.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/postprocessing/merge_extern_blocks.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/postprocessing/merge_extern_blocks.rs	Mon May 11 04:49:32 2026
@@ -4,7 +4,7 @@
 };
 
 pub(super) fn merge_extern_blocks(file: &mut File) {
-    Visitor.visit_file_mut(file)
+    Visitor.visit_file_mut(file);
 }
 
 struct Visitor;
@@ -12,14 +12,14 @@
 impl VisitMut for Visitor {
     fn visit_file_mut(&mut self, file: &mut File) {
         visit_items(&mut file.items);
-        visit_file_mut(self, file)
+        visit_file_mut(self, file);
     }
 
     fn visit_item_mod_mut(&mut self, item_mod: &mut ItemMod) {
         if let Some((_, ref mut items)) = item_mod.content {
             visit_items(items);
         }
-        visit_item_mod_mut(self, item_mod)
+        visit_item_mod_mut(self, item_mod);
     }
 }
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/postprocessing/sort_semantically.rs firefox-140.10.2/third_party/rust/bindgen/codegen/postprocessing/sort_semantically.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/postprocessing/sort_semantically.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/postprocessing/sort_semantically.rs	Mon May 11 04:49:32 2026
@@ -4,7 +4,7 @@
 };
 
 pub(super) fn sort_semantically(file: &mut File) {
-    Visitor.visit_file_mut(file)
+    Visitor.visit_file_mut(file);
 }
 
 struct Visitor;
@@ -12,14 +12,14 @@
 impl VisitMut for Visitor {
     fn visit_file_mut(&mut self, file: &mut File) {
         visit_items(&mut file.items);
-        visit_file_mut(self, file)
+        visit_file_mut(self, file);
     }
 
     fn visit_item_mod_mut(&mut self, item_mod: &mut ItemMod) {
         if let Some((_, ref mut items)) = item_mod.content {
             visit_items(items);
         }
-        visit_item_mod_mut(self, item_mod)
+        visit_item_mod_mut(self, item_mod);
     }
 }
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/serialize.rs firefox-140.10.2/third_party/rust/bindgen/codegen/serialize.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/serialize.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/serialize.rs	Mon May 11 04:49:32 2026
@@ -14,8 +14,7 @@
 
 fn get_loc(item: &Item) -> String {
     item.location()
-        .map(|x| x.to_string())
-        .unwrap_or_else(|| "unknown".to_owned())
+        .map_or_else(|| "unknown".to_owned(), |x| x.to_string())
 }
 
 pub(super) trait CSerialize<'a> {
@@ -45,7 +44,7 @@
                 func.serialize(ctx, (self, extra), stack, writer)
             }
             kind => Err(CodegenError::Serialize {
-                msg: format!("Cannot serialize item kind {:?}", kind),
+                msg: format!("Cannot serialize item kind {kind:?}"),
                 loc: get_loc(self),
             }),
         }
@@ -72,16 +71,17 @@
             });
         }
 
-        let signature = match ctx.resolve_type(self.signature()).kind() {
-            TypeKind::Function(signature) => signature,
-            _ => unreachable!(),
+        let TypeKind::Function(signature) =
+            ctx.resolve_type(self.signature()).kind()
+        else {
+            unreachable!()
         };
 
         assert!(!signature.is_variadic());
 
         let name = self.name();
 
-        // Function argoments stored as `(name, type_id)` tuples.
+        // Function arguments stored as `(name, type_id)` tuples.
         let args = {
             let mut count = 0;
 
@@ -102,7 +102,7 @@
                     } else {
                         Some((
                             opt_name.unwrap_or_else(|| {
-                                let name = format!("arg_{}", count);
+                                let name = format!("arg_{count}");
                                 count += 1;
                                 name
                             }),
@@ -114,7 +114,7 @@
         };
 
         // The name used for the wrapper self.
-        let wrap_name = format!("{}{}", name, ctx.wrap_static_fns_suffix());
+        let wrap_name = format!("{name}{}", ctx.wrap_static_fns_suffix());
 
         // The function's return type
         let (ret_item, ret_ty) = {
@@ -131,15 +131,15 @@
         const INDENT: &str = "    ";
 
         // Write `wrap_name(args`.
-        write!(writer, " {}(", wrap_name)?;
+        write!(writer, " {wrap_name}(")?;
         serialize_args(&args, ctx, writer)?;
 
         if wrap_as_variadic.is_none() {
             // Write `) { name(` if the function returns void and `) { return name(` if it does not.
             if ret_ty.is_void() {
-                write!(writer, ") {{ {}(", name)?;
+                write!(writer, ") {{ {name}(")?;
             } else {
-                write!(writer, ") {{ return {}(", name)?;
+                write!(writer, ") {{ return {name}(")?;
             }
         } else {
             // Write `, ...) {`
@@ -165,7 +165,7 @@
             if !ret_ty.is_void() {
                 write!(writer, "ret = ")?;
             }
-            write!(writer, "{}(", name)?;
+            write!(writer, "{name}(")?;
         }
 
         // Get the arguments names and insert at the right place if necessary `ap`
@@ -179,7 +179,7 @@
 
         // Write `arg_names);`.
         serialize_sep(", ", args.iter(), ctx, writer, |name, _, buf| {
-            write!(buf, "{}", name).map_err(From::from)
+            write!(buf, "{name}").map_err(From::from)
         })?;
         #[rustfmt::skip]
         write!(writer, ");{}", if wrap_as_variadic.is_none() { " " } else { "\n" })?;
@@ -198,7 +198,7 @@
     }
 }
 
-impl<'a> CSerialize<'a> for TypeId {
+impl CSerialize<'_> for TypeId {
     type Extra = ();
 
     fn serialize<W: Write>(
@@ -228,13 +228,13 @@
                 if self.is_const() {
                     write!(writer, "const ")?;
                 }
-                write!(writer, "void")?
+                write!(writer, "void")?;
             }
             TypeKind::NullPtr => {
                 if self.is_const() {
                     write!(writer, "const ")?;
                 }
-                write!(writer, "nullptr_t")?
+                write!(writer, "nullptr_t")?;
             }
             TypeKind::Int(int_kind) => {
                 if self.is_const() {
@@ -257,8 +257,7 @@
                     int_kind => {
                         return Err(CodegenError::Serialize {
                             msg: format!(
-                                "Cannot serialize integer kind {:?}",
-                                int_kind
+                                "Cannot serialize integer kind {int_kind:?}"
                             ),
                             loc: get_loc(item),
                         })
@@ -286,7 +285,7 @@
                     FloatKind::Float => write!(writer, "float complex")?,
                     FloatKind::Double => write!(writer, "double complex")?,
                     FloatKind::LongDouble => {
-                        write!(writer, "long double complex")?
+                        write!(writer, "long double complex")?;
                     }
                     FloatKind::Float128 => write!(writer, "__complex128")?,
                 }
@@ -294,9 +293,9 @@
             TypeKind::Alias(type_id) => {
                 if let Some(name) = self.name() {
                     if self.is_const() {
-                        write!(writer, "const {}", name)?;
+                        write!(writer, "const {name}")?;
                     } else {
-                        write!(writer, "{}", name)?;
+                        write!(writer, "{name}")?;
                     }
                 } else {
                     type_id.serialize(ctx, (), stack, writer)?;
@@ -304,7 +303,7 @@
             }
             TypeKind::Array(type_id, length) => {
                 type_id.serialize(ctx, (), stack, writer)?;
-                write!(writer, " [{}]", length)?
+                write!(writer, " [{length}]")?;
             }
             TypeKind::Function(signature) => {
                 if self.is_const() {
@@ -320,7 +319,7 @@
 
                 write!(writer, " (")?;
                 while let Some(item) = stack.pop() {
-                    write!(writer, "{}", item)?;
+                    write!(writer, "{item}")?;
                 }
                 write!(writer, ")")?;
 
@@ -342,14 +341,14 @@
                             type_id.serialize(ctx, (), &mut stack, buf)
                         },
                     )?;
-                    write!(writer, ")")?
+                    write!(writer, ")")?;
                 }
             }
             TypeKind::ResolvedTypeRef(type_id) => {
                 if self.is_const() {
                     write!(writer, "const ")?;
                 }
-                type_id.serialize(ctx, (), stack, writer)?
+                type_id.serialize(ctx, (), stack, writer)?;
             }
             TypeKind::Pointer(type_id) => {
                 if self.is_const() {
@@ -357,7 +356,7 @@
                 } else {
                     stack.push("*".to_owned());
                 }
-                type_id.serialize(ctx, (), stack, writer)?
+                type_id.serialize(ctx, (), stack, writer)?;
             }
             TypeKind::Comp(comp_info) => {
                 if self.is_const() {
@@ -367,9 +366,9 @@
                 let name = item.canonical_name(ctx);
 
                 match comp_info.kind() {
-                    CompKind::Struct => write!(writer, "struct {}", name)?,
-                    CompKind::Union => write!(writer, "union {}", name)?,
-                };
+                    CompKind::Struct => write!(writer, "struct {name}")?,
+                    CompKind::Union => write!(writer, "union {name}")?,
+                }
             }
             TypeKind::Enum(_enum_ty) => {
                 if self.is_const() {
@@ -377,20 +376,20 @@
                 }
 
                 let name = item.canonical_name(ctx);
-                write!(writer, "enum {}", name)?;
+                write!(writer, "enum {name}")?;
             }
             ty => {
                 return Err(CodegenError::Serialize {
-                    msg: format!("Cannot serialize type kind {:?}", ty),
+                    msg: format!("Cannot serialize type kind {ty:?}"),
                     loc: get_loc(item),
                 })
             }
-        };
+        }
 
         if !stack.is_empty() {
             write!(writer, " ")?;
             while let Some(item) = stack.pop() {
-                write!(writer, "{}", item)?;
+                write!(writer, "{item}")?;
             }
         }
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/codegen/struct_layout.rs firefox-140.10.2/third_party/rust/bindgen/codegen/struct_layout.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/codegen/struct_layout.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/codegen/struct_layout.rs	Mon May 11 04:49:32 2026
@@ -7,7 +7,7 @@
 use crate::ir::layout::Layout;
 use crate::ir::ty::{Type, TypeKind};
 use crate::FieldVisibilityKind;
-use proc_macro2::{self, Ident, Span};
+use proc_macro2::{Ident, Span};
 use std::cmp;
 
 const MAX_GUARANTEED_ALIGN: usize = 8;
@@ -28,6 +28,7 @@
     max_field_align: usize,
     last_field_was_bitfield: bool,
     visibility: FieldVisibilityKind,
+    last_field_was_flexible_array: bool,
 }
 
 /// Returns a size aligned to a given value.
@@ -44,23 +45,6 @@
     size + align - rem
 }
 
-/// Returns the lower power of two byte count that can hold at most n bits.
-pub(crate) fn bytes_from_bits_pow2(mut n: usize) -> usize {
-    if n == 0 {
-        return 0;
-    }
-
-    if n <= 8 {
-        return 1;
-    }
-
-    if !n.is_power_of_two() {
-        n = n.next_power_of_two();
-    }
-
-    n / 8
-}
-
 #[test]
 fn test_align_to() {
     assert_eq!(align_to(1, 1), 1);
@@ -70,20 +54,6 @@
     assert_eq!(align_to(17, 4), 20);
 }
 
-#[test]
-fn test_bytes_from_bits_pow2() {
-    assert_eq!(bytes_from_bits_pow2(0), 0);
-    for i in 1..9 {
-        assert_eq!(bytes_from_bits_pow2(i), 1);
-    }
-    for i in 9..17 {
-        assert_eq!(bytes_from_bits_pow2(i), 2);
-    }
-    for i in 17..33 {
-        assert_eq!(bytes_from_bits_pow2(i), 4);
-    }
-}
-
 impl<'a> StructLayoutTracker<'a> {
     pub(crate) fn new(
         ctx: &'a BindgenContext,
@@ -110,6 +80,7 @@
             latest_field_layout: None,
             max_field_align: 0,
             last_field_was_bitfield: false,
+            last_field_was_flexible_array: false,
         }
     }
 
@@ -121,6 +92,10 @@
         self.is_rust_union
     }
 
+    pub(crate) fn saw_flexible_array(&mut self) {
+        self.last_field_was_flexible_array = true;
+    }
+
     pub(crate) fn saw_vtable(&mut self) {
         debug!("saw vtable for {}", self.name);
 
@@ -142,7 +117,7 @@
     }
 
     pub(crate) fn saw_bitfield_unit(&mut self, layout: Layout) {
-        debug!("saw bitfield unit for {}: {:?}", self.name, layout);
+        debug!("saw bitfield unit for {}: {layout:?}", self.name);
 
         self.align_to_latest_field(layout);
 
@@ -242,12 +217,9 @@
             );
 
             debug!(
-                "align field {} to {}/{} with {} padding bytes {:?}",
-                field_name,
+                "align field {field_name} to {}/{} with {padding_bytes} padding bytes {field_layout:?}",
                 self.latest_offset,
                 field_offset.unwrap_or(0) / 8,
-                padding_bytes,
-                field_layout
             );
 
             let padding_align = if force_padding {
@@ -263,15 +235,19 @@
             }
         };
 
-        self.latest_offset += field_layout.size;
+        if is_union {
+            self.latest_offset =
+                cmp::max(self.latest_offset, field_layout.size);
+        } else {
+            self.latest_offset += field_layout.size;
+        }
         self.latest_field_layout = Some(field_layout);
         self.max_field_align =
             cmp::max(self.max_field_align, field_layout.align);
         self.last_field_was_bitfield = false;
 
         debug!(
-            "Offset: {}: {} -> {}",
-            field_name,
+            "Offset: {field_name}: {} -> {}",
             self.latest_offset - field_layout.size,
             self.latest_offset
         );
@@ -295,14 +271,18 @@
             return None;
         }
 
+        // Also doesn't make sense for structs with flexible array members
+        if self.last_field_was_flexible_array {
+            return None;
+        }
+
         if self.latest_offset == comp_layout.size {
             // This struct does not contain tail padding.
             return None;
         }
 
         trace!(
-            "need a tail padding field for {}: offset {} -> size {}",
-            comp_name,
+            "need a tail padding field for {comp_name}: offset {} -> size {}",
             self.latest_offset,
             comp_layout.size
         );
@@ -314,10 +294,7 @@
         &mut self,
         layout: Layout,
     ) -> Option<proc_macro2::TokenStream> {
-        debug!(
-            "pad_struct:\n\tself = {:#?}\n\tlayout = {:#?}",
-            self, layout
-        );
+        debug!("pad_struct:\n\tself = {self:#?}\n\tlayout = {layout:#?}");
 
         if layout.size < self.latest_offset {
             warn!(
@@ -333,7 +310,7 @@
             return None;
         }
 
-        let repr_align = self.ctx.options().rust_features().repr_align;
+        let repr_align = true;
 
         // We always pad to get to the correct size if the struct is one of
         // those we can't align properly.
@@ -357,7 +334,7 @@
                 Layout::new(padding_bytes, layout.align)
             };
 
-            debug!("pad bytes to struct {}, {:?}", self.name, layout);
+            debug!("pad bytes to struct {}, {layout:?}", self.name);
 
             Some(self.padding_field(layout))
         } else {
@@ -366,7 +343,7 @@
     }
 
     pub(crate) fn requires_explicit_align(&self, layout: Layout) -> bool {
-        let repr_align = self.ctx.options().rust_features().repr_align;
+        let repr_align = true;
 
         // Always force explicit repr(align) for stuff more than 16-byte aligned
         // to work-around https://github.com/rust-lang/rust/issues/54341.
@@ -390,13 +367,13 @@
     }
 
     fn padding_field(&mut self, layout: Layout) -> proc_macro2::TokenStream {
-        let ty = helpers::blob(self.ctx, layout);
+        let ty = helpers::blob(self.ctx, layout, false);
         let padding_count = self.padding_count;
 
         self.padding_count += 1;
 
         let padding_field_name = Ident::new(
-            &format!("__bindgen_padding_{}", padding_count),
+            &format!("__bindgen_padding_{padding_count}"),
             Span::call_site(),
         );
 
@@ -411,23 +388,22 @@
 
     /// Returns whether the new field is known to merge with a bitfield.
     ///
-    /// This is just to avoid doing the same check also in pad_field.
+    /// This is just to avoid doing the same check also in `pad_field`.
     fn align_to_latest_field(&mut self, new_field_layout: Layout) -> bool {
         if self.is_packed {
             // Skip to align fields when packed.
             return false;
         }
 
-        let layout = match self.latest_field_layout {
-            Some(l) => l,
-            None => return false,
+        let Some(layout) = self.latest_field_layout else {
+            return false;
         };
 
         // If it was, we may or may not need to align, depending on what the
         // current field alignment and the bitfield size and alignment are.
         debug!(
-            "align_to_bitfield? {}: {:?} {:?}",
-            self.last_field_was_bitfield, layout, new_field_layout
+            "align_to_bitfield? {}: {layout:?} {new_field_layout:?}",
+            self.last_field_was_bitfield,
         );
 
         // Avoid divide-by-zero errors if align is 0.
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/deps.rs firefox-140.10.2/third_party/rust/bindgen/deps.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/deps.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/deps.rs	Mon May 11 04:49:32 2026
@@ -18,7 +18,7 @@
 
         let mut buf = format!("{}:", escape(&self.output_module));
         for file in deps {
-            buf = format!("{} {}", buf, escape(file));
+            buf = format!("{buf} {}", escape(file));
         }
         buf
     }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/diagnostics.rs firefox-140.10.2/third_party/rust/bindgen/diagnostics.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/diagnostics.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/diagnostics.rs	Mon May 11 04:49:32 2026
@@ -6,34 +6,10 @@
 use std::io::{self, BufRead, BufReader};
 use std::{borrow::Cow, fs::File};
 
-use annotate_snippets::{
-    display_list::{DisplayList, FormatOptions},
-    snippet::{Annotation, Slice as ExtSlice, Snippet},
-};
+use annotate_snippets::{Renderer, Snippet};
 
-use annotate_snippets::snippet::AnnotationType;
+pub(crate) use annotate_snippets::Level;
 
-#[derive(Clone, Copy, Debug)]
-pub(crate) enum Level {
-    Error,
-    Warn,
-    Info,
-    Note,
-    Help,
-}
-
-impl From<Level> for AnnotationType {
-    fn from(level: Level) -> Self {
-        match level {
-            Level::Error => Self::Error,
-            Level::Warn => Self::Warning,
-            Level::Info => Self::Info,
-            Level::Note => Self::Note,
-            Level::Help => Self::Help,
-        }
-    }
-}
-
 /// A `bindgen` diagnostic.
 #[derive(Default)]
 pub(crate) struct Diagnostic<'a> {
@@ -78,55 +54,37 @@
             static INVOKED_BY_BUILD_SCRIPT: bool =  std::env::var_os("CARGO_CFG_TARGET_ARCH").is_some();
         }
 
-        let mut title = None;
         let mut footer = vec![];
         let mut slices = vec![];
-        if let Some((msg, level)) = &self.title {
-            title = Some(Annotation {
-                id: Some("bindgen"),
-                label: Some(msg.as_ref()),
-                annotation_type: (*level).into(),
-            })
-        }
+        let snippet = if let Some((msg, level)) = &self.title {
+            (*level).title(msg)
+        } else {
+            return;
+        };
 
         for (msg, level) in &self.footer {
-            footer.push(Annotation {
-                id: None,
-                label: Some(msg.as_ref()),
-                annotation_type: (*level).into(),
-            });
+            footer.push((*level).title(msg));
         }
 
         // add additional info that this is generated by bindgen
         // so as to not confuse with rustc warnings
-        footer.push(Annotation {
-            id: None,
-            label: Some("This diagnostic was generated by bindgen."),
-            annotation_type: AnnotationType::Info,
-        });
+        footer.push(
+            Level::Info.title("This diagnostic was generated by bindgen."),
+        );
 
         for slice in &self.slices {
             if let Some(source) = &slice.source {
-                slices.push(ExtSlice {
-                    source: source.as_ref(),
-                    line_start: slice.line.unwrap_or_default(),
-                    origin: slice.filename.as_deref(),
-                    annotations: vec![],
-                    fold: false,
-                })
+                let mut snippet = Snippet::source(source)
+                    .line_start(slice.line.unwrap_or_default());
+                if let Some(origin) = &slice.filename {
+                    snippet = snippet.origin(origin);
+                }
+                slices.push(snippet);
             }
         }
 
-        let snippet = Snippet {
-            title,
-            footer,
-            slices,
-            opt: FormatOptions {
-                color: true,
-                ..Default::default()
-            },
-        };
-        let dl = DisplayList::from(snippet);
+        let renderer = Renderer::styled();
+        let dl = renderer.render(snippet.snippets(slices).footers(footer));
 
         if INVOKED_BY_BUILD_SCRIPT.with(Clone::clone) {
             // This is just a hack which hides the `warning:` added by cargo at the beginning of
@@ -135,10 +93,10 @@
             let hide_warning = "\r        \r";
             let string = dl.to_string();
             for line in string.lines() {
-                println!("cargo:warning={}{}", hide_warning, line);
+                println!("cargo:warning={hide_warning}{line}");
             }
         } else {
-            eprintln!("{}\n", dl);
+            eprintln!("{dl}\n");
         }
     }
 }
@@ -168,8 +126,7 @@
         line: usize,
         col: usize,
     ) -> &mut Self {
-        write!(name, ":{}:{}", line, col)
-            .expect("Writing to a string cannot fail");
+        write!(name, ":{line}:{col}").expect("Writing to a string cannot fail");
         self.filename = Some(name);
         self.line = Some(line);
         self
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/extra_assertions.rs firefox-140.10.2/third_party/rust/bindgen/extra_assertions.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/extra_assertions.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/extra_assertions.rs	Mon May 11 04:49:32 2026
@@ -2,7 +2,7 @@
 //! and/or CI when the `__testing_only_extra_assertions` feature is enabled.
 
 /// Simple macro that forwards to assert! when using
-/// __testing_only_extra_assertions.
+/// `__testing_only_extra_assertions`.
 macro_rules! extra_assert {
     ( $cond:expr ) => {
         if cfg!(feature = "__testing_only_extra_assertions") {
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/features.rs firefox-140.10.2/third_party/rust/bindgen/features.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/features.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/features.rs	Mon May 11 04:49:32 2026
@@ -4,86 +4,303 @@
 #![deny(clippy::missing_docs_in_private_items)]
 #![allow(deprecated)]
 
-use std::cmp::Ordering;
-use std::io;
 use std::str::FromStr;
+use std::{fmt, io};
 
+/// Represents the version of the Rust language to target.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+#[repr(transparent)]
+pub struct RustTarget(Version);
+
+impl RustTarget {
+    /// Create a new [`RustTarget`] for a stable release of Rust.
+    pub fn stable(minor: u64, patch: u64) -> Result<Self, InvalidRustTarget> {
+        let target = Self(Version::Stable(minor, patch));
+
+        if target < EARLIEST_STABLE_RUST {
+            return Err(InvalidRustTarget::TooEarly);
+        }
+
+        Ok(target)
+    }
+
+    const fn minor(&self) -> Option<u64> {
+        match self.0 {
+            Version::Nightly => None,
+            Version::Stable(minor, _) => Some(minor),
+        }
+    }
+
+    const fn is_compatible(&self, other: &Self) -> bool {
+        match (self.0, other.0) {
+            (Version::Stable(minor, _), Version::Stable(other_minor, _)) => {
+                // We ignore the patch version number as they only include backwards compatible bug
+                // fixes.
+                minor >= other_minor
+            }
+            // Nightly is compatible with everything
+            (Version::Nightly, _) => true,
+            // No stable release is compatible with nightly
+            (Version::Stable { .. }, Version::Nightly) => false,
+        }
+    }
+}
+
+impl Default for RustTarget {
+    fn default() -> Self {
+        // Bindgen from build script: default to generating bindings compatible
+        // with the Rust version currently performing this build.
+        #[cfg(not(feature = "__cli"))]
+        {
+            use std::env;
+            use std::iter;
+            use std::process::Command;
+            use std::sync::OnceLock;
+
+            static CURRENT_RUST: OnceLock<Option<RustTarget>> = OnceLock::new();
+
+            if let Some(current_rust) = *CURRENT_RUST.get_or_init(|| {
+                let is_build_script =
+                    env::var_os("CARGO_CFG_TARGET_ARCH").is_some();
+                if !is_build_script {
+                    return None;
+                }
+
+                let rustc = env::var_os("RUSTC")?;
+                let rustc_wrapper = env::var_os("RUSTC_WRAPPER")
+                    .filter(|wrapper| !wrapper.is_empty());
+                let wrapped_rustc =
+                    rustc_wrapper.iter().chain(iter::once(&rustc));
+
+                let mut is_clippy_driver = false;
+                loop {
+                    let mut wrapped_rustc = wrapped_rustc.clone();
+                    let mut command =
+                        Command::new(wrapped_rustc.next().unwrap());
+                    command.args(wrapped_rustc);
+                    if is_clippy_driver {
+                        command.arg("--rustc");
+                    }
+                    command.arg("--version");
+
+                    let output = command.output().ok()?;
+                    let string = String::from_utf8(output.stdout).ok()?;
+
+                    // Version string like "rustc 1.100.0-beta.5 (f0e1d2c3b 2026-10-17)"
+                    let last_line = string.lines().last().unwrap_or(&string);
+                    let (program, rest) = last_line.trim().split_once(' ')?;
+                    if program != "rustc" {
+                        if program.starts_with("clippy") && !is_clippy_driver {
+                            is_clippy_driver = true;
+                            continue;
+                        }
+                        return None;
+                    }
+
+                    let number = rest.split([' ', '-', '+']).next()?;
+                    break RustTarget::from_str(number).ok();
+                }
+            }) {
+                return current_rust;
+            }
+        }
+
+        // Bindgen from CLI, or cannot determine compiler version: default to
+        // generating bindings compatible with the latest stable release of Rust
+        // that Bindgen knows about.
+        LATEST_STABLE_RUST
+    }
+}
+
+impl fmt::Display for RustTarget {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.0 {
+            Version::Stable(minor, patch) => write!(f, "1.{minor}.{patch}"),
+            Version::Nightly => "nightly".fmt(f),
+        }
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+enum Version {
+    Stable(u64, u64),
+    Nightly,
+}
+
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub enum InvalidRustTarget {
+    TooEarly,
+}
+
+impl fmt::Display for InvalidRustTarget {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::TooEarly => write!(f, "the earliest Rust version supported by bindgen is {EARLIEST_STABLE_RUST}"),
+        }
+    }
+}
+
+/// This macro defines the Rust editions supported by bindgen.
+macro_rules! define_rust_editions {
+    ($($variant:ident($value:literal) => $minor:literal,)*) => {
+        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+        #[doc = "Represents Rust Edition for the generated bindings"]
+        pub enum RustEdition {
+            $(
+                #[doc = concat!("The ", stringify!($value), " edition of Rust.")]
+                $variant,
+            )*
+        }
+
+        impl FromStr for RustEdition {
+            type Err = InvalidRustEdition;
+
+            fn from_str(s: &str) -> Result<Self, Self::Err> {
+                match s {
+                    $(stringify!($value) => Ok(Self::$variant),)*
+                    _ => Err(InvalidRustEdition(s.to_owned())),
+                }
+            }
+        }
+
+        impl fmt::Display for RustEdition {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                match self {
+                    $(Self::$variant => stringify!($value).fmt(f),)*
+                }
+            }
+        }
+
+        impl RustEdition {
+            pub(crate) const ALL: [Self; [$($value,)*].len()] = [$(Self::$variant,)*];
+
+            pub(crate) fn is_available(self, target: RustTarget) -> bool {
+                let Some(minor) = target.minor() else {
+                    return true;
+                };
+
+                match self {
+                    $(Self::$variant => $minor <= minor,)*
+                }
+            }
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct InvalidRustEdition(String);
+
+impl fmt::Display for InvalidRustEdition {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "\"{}\" is not a valid Rust edition", self.0)
+    }
+}
+
+impl std::error::Error for InvalidRustEdition {}
+
+define_rust_editions! {
+    Edition2018(2018) => 31,
+    Edition2021(2021) => 56,
+    Edition2024(2024) => 85,
+}
+
+impl RustTarget {
+    /// Returns the latest edition supported by this target.
+    pub(crate) fn latest_edition(self) -> RustEdition {
+        RustEdition::ALL
+            .iter()
+            .rev()
+            .find(|edition| edition.is_available(self))
+            .copied()
+            .expect("bindgen should always support at least one edition")
+    }
+}
+
+impl Default for RustEdition {
+    fn default() -> Self {
+        RustTarget::default().latest_edition()
+    }
+}
+
 /// This macro defines the [`RustTarget`] and [`RustFeatures`] types.
 macro_rules! define_rust_targets {
     (
-        Nightly => {$($nightly_feature:ident $(: #$issue:literal)?),* $(,)?} $(,)?
+        Nightly => {$($nightly_feature:ident $(($nightly_edition:literal))|* $(: #$issue:literal)?),* $(,)?} $(,)?
         $(
-            $(#[$attrs:meta])*
-            $variant:ident($minor:literal) => {$($feature:ident $(: #$pull:literal)?),* $(,)?},
+            $variant:ident($minor:literal) => {$($feature:ident $(($edition:literal))|* $(: #$pull:literal)?),* $(,)?},
         )*
         $(,)?
     ) => {
-        /// Represents the version of the Rust language to target.
-        ///
-        /// To support a beta release, use the corresponding stable release.
-        ///
-        /// This enum will have more variants added as necessary.
-        #[allow(non_camel_case_types)]
-        #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-        pub enum RustTarget {
-            /// Rust Nightly
+
+        impl RustTarget {
+            /// The nightly version of Rust, which introduces the following features:"
             $(#[doc = concat!(
                 "- [`", stringify!($nightly_feature), "`]",
                 "(", $("https://github.com/rust-lang/rust/pull/", stringify!($issue),)* ")",
             )])*
-            Nightly,
+            #[deprecated = "The use of this constant is deprecated, please use `RustTarget::nightly` instead."]
+            pub const Nightly: Self = Self::nightly();
+
+            /// The nightly version of Rust, which introduces the following features:"
+            $(#[doc = concat!(
+                "- [`", stringify!($nightly_feature), "`]",
+                "(", $("https://github.com/rust-lang/rust/pull/", stringify!($issue),)* ")",
+            )])*
+            pub const fn nightly() -> Self {
+                Self(Version::Nightly)
+            }
+
             $(
-                #[doc = concat!("Rust 1.", stringify!($minor))]
+                #[doc = concat!("Version 1.", stringify!($minor), " of Rust, which introduced the following features:")]
                 $(#[doc = concat!(
                     "- [`", stringify!($feature), "`]",
                     "(", $("https://github.com/rust-lang/rust/pull/", stringify!($pull),)* ")",
                 )])*
-                $(#[$attrs])*
-                $variant,
+                #[deprecated = "The use of this constant is deprecated, please use `RustTarget::stable` instead."]
+                pub const $variant: Self = Self(Version::Stable($minor, 0));
             )*
-        }
 
-        impl RustTarget {
-            fn minor(self) -> Option<u64> {
-                match self {
-                    $( Self::$variant => Some($minor),)*
-                    Self::Nightly => None
-                }
-            }
-
             const fn stable_releases() -> [(Self, u64); [$($minor,)*].len()] {
                 [$((Self::$variant, $minor),)*]
             }
         }
 
-        #[cfg(feature = "__cli")]
-        /// Strings of allowed `RustTarget` values
-        pub const RUST_TARGET_STRINGS: &[&str] = &[$(concat!("1.", stringify!($minor)),)*];
-
         #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
         pub(crate) struct RustFeatures {
             $($(pub(crate) $feature: bool,)*)*
             $(pub(crate) $nightly_feature: bool,)*
         }
 
-        impl From<RustTarget> for RustFeatures {
-            fn from(target: RustTarget) -> Self {
-                if target == RustTarget::Nightly {
-                    return Self {
-                        $($($feature: true,)*)*
-                        $($nightly_feature: true,)*
-                    };
-                }
-
+        impl RustFeatures {
+            /// Compute the features that must be enabled in a specific Rust target with a specific edition.
+            pub(crate) fn new(target: RustTarget, edition: RustEdition) -> Self {
                 let mut features = Self {
                     $($($feature: false,)*)*
                     $($nightly_feature: false,)*
                 };
 
-                $(if target >= RustTarget::$variant {
-                    $(features.$feature = true;)*
-                })*
+                if target.is_compatible(&RustTarget::nightly()) {
+                    $(
+                        let editions: &[RustEdition] = &[$(stringify!($nightly_edition).parse::<RustEdition>().ok().expect("invalid edition"),)*];
 
+                        if editions.is_empty() || editions.contains(&edition) {
+                            features.$nightly_feature = true;
+                        }
+                    )*
+                }
+
+                $(
+                    if target.is_compatible(&RustTarget::$variant) {
+                        $(
+                            let editions: &[RustEdition] = &[$(stringify!($edition).parse::<RustEdition>().ok().expect("invalid edition"),)*];
+
+                            if editions.is_empty() || editions.contains(&edition) {
+                                features.$feature = true;
+                            }
+                        )*
+                    }
+                )*
+
                 features
             }
         }
@@ -95,43 +312,26 @@
 // not stable.
 define_rust_targets! {
     Nightly => {
-        vectorcall_abi,
+        vectorcall_abi: #124485,
+        ptr_metadata: #81513,
+        layout_for_ptr: #69835,
     },
+    Stable_1_82(82) => {
+        unsafe_extern_blocks: #127921,
+    },
+    Stable_1_77(77) => {
+        offset_of: #106655,
+        literal_cstr(2021)|(2024): #117472,
+    },
     Stable_1_73(73) => { thiscall_abi: #42202 },
     Stable_1_71(71) => { c_unwind_abi: #106075 },
     Stable_1_68(68) => { abi_efiapi: #105795 },
     Stable_1_64(64) => { core_ffi_c: #94503 },
     Stable_1_59(59) => { const_cstr: #54745 },
-    Stable_1_47(47) => { larger_arrays: #74060 },
-    Stable_1_40(40) => { non_exhaustive: #44109 },
-    Stable_1_36(36) => { maybe_uninit: #60445 },
-    Stable_1_33(33) => { repr_packed_n: #57049 },
-    #[deprecated]
-    Stable_1_30(30) => {
-        core_ffi_c_void: #53910,
-        min_const_fn: #54835,
-    },
-    #[deprecated]
-    Stable_1_28(28) => { repr_transparent: #51562 },
-    #[deprecated]
-    Stable_1_27(27) => { must_use_function: #48925 },
-    #[deprecated]
-    Stable_1_26(26) => { i128_and_u128: #49101 },
-    #[deprecated]
-    Stable_1_25(25) => { repr_align: #47006 },
-    #[deprecated]
-    Stable_1_21(21) => { builtin_clone_impls: #43690 },
-    #[deprecated]
-    Stable_1_20(20) => { associated_const: #42809 },
-    #[deprecated]
-    Stable_1_19(19) => { untagged_union: #42068 },
-    #[deprecated]
-    Stable_1_17(17) => { static_lifetime_elision: #39265 },
-    #[deprecated]
-    Stable_1_0(0) => {},
+    Stable_1_51(51) => {},
 }
 
-/// Latest stable release of Rust
+/// Latest stable release of Rust that is supported by bindgen
 pub const LATEST_STABLE_RUST: RustTarget = {
     // FIXME: replace all this code by
     // ```
@@ -139,7 +339,7 @@
     //     .into_iter()
     //     .max_by_key(|(_, m)| m)
     //     .map(|(t, _)| t)
-    //     .unwrap_or(RustTarget::Nightly)
+    //     .unwrap()
     // ```
     // once those operations can be used in constants.
     let targets = RustTarget::stable_releases();
@@ -165,132 +365,198 @@
     }
 };
 
-impl Default for RustTarget {
-    fn default() -> Self {
-        LATEST_STABLE_RUST
-    }
-}
+/// Earliest stable release of Rust that is supported by bindgen
+pub const EARLIEST_STABLE_RUST: RustTarget = {
+    // FIXME: replace all this code by
+    // ```
+    // RustTarget::stable_releases()
+    //     .into_iter()
+    //     .min_by_key(|(_, m)| m)
+    //     .map(|(t, _)| t)
+    //     .unwrap_or(LATEST_STABLE_RUST)
+    // ```
+    // once those operations can be used in constants.
+    let targets = RustTarget::stable_releases();
 
-impl PartialOrd for RustTarget {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
+    let mut i = 0;
+    let mut earliest_target = None;
+    let Some(mut earliest_minor) = LATEST_STABLE_RUST.minor() else {
+        unreachable!()
+    };
 
-impl Ord for RustTarget {
-    fn cmp(&self, other: &Self) -> Ordering {
-        match (self.minor(), other.minor()) {
-            (Some(a), Some(b)) => a.cmp(&b),
-            (Some(_), None) => Ordering::Less,
-            (None, Some(_)) => Ordering::Greater,
-            (None, None) => Ordering::Equal,
+    while i < targets.len() {
+        let (target, minor) = targets[i];
+
+        if earliest_minor > minor {
+            earliest_minor = minor;
+            earliest_target = Some(target);
         }
+
+        i += 1;
     }
+
+    match earliest_target {
+        Some(target) => target,
+        None => unreachable!(),
+    }
+};
+
+fn invalid_input(input: &str, msg: impl fmt::Display) -> io::Error {
+    io::Error::new(
+        io::ErrorKind::InvalidInput,
+        format!("\"{input}\" is not a valid Rust target, {msg}"),
+    )
 }
 
 impl FromStr for RustTarget {
     type Err = io::Error;
 
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        if s == "nightly" {
+    fn from_str(input: &str) -> Result<Self, Self::Err> {
+        if input == "nightly" {
             return Ok(Self::Nightly);
         }
 
-        if let Some(("1", str_minor)) = s.split_once('.') {
-            if let Ok(minor) = str_minor.parse::<u64>() {
-                for (target, target_minor) in Self::stable_releases() {
-                    if minor == target_minor {
-                        return Ok(target);
-                    }
-                }
-            }
+        let Some((major_str, tail)) = input.split_once('.') else {
+            return Err(invalid_input(input, "accepted values are of the form \"1.71\", \"1.71.1\" or \"nightly\"." ) );
+        };
+
+        if major_str != "1" {
+            return Err(invalid_input(
+                input,
+                "The largest major version of Rust released is \"1\"",
+            ));
         }
 
-        Err(io::Error::new(
-            io::ErrorKind::InvalidInput,
-            "Got an invalid Rust target. Accepted values are of the form \"1.71\" or \"nightly\"."
-        ))
+        let (minor, patch) = if let Some((minor_str, patch_str)) =
+            tail.split_once('.')
+        {
+            let Ok(minor) = minor_str.parse::<u64>() else {
+                return Err(invalid_input(input, "the minor version number must be an unsigned 64-bit integer"));
+            };
+            let Ok(patch) = patch_str.parse::<u64>() else {
+                return Err(invalid_input(input, "the patch version number must be an unsigned 64-bit integer"));
+            };
+            (minor, patch)
+        } else {
+            let Ok(minor) = tail.parse::<u64>() else {
+                return Err(invalid_input(input, "the minor version number must be an unsigned 64-bit integer"));
+            };
+            (minor, 0)
+        };
+
+        Self::stable(minor, patch).map_err(|err| invalid_input(input, err))
     }
 }
 
-impl std::fmt::Display for RustTarget {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        match self.minor() {
-            Some(minor) => write!(f, "1.{}", minor),
-            None => "nightly".fmt(f),
-        }
+impl RustFeatures {
+    /// Compute the features that must be enabled in a specific Rust target with the latest edition
+    /// available in that target.
+    pub(crate) fn new_with_latest_edition(target: RustTarget) -> Self {
+        Self::new(target, target.latest_edition())
     }
 }
 
 impl Default for RustFeatures {
     fn default() -> Self {
-        RustTarget::default().into()
+        Self::new_with_latest_edition(RustTarget::default())
     }
 }
 
 #[cfg(test)]
 mod test {
-    #![allow(unused_imports)]
     use super::*;
 
     #[test]
-    fn target_features() {
-        let f_1_0 = RustFeatures::from(RustTarget::Stable_1_0);
-        assert!(
-            !f_1_0.static_lifetime_elision &&
-                !f_1_0.core_ffi_c_void &&
-                !f_1_0.untagged_union &&
-                !f_1_0.associated_const &&
-                !f_1_0.builtin_clone_impls &&
-                !f_1_0.repr_align &&
-                !f_1_0.thiscall_abi &&
-                !f_1_0.vectorcall_abi
+    fn release_versions_for_editions() {
+        assert_eq!(
+            "1.51".parse::<RustTarget>().unwrap().latest_edition(),
+            RustEdition::Edition2018
         );
-        let f_1_21 = RustFeatures::from(RustTarget::Stable_1_21);
-        assert!(
-            f_1_21.static_lifetime_elision &&
-                !f_1_21.core_ffi_c_void &&
-                f_1_21.untagged_union &&
-                f_1_21.associated_const &&
-                f_1_21.builtin_clone_impls &&
-                !f_1_21.repr_align &&
-                !f_1_21.thiscall_abi &&
-                !f_1_21.vectorcall_abi
+        assert_eq!(
+            "1.59".parse::<RustTarget>().unwrap().latest_edition(),
+            RustEdition::Edition2021
         );
-        let features = RustFeatures::from(RustTarget::Stable_1_71);
+        assert_eq!(
+            "1.85".parse::<RustTarget>().unwrap().latest_edition(),
+            RustEdition::Edition2024
+        );
+        assert_eq!(
+            "nightly".parse::<RustTarget>().unwrap().latest_edition(),
+            RustEdition::Edition2024
+        );
+    }
+
+    #[test]
+    fn target_features() {
+        let features =
+            RustFeatures::new_with_latest_edition(RustTarget::Stable_1_71);
         assert!(
             features.c_unwind_abi &&
                 features.abi_efiapi &&
                 !features.thiscall_abi
         );
-        let f_nightly = RustFeatures::from(RustTarget::Nightly);
+
+        let features = RustFeatures::new(
+            RustTarget::Stable_1_77,
+            RustEdition::Edition2018,
+        );
+        assert!(!features.literal_cstr);
+
+        let features =
+            RustFeatures::new_with_latest_edition(RustTarget::Stable_1_77);
+        assert!(features.literal_cstr);
+
+        let f_nightly =
+            RustFeatures::new_with_latest_edition(RustTarget::Nightly);
         assert!(
-            f_nightly.static_lifetime_elision &&
-                f_nightly.core_ffi_c_void &&
-                f_nightly.untagged_union &&
-                f_nightly.associated_const &&
-                f_nightly.builtin_clone_impls &&
-                f_nightly.maybe_uninit &&
-                f_nightly.repr_align &&
-                f_nightly.thiscall_abi &&
-                f_nightly.vectorcall_abi
+            f_nightly.vectorcall_abi &&
+                f_nightly.ptr_metadata &&
+                f_nightly.layout_for_ptr
         );
     }
 
-    fn test_target(target_str: &str, target: RustTarget) {
-        let target_string = target.to_string();
-        assert_eq!(target_str, target_string);
-        assert_eq!(target, RustTarget::from_str(target_str).unwrap());
+    fn test_target(input: &str, expected: RustTarget) {
+        // Two targets are equivalent if they enable the same set of features
+        let expected = RustFeatures::new_with_latest_edition(expected);
+        let found = RustFeatures::new_with_latest_edition(
+            input.parse::<RustTarget>().unwrap(),
+        );
+        assert_eq!(
+            expected,
+            found,
+            "target {input} enables features:\n{found:#?}\nand should enable features:\n{expected:#?}"
+        );
     }
 
+    fn test_invalid_target(input: &str) {
+        assert!(
+            input.parse::<RustTarget>().is_err(),
+            "{input} should be an invalid target"
+        );
+    }
+
     #[test]
-    fn str_to_target() {
-        test_target("1.0", RustTarget::Stable_1_0);
-        test_target("1.17", RustTarget::Stable_1_17);
-        test_target("1.19", RustTarget::Stable_1_19);
-        test_target("1.21", RustTarget::Stable_1_21);
-        test_target("1.25", RustTarget::Stable_1_25);
+    fn valid_targets() {
         test_target("1.71", RustTarget::Stable_1_71);
+        test_target("1.71.0", RustTarget::Stable_1_71);
+        test_target("1.71.1", RustTarget::Stable_1_71);
+        test_target("1.72", RustTarget::Stable_1_71);
+        test_target("1.73", RustTarget::Stable_1_73);
+        test_target("1.18446744073709551615", LATEST_STABLE_RUST);
         test_target("nightly", RustTarget::Nightly);
+    }
+
+    #[test]
+    fn invalid_targets() {
+        test_invalid_target("2.0");
+        test_invalid_target("1.cat");
+        test_invalid_target("1.0.cat");
+        test_invalid_target("1.18446744073709551616");
+        test_invalid_target("1.0.18446744073709551616");
+        test_invalid_target("1.-1.0");
+        test_invalid_target("1.0.-1");
+        test_invalid_target("beta");
+        test_invalid_target("1.0.0");
+        test_invalid_target("1.32.0");
     }
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/derive.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/derive.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/derive.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/derive.rs	Mon May 11 04:49:32 2026
@@ -104,7 +104,7 @@
     }
 }
 
-impl<'ctx> CannotDerive<'ctx> {
+impl CannotDerive<'_> {
     fn insert<Id: Into<ItemId>>(
         &mut self,
         id: Id,
@@ -112,10 +112,8 @@
     ) -> ConstrainResult {
         let id = id.into();
         trace!(
-            "inserting {:?} can_derive<{}>={:?}",
-            id,
+            "inserting {id:?} can_derive<{}>={can_derive:?}",
             self.derive_trait,
-            can_derive
         );
 
         if let CanDerive::Yes = can_derive {
@@ -168,7 +166,7 @@
             return CanDerive::No;
         }
 
-        trace!("ty: {:?}", ty);
+        trace!("ty: {ty:?}");
         if item.is_opaque(self.ctx, &()) {
             if !self.derive_trait.can_derive_union() &&
                 ty.is_union() &&
@@ -181,26 +179,11 @@
                 return CanDerive::No;
             }
 
-            let layout_can_derive =
-                ty.layout(self.ctx).map_or(CanDerive::Yes, |l| {
-                    l.opaque().array_size_within_derive_limit(self.ctx)
-                });
-
-            match layout_can_derive {
-                CanDerive::Yes => {
-                    trace!(
-                        "    we can trivially derive {} for the layout",
-                        self.derive_trait
-                    );
-                }
-                _ => {
-                    trace!(
-                        "    we cannot derive {} for the layout",
-                        self.derive_trait
-                    );
-                }
-            };
-            return layout_can_derive;
+            trace!(
+                "    we can trivially derive {} for the layout",
+                self.derive_trait
+            );
+            return CanDerive::Yes;
         }
 
         match *ty.kind() {
@@ -217,9 +200,7 @@
             TypeKind::Reference(..) |
             TypeKind::ObjCInterface(..) |
             TypeKind::ObjCId |
-            TypeKind::ObjCSel => {
-                return self.derive_trait.can_derive_simple(ty.kind());
-            }
+            TypeKind::ObjCSel => self.derive_trait.can_derive_simple(ty.kind()),
             TypeKind::Pointer(inner) => {
                 let inner_type =
                     self.ctx.resolve_type(inner).canonical_type(self.ctx);
@@ -236,7 +217,7 @@
             // Complex cases need more information
             TypeKind::Array(t, len) => {
                 let inner_type =
-                    self.can_derive.get(&t.into()).cloned().unwrap_or_default();
+                    self.can_derive.get(&t.into()).copied().unwrap_or_default();
                 if inner_type != CanDerive::Yes {
                     trace!(
                         "    arrays of T for which we cannot derive {} \
@@ -275,7 +256,7 @@
             }
             TypeKind::Vector(t, len) => {
                 let inner_type =
-                    self.can_derive.get(&t.into()).cloned().unwrap_or_default();
+                    self.can_derive.get(&t.into()).copied().unwrap_or_default();
                 if inner_type != CanDerive::Yes {
                     trace!(
                         "    vectors of T for which we cannot derive {} \
@@ -342,26 +323,11 @@
                             return CanDerive::No;
                         }
 
-                        let layout_can_derive =
-                            ty.layout(self.ctx).map_or(CanDerive::Yes, |l| {
-                                l.opaque()
-                                    .array_size_within_derive_limit(self.ctx)
-                            });
-                        match layout_can_derive {
-                            CanDerive::Yes => {
-                                trace!(
-                                    "    union layout can trivially derive {}",
-                                    self.derive_trait
-                                );
-                            }
-                            _ => {
-                                trace!(
-                                    "    union layout cannot derive {}",
-                                    self.derive_trait
-                                );
-                            }
-                        };
-                        return layout_can_derive;
+                        trace!(
+                            "    union layout can trivially derive {}",
+                            self.derive_trait
+                        );
+                        return CanDerive::Yes;
                     }
                 }
 
@@ -431,13 +397,13 @@
 
                 let can_derive = self.can_derive
                     .get(&sub_id)
-                    .cloned()
+                    .copied()
                     .unwrap_or_default();
 
                 match can_derive {
-                    CanDerive::Yes => trace!("    member {:?} can derive {}", sub_id, self.derive_trait),
-                    CanDerive::Manually => trace!("    member {:?} cannot derive {}, but it may be implemented", sub_id, self.derive_trait),
-                    CanDerive::No => trace!("    member {:?} cannot derive {}", sub_id, self.derive_trait),
+                    CanDerive::Yes => trace!("    member {sub_id:?} can derive {}", self.derive_trait),
+                    CanDerive::Manually => trace!("    member {sub_id:?} cannot derive {}, but it may be implemented", self.derive_trait),
+                    CanDerive::No => trace!("    member {sub_id:?} cannot derive {}", self.derive_trait),
                 }
 
                 *candidate.get_or_insert(CanDerive::Yes) |= can_derive;
@@ -456,7 +422,7 @@
 }
 
 impl DeriveTrait {
-    fn not_by_name(&self, ctx: &BindgenContext, item: &Item) -> bool {
+    fn not_by_name(self, ctx: &BindgenContext, item: &Item) -> bool {
         match self {
             DeriveTrait::Copy => ctx.no_copy_by_name(item),
             DeriveTrait::Debug => ctx.no_debug_by_name(item),
@@ -468,21 +434,21 @@
         }
     }
 
-    fn consider_edge_comp(&self) -> EdgePredicate {
+    fn consider_edge_comp(self) -> EdgePredicate {
         match self {
             DeriveTrait::PartialEqOrPartialOrd => consider_edge_default,
             _ => |kind| matches!(kind, EdgeKind::BaseMember | EdgeKind::Field),
         }
     }
 
-    fn consider_edge_typeref(&self) -> EdgePredicate {
+    fn consider_edge_typeref(self) -> EdgePredicate {
         match self {
             DeriveTrait::PartialEqOrPartialOrd => consider_edge_default,
             _ => |kind| kind == EdgeKind::TypeReference,
         }
     }
 
-    fn consider_edge_tmpl_inst(&self) -> EdgePredicate {
+    fn consider_edge_tmpl_inst(self) -> EdgePredicate {
         match self {
             DeriveTrait::PartialEqOrPartialOrd => consider_edge_default,
             _ => |kind| {
@@ -494,31 +460,27 @@
         }
     }
 
-    fn can_derive_large_array(&self, ctx: &BindgenContext) -> bool {
-        if ctx.options().rust_features().larger_arrays {
-            !matches!(self, DeriveTrait::Default)
-        } else {
-            matches!(self, DeriveTrait::Copy)
-        }
+    fn can_derive_large_array(self, _: &BindgenContext) -> bool {
+        !matches!(self, DeriveTrait::Default)
     }
 
-    fn can_derive_union(&self) -> bool {
+    fn can_derive_union(self) -> bool {
         matches!(self, DeriveTrait::Copy)
     }
 
-    fn can_derive_compound_with_destructor(&self) -> bool {
+    fn can_derive_compound_with_destructor(self) -> bool {
         !matches!(self, DeriveTrait::Copy)
     }
 
-    fn can_derive_compound_with_vtable(&self) -> bool {
+    fn can_derive_compound_with_vtable(self) -> bool {
         !matches!(self, DeriveTrait::Default)
     }
 
-    fn can_derive_compound_forward_decl(&self) -> bool {
+    fn can_derive_compound_forward_decl(self) -> bool {
         matches!(self, DeriveTrait::Copy | DeriveTrait::Debug)
     }
 
-    fn can_derive_incomplete_array(&self) -> bool {
+    fn can_derive_incomplete_array(self) -> bool {
         !matches!(
             self,
             DeriveTrait::Copy |
@@ -527,63 +489,60 @@
         )
     }
 
-    fn can_derive_fnptr(&self, f: &FunctionSig) -> CanDerive {
+    fn can_derive_fnptr(self, f: &FunctionSig) -> CanDerive {
         match (self, f.function_pointers_can_derive()) {
-            (DeriveTrait::Copy, _) | (DeriveTrait::Default, _) | (_, true) => {
-                trace!("    function pointer can derive {}", self);
+            (DeriveTrait::Copy | DeriveTrait::Default, _) | (_, true) => {
+                trace!("    function pointer can derive {self}");
                 CanDerive::Yes
             }
             (DeriveTrait::Debug, false) => {
-                trace!("    function pointer cannot derive {}, but it may be implemented", self);
+                trace!("    function pointer cannot derive {self}, but it may be implemented");
                 CanDerive::Manually
             }
             (_, false) => {
-                trace!("    function pointer cannot derive {}", self);
+                trace!("    function pointer cannot derive {self}");
                 CanDerive::No
             }
         }
     }
 
-    fn can_derive_vector(&self) -> CanDerive {
-        match self {
-            DeriveTrait::PartialEqOrPartialOrd => {
-                // FIXME: vectors always can derive PartialEq, but they should
-                // not derive PartialOrd:
-                // https://github.com/rust-lang-nursery/packed_simd/issues/48
-                trace!("    vectors cannot derive PartialOrd");
-                CanDerive::No
-            }
-            _ => {
-                trace!("    vector can derive {}", self);
-                CanDerive::Yes
-            }
+    fn can_derive_vector(self) -> CanDerive {
+        if self == DeriveTrait::PartialEqOrPartialOrd {
+            // FIXME: vectors always can derive PartialEq, but they should
+            // not derive PartialOrd:
+            // https://github.com/rust-lang-nursery/packed_simd/issues/48
+            trace!("    vectors cannot derive PartialOrd");
+            CanDerive::No
+        } else {
+            trace!("    vector can derive {self}");
+            CanDerive::Yes
         }
     }
 
-    fn can_derive_pointer(&self) -> CanDerive {
-        match self {
-            DeriveTrait::Default => {
-                trace!("    pointer cannot derive Default");
-                CanDerive::No
-            }
-            _ => {
-                trace!("    pointer can derive {}", self);
-                CanDerive::Yes
-            }
+    fn can_derive_pointer(self) -> CanDerive {
+        if self == DeriveTrait::Default {
+            trace!("    pointer cannot derive Default");
+            CanDerive::No
+        } else {
+            trace!("    pointer can derive {self}");
+            CanDerive::Yes
         }
     }
 
-    fn can_derive_simple(&self, kind: &TypeKind) -> CanDerive {
+    fn can_derive_simple(self, kind: &TypeKind) -> CanDerive {
         match (self, kind) {
             // === Default ===
-            (DeriveTrait::Default, TypeKind::Void) |
-            (DeriveTrait::Default, TypeKind::NullPtr) |
-            (DeriveTrait::Default, TypeKind::Enum(..)) |
-            (DeriveTrait::Default, TypeKind::Reference(..)) |
-            (DeriveTrait::Default, TypeKind::TypeParam) |
-            (DeriveTrait::Default, TypeKind::ObjCInterface(..)) |
-            (DeriveTrait::Default, TypeKind::ObjCId) |
-            (DeriveTrait::Default, TypeKind::ObjCSel) => {
+            (
+                DeriveTrait::Default,
+                TypeKind::Void |
+                TypeKind::NullPtr |
+                TypeKind::Enum(..) |
+                TypeKind::Reference(..) |
+                TypeKind::TypeParam |
+                TypeKind::ObjCInterface(..) |
+                TypeKind::ObjCId |
+                TypeKind::ObjCSel,
+            ) => {
                 trace!("    types that always cannot derive Default");
                 CanDerive::No
             }
@@ -593,14 +552,16 @@
                 )
             }
             // === Hash ===
-            (DeriveTrait::Hash, TypeKind::Float(..)) |
-            (DeriveTrait::Hash, TypeKind::Complex(..)) => {
+            (
+                DeriveTrait::Hash,
+                TypeKind::Float(..) | TypeKind::Complex(..),
+            ) => {
                 trace!("    float cannot derive Hash");
                 CanDerive::No
             }
             // === others ===
             _ => {
-                trace!("    simple type that can always derive {}", self);
+                trace!("    simple type that can always derive {self}");
                 CanDerive::Yes
             }
         }
@@ -645,7 +606,7 @@
         self.ctx
             .allowlisted_items()
             .iter()
-            .cloned()
+            .copied()
             .flat_map(|i| {
                 let mut reachable = vec![i];
                 i.trace(
@@ -661,9 +622,9 @@
     }
 
     fn constrain(&mut self, id: ItemId) -> ConstrainResult {
-        trace!("constrain: {:?}", id);
+        trace!("constrain: {id:?}");
 
-        if let Some(CanDerive::No) = self.can_derive.get(&id).cloned() {
+        if let Some(CanDerive::No) = self.can_derive.get(&id) {
             trace!("    already know it cannot derive {}", self.derive_trait);
             return ConstrainResult::Same;
         }
@@ -676,7 +637,7 @@
                     let is_reached_limit =
                         |l: Layout| l.align > RUST_DERIVE_IN_ARRAY_LIMIT;
                     if !self.derive_trait.can_derive_large_array(self.ctx) &&
-                        ty.layout(self.ctx).map_or(false, is_reached_limit)
+                        ty.layout(self.ctx).is_some_and(is_reached_limit)
                     {
                         // We have to be conservative: the struct *could* have enough
                         // padding that we emit an array that is longer than
@@ -700,7 +661,7 @@
     {
         if let Some(edges) = self.dependencies.get(&id) {
             for item in edges {
-                trace!("enqueue {:?} into worklist", item);
+                trace!("enqueue {item:?} into worklist");
                 f(*item);
             }
         }
@@ -727,6 +688,6 @@
 ) -> HashSet<ItemId> {
     can_derive
         .into_iter()
-        .filter_map(|(k, v)| if v != CanDerive::Yes { Some(k) } else { None })
+        .filter_map(|(k, v)| if v == CanDerive::Yes { None } else { Some(k) })
         .collect()
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_destructor.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_destructor.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_destructor.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_destructor.rs	Mon May 11 04:49:32 2026
@@ -39,7 +39,7 @@
     dependencies: HashMap<ItemId, Vec<ItemId>>,
 }
 
-impl<'ctx> HasDestructorAnalysis<'ctx> {
+impl HasDestructorAnalysis<'_> {
     fn consider_edge(kind: EdgeKind) -> bool {
         // These are the only edges that can affect whether a type has a
         // destructor or not.
@@ -58,9 +58,8 @@
         let was_not_already_in_set = self.have_destructor.insert(id);
         assert!(
             was_not_already_in_set,
-            "We shouldn't try and insert {:?} twice because if it was \
-             already in the set, `constrain` should have exited early.",
-            id
+            "We shouldn't try and insert {id:?} twice because if it was \
+             already in the set, `constrain` should have exited early."
         );
         ConstrainResult::Changed
     }
@@ -83,7 +82,7 @@
     }
 
     fn initial_worklist(&self) -> Vec<ItemId> {
-        self.ctx.allowlisted_items().iter().cloned().collect()
+        self.ctx.allowlisted_items().iter().copied().collect()
     }
 
     fn constrain(&mut self, id: ItemId) -> ConstrainResult {
@@ -94,9 +93,8 @@
         }
 
         let item = self.ctx.resolve_item(id);
-        let ty = match item.as_type() {
-            None => return ConstrainResult::Same,
-            Some(ty) => ty,
+        let Some(ty) = item.as_type() else {
+            return ConstrainResult::Same;
         };
 
         match *ty.kind() {
@@ -162,7 +160,7 @@
     {
         if let Some(edges) = self.dependencies.get(&id) {
             for item in edges {
-                trace!("enqueue {:?} into worklist", item);
+                trace!("enqueue {item:?} into worklist");
                 f(*item);
             }
         }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_float.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_float.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_float.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_float.rs	Mon May 11 04:49:32 2026
@@ -39,7 +39,7 @@
     dependencies: HashMap<ItemId, Vec<ItemId>>,
 }
 
-impl<'ctx> HasFloat<'ctx> {
+impl HasFloat<'_> {
     fn consider_edge(kind: EdgeKind) -> bool {
         match kind {
             EdgeKind::BaseMember |
@@ -56,21 +56,20 @@
             EdgeKind::FunctionParameter |
             EdgeKind::InnerType |
             EdgeKind::InnerVar |
-            EdgeKind::Method => false,
+            EdgeKind::Method |
             EdgeKind::Generic => false,
         }
     }
 
     fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
         let id = id.into();
-        trace!("inserting {:?} into the has_float set", id);
+        trace!("inserting {id:?} into the has_float set");
 
         let was_not_already_in_set = self.has_float.insert(id);
         assert!(
             was_not_already_in_set,
-            "We shouldn't try and insert {:?} twice because if it was \
-             already in the set, `constrain` should have exited early.",
-            id
+            "We shouldn't try and insert {id:?} twice because if it was \
+             already in the set, `constrain` should have exited early."
         );
 
         ConstrainResult::Changed
@@ -94,11 +93,11 @@
     }
 
     fn initial_worklist(&self) -> Vec<ItemId> {
-        self.ctx.allowlisted_items().iter().cloned().collect()
+        self.ctx.allowlisted_items().iter().copied().collect()
     }
 
     fn constrain(&mut self, id: ItemId) -> ConstrainResult {
-        trace!("constrain: {:?}", id);
+        trace!("constrain: {id:?}");
 
         if self.has_float.contains(&id) {
             trace!("    already know it do not have float");
@@ -106,12 +105,9 @@
         }
 
         let item = self.ctx.resolve_item(id);
-        let ty = match item.as_type() {
-            Some(ty) => ty,
-            None => {
-                trace!("    not a type; ignoring");
-                return ConstrainResult::Same;
-            }
+        let Some(ty) = item.as_type() else {
+            trace!("    not a type; ignoring");
+            return ConstrainResult::Same;
         };
 
         match *ty.kind() {
@@ -210,7 +206,7 @@
                 if args_have {
                     trace!(
                         "    template args have float, so \
-                         insantiation also has float"
+                         instantiation also has float"
                     );
                     return self.insert(id);
                 }
@@ -221,7 +217,7 @@
                 if def_has {
                     trace!(
                         "    template definition has float, so \
-                         insantiation also has"
+                         instantiation also has"
                     );
                     return self.insert(id);
                 }
@@ -238,7 +234,7 @@
     {
         if let Some(edges) = self.dependencies.get(&id) {
             for item in edges {
-                trace!("enqueue {:?} into worklist", item);
+                trace!("enqueue {item:?} into worklist");
                 f(*item);
             }
         }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_type_param_in_array.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_type_param_in_array.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_type_param_in_array.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_type_param_in_array.rs	Mon May 11 04:49:32 2026
@@ -17,7 +17,7 @@
 /// * If T is a type alias, a templated alias or an indirection to another type,
 ///   it has type parameter in array if the type T refers to has.
 /// * If T is a compound type, it has array if any of base memter or field
-///   has type paramter in array.
+///   has type parameter in array.
 /// * If T is an instantiation of an abstract template definition, T has
 ///   type parameter in array if any of the template arguments or template definition
 ///   has.
@@ -39,7 +39,7 @@
     dependencies: HashMap<ItemId, Vec<ItemId>>,
 }
 
-impl<'ctx> HasTypeParameterInArray<'ctx> {
+impl HasTypeParameterInArray<'_> {
     fn consider_edge(kind: EdgeKind) -> bool {
         match kind {
             // These are the only edges that can affect whether a type has type parameter
@@ -58,25 +58,21 @@
             EdgeKind::FunctionParameter |
             EdgeKind::InnerType |
             EdgeKind::InnerVar |
-            EdgeKind::Method => false,
+            EdgeKind::Method |
             EdgeKind::Generic => false,
         }
     }
 
     fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
         let id = id.into();
-        trace!(
-            "inserting {:?} into the has_type_parameter_in_array set",
-            id
-        );
+        trace!("inserting {id:?} into the has_type_parameter_in_array set");
 
         let was_not_already_in_set =
             self.has_type_parameter_in_array.insert(id);
         assert!(
             was_not_already_in_set,
-            "We shouldn't try and insert {:?} twice because if it was \
-             already in the set, `constrain` should have exited early.",
-            id
+            "We shouldn't try and insert {id:?} twice because if it was \
+             already in the set, `constrain` should have exited early."
         );
 
         ConstrainResult::Changed
@@ -100,11 +96,11 @@
     }
 
     fn initial_worklist(&self) -> Vec<ItemId> {
-        self.ctx.allowlisted_items().iter().cloned().collect()
+        self.ctx.allowlisted_items().iter().copied().collect()
     }
 
     fn constrain(&mut self, id: ItemId) -> ConstrainResult {
-        trace!("constrain: {:?}", id);
+        trace!("constrain: {id:?}");
 
         if self.has_type_parameter_in_array.contains(&id) {
             trace!("    already know it do not have array");
@@ -112,12 +108,9 @@
         }
 
         let item = self.ctx.resolve_item(id);
-        let ty = match item.as_type() {
-            Some(ty) => ty,
-            None => {
-                trace!("    not a type; ignoring");
-                return ConstrainResult::Same;
-            }
+        let Some(ty) = item.as_type() else {
+            trace!("    not a type; ignoring");
+            return ConstrainResult::Same;
         };
 
         match *ty.kind() {
@@ -146,17 +139,14 @@
             TypeKind::Array(t, _) => {
                 let inner_ty =
                     self.ctx.resolve_type(t).canonical_type(self.ctx);
-                match *inner_ty.kind() {
-                    TypeKind::TypeParam => {
-                        trace!("    Array with Named type has type parameter");
-                        self.insert(id)
-                    }
-                    _ => {
-                        trace!(
-                            "    Array without Named type does have type parameter"
-                        );
-                        ConstrainResult::Same
-                    }
+                if let TypeKind::TypeParam = *inner_ty.kind() {
+                    trace!("    Array with Named type has type parameter");
+                    self.insert(id)
+                } else {
+                    trace!(
+                        "    Array without Named type does have type parameter"
+                    );
+                    ConstrainResult::Same
                 }
             }
 
@@ -210,7 +200,7 @@
                 if args_have {
                     trace!(
                         "    template args have array, so \
-                         insantiation also has array"
+                         instantiation also has array"
                     );
                     return self.insert(id);
                 }
@@ -221,7 +211,7 @@
                 if def_has {
                     trace!(
                         "    template definition has array, so \
-                         insantiation also has"
+                         instantiation also has"
                     );
                     return self.insert(id);
                 }
@@ -238,7 +228,7 @@
     {
         if let Some(edges) = self.dependencies.get(&id) {
             for item in edges {
-                trace!("enqueue {:?} into worklist", item);
+                trace!("enqueue {item:?} into worklist");
                 f(*item);
             }
         }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_vtable.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_vtable.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/has_vtable.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/has_vtable.rs	Mon May 11 04:49:32 2026
@@ -9,9 +9,10 @@
 use std::ops;
 
 /// The result of the `HasVtableAnalysis` for an individual item.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
 pub(crate) enum HasVtableResult {
     /// The item does not have a vtable pointer.
+    #[default]
     No,
 
     /// The item has a vtable and the actual vtable pointer is within this item.
@@ -22,12 +23,6 @@
     BaseHasVtable,
 }
 
-impl Default for HasVtableResult {
-    fn default() -> Self {
-        HasVtableResult::No
-    }
-}
-
 impl HasVtableResult {
     /// Take the least upper bound of `self` and `rhs`.
     pub(crate) fn join(self, rhs: Self) -> Self {
@@ -45,7 +40,7 @@
 
 impl ops::BitOrAssign for HasVtableResult {
     fn bitor_assign(&mut self, rhs: HasVtableResult) {
-        *self = self.join(rhs)
+        *self = self.join(rhs);
     }
 }
 
@@ -77,7 +72,7 @@
     dependencies: HashMap<ItemId, Vec<ItemId>>,
 }
 
-impl<'ctx> HasVtableAnalysis<'ctx> {
+impl HasVtableAnalysis<'_> {
     fn consider_edge(kind: EdgeKind) -> bool {
         // These are the only edges that can affect whether a type has a
         // vtable or not.
@@ -123,9 +118,9 @@
         let from = from.into();
         let to = to.into();
 
-        match self.have_vtable.get(&from).cloned() {
+        match self.have_vtable.get(&from) {
             None => ConstrainResult::Same,
-            Some(r) => self.insert(to, r),
+            Some(r) => self.insert(to, *r),
         }
     }
 }
@@ -147,16 +142,15 @@
     }
 
     fn initial_worklist(&self) -> Vec<ItemId> {
-        self.ctx.allowlisted_items().iter().cloned().collect()
+        self.ctx.allowlisted_items().iter().copied().collect()
     }
 
     fn constrain(&mut self, id: ItemId) -> ConstrainResult {
-        trace!("constrain {:?}", id);
+        trace!("constrain {id:?}");
 
         let item = self.ctx.resolve_item(id);
-        let ty = match item.as_type() {
-            None => return ConstrainResult::Same,
-            Some(ty) => ty,
+        let Some(ty) = item.as_type() else {
+            return ConstrainResult::Same;
         };
 
         // TODO #851: figure out a way to handle deriving from template type parameters.
@@ -181,7 +175,7 @@
                 }
 
                 let bases_has_vtable = info.base_members().iter().any(|base| {
-                    trace!("    comp has a base with a vtable: {:?}", base);
+                    trace!("    comp has a base with a vtable: {base:?}");
                     self.have_vtable.contains_key(&base.ty.into())
                 });
                 if bases_has_vtable {
@@ -205,7 +199,7 @@
     {
         if let Some(edges) = self.dependencies.get(&id) {
             for item in edges {
-                trace!("enqueue {:?} into worklist", item);
+                trace!("enqueue {item:?} into worklist");
                 f(*item);
             }
         }
@@ -228,7 +222,7 @@
 /// vtable during codegen.
 ///
 /// This is not for _computing_ whether the thing has a vtable, it is for
-/// looking up the results of the HasVtableAnalysis's computations for a
+/// looking up the results of the `HasVtableAnalysis`'s computations for a
 /// specific thing.
 pub(crate) trait HasVtable {
     /// Return `true` if this thing has vtable, `false` otherwise.
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/mod.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/mod.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/mod.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/mod.rs	Mon May 11 04:49:32 2026
@@ -125,22 +125,17 @@
 
 /// Whether an analysis's `constrain` function modified the incremental results
 /// or not.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
 pub(crate) enum ConstrainResult {
     /// The incremental results were updated, and the fix-point computation
     /// should continue.
     Changed,
 
     /// The incremental results were not updated.
+    #[default]
     Same,
 }
 
-impl Default for ConstrainResult {
-    fn default() -> Self {
-        ConstrainResult::Same
-    }
-}
-
 impl ops::BitOr for ConstrainResult {
     type Output = Self;
 
@@ -216,7 +211,7 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::{HashMap, HashSet};
+    use crate::HashSet;
 
     // Here we find the set of nodes that are reachable from any given
     // node. This is a lattice mapping nodes to subsets of all nodes. Our join
@@ -285,9 +280,9 @@
 
         fn reverse(&self) -> Graph {
             let mut reversed = Graph::default();
-            for (node, edges) in self.0.iter() {
+            for (node, edges) in &self.0 {
                 reversed.0.entry(*node).or_insert_with(Vec::new);
-                for referent in edges.iter() {
+                for referent in edges {
                     reversed
                         .0
                         .entry(*referent)
@@ -311,7 +306,7 @@
         type Extra = &'a Graph;
         type Output = HashMap<Node, HashSet<Node>>;
 
-        fn new(graph: &'a Graph) -> ReachableFrom {
+        fn new(graph: &'a Graph) -> Self {
             let reversed = graph.reverse();
             ReachableFrom {
                 reachable: Default::default(),
@@ -321,7 +316,7 @@
         }
 
         fn initial_worklist(&self) -> Vec<Node> {
-            self.graph.0.keys().cloned().collect()
+            self.graph.0.keys().copied().collect()
         }
 
         fn constrain(&mut self, node: Node) -> ConstrainResult {
@@ -336,7 +331,7 @@
 
             let original_size = self.reachable.entry(node).or_default().len();
 
-            for sub_node in self.graph.0[&node].iter() {
+            for sub_node in &self.graph.0[&node] {
                 self.reachable.get_mut(&node).unwrap().insert(*sub_node);
 
                 let sub_reachable =
@@ -348,10 +343,10 @@
             }
 
             let new_size = self.reachable[&node].len();
-            if original_size != new_size {
-                ConstrainResult::Changed
-            } else {
+            if original_size == new_size {
                 ConstrainResult::Same
+            } else {
+                ConstrainResult::Changed
             }
         }
 
@@ -359,7 +354,7 @@
         where
             F: FnMut(Node),
         {
-            for dep in self.reversed.0[&node].iter() {
+            for dep in &self.reversed.0[&node] {
                 f(*dep);
             }
         }
@@ -375,13 +370,13 @@
     fn monotone() {
         let g = Graph::make_test_graph();
         let reachable = analyze::<ReachableFrom>(&g);
-        println!("reachable = {:#?}", reachable);
+        println!("reachable = {reachable:#?}");
 
         fn nodes<A>(nodes: A) -> HashSet<Node>
         where
             A: AsRef<[usize]>,
         {
-            nodes.as_ref().iter().cloned().map(Node).collect()
+            nodes.as_ref().iter().copied().map(Node).collect()
         }
 
         let mut expected = HashMap::default();
@@ -393,7 +388,7 @@
         expected.insert(Node(6), nodes([8]));
         expected.insert(Node(7), nodes([3, 4, 5, 6, 7, 8]));
         expected.insert(Node(8), nodes([]));
-        println!("expected = {:#?}", expected);
+        println!("expected = {expected:#?}");
 
         assert_eq!(reachable, expected);
     }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/sizedness.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/sizedness.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/sizedness.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/sizedness.rs	Mon May 11 04:49:32 2026
@@ -24,13 +24,14 @@
 ///
 /// We initially assume that all types are `ZeroSized` and then update our
 /// understanding as we learn more about each type.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
 pub(crate) enum SizednessResult {
     /// The type is zero-sized.
     ///
     /// This means that if it is a C++ type, and is not being used as a base
     /// member, then we must add an `_address` byte to enforce the
     /// unique-address-per-distinct-object-instance rule.
+    #[default]
     ZeroSized,
 
     /// Whether this type is zero-sized or not depends on whether a type
@@ -62,12 +63,6 @@
     NonZeroSized,
 }
 
-impl Default for SizednessResult {
-    fn default() -> Self {
-        SizednessResult::ZeroSized
-    }
-}
-
 impl SizednessResult {
     /// Take the least upper bound of `self` and `rhs`.
     pub(crate) fn join(self, rhs: Self) -> Self {
@@ -85,20 +80,20 @@
 
 impl ops::BitOrAssign for SizednessResult {
     fn bitor_assign(&mut self, rhs: SizednessResult) {
-        *self = self.join(rhs)
+        *self = self.join(rhs);
     }
 }
 
 /// An analysis that computes the sizedness of all types.
 ///
 /// * For types with known sizes -- for example pointers, scalars, etc... --
-/// they are assigned `NonZeroSized`.
+///   they are assigned `NonZeroSized`.
 ///
 /// * For compound structure types with one or more fields, they are assigned
-/// `NonZeroSized`.
+///   `NonZeroSized`.
 ///
 /// * For compound structure types without any fields, the results of the bases
-/// are `join`ed.
+///   are `join`ed.
 ///
 /// * For type parameters, `DependsOnTypeParam` is assigned.
 #[derive(Debug)]
@@ -110,7 +105,7 @@
     sized: HashMap<TypeId, SizednessResult>,
 }
 
-impl<'ctx> SizednessAnalysis<'ctx> {
+impl SizednessAnalysis<'_> {
     fn consider_edge(kind: EdgeKind) -> bool {
         // These are the only edges that can affect whether a type is
         // zero-sized or not.
@@ -132,7 +127,7 @@
         id: TypeId,
         result: SizednessResult,
     ) -> ConstrainResult {
-        trace!("inserting {:?} for {:?}", result, id);
+        trace!("inserting {result:?} for {id:?}");
 
         if let SizednessResult::ZeroSized = result {
             return ConstrainResult::Same;
@@ -155,9 +150,9 @@
     }
 
     fn forward(&mut self, from: TypeId, to: TypeId) -> ConstrainResult {
-        match self.sized.get(&from).cloned() {
+        match self.sized.get(&from) {
             None => ConstrainResult::Same,
-            Some(r) => self.insert(to, r),
+            Some(r) => self.insert(to, *r),
         }
     }
 }
@@ -196,17 +191,14 @@
         self.ctx
             .allowlisted_items()
             .iter()
-            .cloned()
             .filter_map(|id| id.as_type_id(self.ctx))
             .collect()
     }
 
     fn constrain(&mut self, id: TypeId) -> ConstrainResult {
-        trace!("constrain {:?}", id);
+        trace!("constrain {id:?}");
 
-        if let Some(SizednessResult::NonZeroSized) =
-            self.sized.get(&id).cloned()
-        {
+        if let Some(SizednessResult::NonZeroSized) = self.sized.get(&id) {
             trace!("    already know it is not zero-sized");
             return ConstrainResult::Same;
         }
@@ -327,7 +319,7 @@
     {
         if let Some(edges) = self.dependencies.get(&id) {
             for ty in edges {
-                trace!("enqueue {:?} into worklist", ty);
+                trace!("enqueue {ty:?} into worklist");
                 f(*ty);
             }
         }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/template_params.rs firefox-140.10.2/third_party/rust/bindgen/ir/analysis/template_params.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/analysis/template_params.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/analysis/template_params.rs	Mon May 11 04:49:32 2026
@@ -124,8 +124,8 @@
 /// ```
 ///
 /// * Finally, for all other IR item kinds, we use our lattice's `join`
-/// operation: set union with each successor of the given item's template
-/// parameter usage:
+///   operation: set union with each successor of the given item's template
+///   parameter usage:
 ///
 /// ```ignore
 /// template_param_usage(v) =
@@ -161,7 +161,7 @@
     allowlisted_items: HashSet<ItemId>,
 }
 
-impl<'ctx> UsedTemplateParameters<'ctx> {
+impl UsedTemplateParameters<'_> {
     fn consider_edge(kind: EdgeKind) -> bool {
         match kind {
             // For each of these kinds of edges, if the referent uses a template
@@ -259,7 +259,6 @@
                          a's used template param set should be `Some`",
                     )
                     .iter()
-                    .cloned()
             });
 
         used_by_this_id.extend(args);
@@ -291,10 +290,8 @@
 
         for (arg, param) in args.iter().zip(params.iter()) {
             trace!(
-                "      instantiation's argument {:?} is used if definition's \
-                 parameter {:?} is used",
-                arg,
-                param
+                "      instantiation's argument {arg:?} is used if definition's \
+                 parameter {param:?} is used",
             );
 
             if used_by_def.contains(&param.into()) {
@@ -322,8 +319,7 @@
                          arg's used template param set should be \
                          `Some`",
                     )
-                    .iter()
-                    .cloned();
+                    .iter();
                 used_by_this_id.extend(used_by_arg);
             }
         }
@@ -355,12 +351,10 @@
                          sub_id's used template param set should be \
                          `Some`",
                     )
-                    .iter()
-                    .cloned();
+                    .iter();
 
                 trace!(
-                    "      union with {:?}'s usage: {:?}",
-                    sub_id,
+                    "      union with {sub_id:?}'s usage: {:?}",
                     used_by_sub_id.clone().collect::<Vec<_>>()
                 );
 
@@ -380,11 +374,11 @@
         let mut used = HashMap::default();
         let mut dependencies = HashMap::default();
         let allowlisted_items: HashSet<_> =
-            ctx.allowlisted_items().iter().cloned().collect();
+            ctx.allowlisted_items().iter().copied().collect();
 
         let allowlisted_and_blocklisted_items: ItemSet = allowlisted_items
             .iter()
-            .cloned()
+            .copied()
             .flat_map(|i| {
                 let mut reachable = vec![i];
                 i.trace(
@@ -470,7 +464,7 @@
             // (This is so that every item we call `constrain` on is guaranteed
             // to have a set of template parameters, and we can allow
             // blocklisted templates to use all of their parameters).
-            for item in allowlisted_items.iter() {
+            for item in &allowlisted_items {
                 extra_assert!(used.contains_key(item));
                 extra_assert!(dependencies.contains_key(item));
                 item.trace(
@@ -480,7 +474,7 @@
                         extra_assert!(dependencies.contains_key(&sub_item));
                     },
                     &(),
-                )
+                );
             }
         }
 
@@ -498,7 +492,7 @@
         self.ctx
             .allowlisted_items()
             .iter()
-            .cloned()
+            .copied()
             .flat_map(|i| {
                 let mut reachable = vec![i];
                 i.trace(
@@ -524,8 +518,8 @@
         // an analog to slice::split_at_mut.
         let mut used_by_this_id = self.take_this_id_usage_set(id);
 
-        trace!("constrain {:?}", id);
-        trace!("  initially, used set is {:?}", used_by_this_id);
+        trace!("constrain {id:?}");
+        trace!("  initially, used set is {used_by_this_id:?}");
 
         let original_len = used_by_this_id.len();
 
@@ -562,7 +556,7 @@
             _ => self.constrain_join(&mut used_by_this_id, item),
         }
 
-        trace!("  finally, used set is {:?}", used_by_this_id);
+        trace!("  finally, used set is {used_by_this_id:?}");
 
         let new_len = used_by_this_id.len();
         assert!(
@@ -576,10 +570,10 @@
         self.used.insert(id, Some(used_by_this_id));
         extra_assert!(self.used.values().all(|v| v.is_some()));
 
-        if new_len != original_len {
-            ConstrainResult::Changed
-        } else {
+        if new_len == original_len {
             ConstrainResult::Same
+        } else {
+            ConstrainResult::Changed
         }
     }
 
@@ -589,7 +583,7 @@
     {
         if let Some(edges) = self.dependencies.get(&item) {
             for item in edges {
-                trace!("enqueue {:?} into worklist", item);
+                trace!("enqueue {item:?} into worklist");
                 f(*item);
             }
         }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/annotations.rs firefox-140.10.2/third_party/rust/bindgen/ir/annotations.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/annotations.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/annotations.rs	Mon May 11 04:49:32 2026
@@ -8,14 +8,15 @@
 
 use crate::clang;
 
-/// What kind of visibility modifer should be used for a struct or field?
-#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
+/// What kind of visibility modifier should be used for a struct or field?
+#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Default)]
 pub enum FieldVisibilityKind {
     /// Fields are marked as private, i.e., struct Foo {bar: bool}
     Private,
     /// Fields are marked as crate public, i.e., struct Foo {pub(crate) bar: bool}
     PublicCrate,
     /// Fields are marked as public, i.e., struct Foo {pub bar: bool}
+    #[default]
     Public,
 }
 
@@ -27,7 +28,7 @@
             "private" => Ok(Self::Private),
             "crate" => Ok(Self::PublicCrate),
             "public" => Ok(Self::Public),
-            _ => Err(format!("Invalid visibility kind: `{}`", s)),
+            _ => Err(format!("Invalid visibility kind: `{s}`")),
         }
     }
 }
@@ -44,12 +45,6 @@
     }
 }
 
-impl Default for FieldVisibilityKind {
-    fn default() -> Self {
-        FieldVisibilityKind::Public
-    }
-}
-
 /// What kind of accessor should we provide for a field?
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
 pub(crate) enum FieldAccessorKind {
@@ -107,6 +102,8 @@
     constify_enum_variant: bool,
     /// List of explicit derives for this type.
     derives: Vec<String>,
+    /// List of explicit attributes for this type.
+    attributes: Vec<String>,
 }
 
 fn parse_accessor(s: &str) -> FieldAccessorKind {
@@ -174,6 +171,11 @@
         &self.derives
     }
 
+    /// The list of attributes that have been specified in this annotation.
+    pub(crate) fn attributes(&self) -> &[String] {
+        &self.attributes
+    }
+
     /// Should we avoid implementing the `Copy` trait?
     pub(crate) fn disallow_copy(&self) -> bool {
         self.disallow_copy
@@ -211,7 +213,7 @@
             comment
                 .get_tag_attrs()
                 .next()
-                .map_or(false, |attr| attr.name == "rustbindgen")
+                .is_some_and(|attr| attr.name == "rustbindgen")
         {
             *matched = true;
             for attr in comment.get_tag_attrs() {
@@ -225,18 +227,19 @@
                     "replaces" => {
                         self.use_instead_of = Some(
                             attr.value.split("::").map(Into::into).collect(),
-                        )
+                        );
                     }
                     "derive" => self.derives.push(attr.value),
+                    "attribute" => self.attributes.push(attr.value),
                     "private" => {
-                        self.visibility_kind = if attr.value != "false" {
-                            Some(FieldVisibilityKind::Private)
-                        } else {
+                        self.visibility_kind = if attr.value == "false" {
                             Some(FieldVisibilityKind::Public)
+                        } else {
+                            Some(FieldVisibilityKind::Private)
                         };
                     }
                     "accessor" => {
-                        self.accessor_kind = Some(parse_accessor(&attr.value))
+                        self.accessor_kind = Some(parse_accessor(&attr.value));
                     }
                     "constant" => self.constify_enum_variant = true,
                     _ => {}
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/comment.rs firefox-140.10.2/third_party/rust/bindgen/ir/comment.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/comment.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/comment.rs	Mon May 11 04:49:32 2026
@@ -13,7 +13,7 @@
 
 /// Preprocesses a C/C++ comment so that it is a valid Rust comment.
 pub(crate) fn preprocess(comment: &str) -> String {
-    match self::kind(comment) {
+    match kind(comment) {
         Some(Kind::SingleLines) => preprocess_single_lines(comment),
         Some(Kind::MultiLine) => preprocess_multi_line(comment),
         None => comment.to_owned(),
@@ -58,7 +58,7 @@
         .collect();
 
     // Remove the trailing line corresponding to the `*/`.
-    if lines.last().map_or(false, |l| l.trim().is_empty()) {
+    if lines.last().is_some_and(|l| l.trim().is_empty()) {
         lines.pop();
     }
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/comp.rs firefox-140.10.2/third_party/rust/bindgen/ir/comp.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/comp.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/comp.rs	Mon May 11 04:49:32 2026
@@ -12,7 +12,7 @@
 use super::traversal::{EdgeKind, Trace, Tracer};
 use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
 use crate::clang;
-use crate::codegen::struct_layout::{align_to, bytes_from_bits_pow2};
+use crate::codegen::struct_layout::align_to;
 use crate::ir::derive::CanDeriveCopy;
 use crate::parse::ParseError;
 use crate::HashMap;
@@ -56,16 +56,16 @@
 
 impl MethodKind {
     /// Is this a destructor method?
-    pub(crate) fn is_destructor(&self) -> bool {
+    pub(crate) fn is_destructor(self) -> bool {
         matches!(
-            *self,
+            self,
             MethodKind::Destructor | MethodKind::VirtualDestructor { .. }
         )
     }
 
     /// Is this a pure virtual method?
-    pub(crate) fn is_pure_virtual(&self) -> bool {
-        match *self {
+    pub(crate) fn is_pure_virtual(self) -> bool {
+        match self {
             MethodKind::Virtual { pure_virtual } |
             MethodKind::VirtualDestructor { pure_virtual } => pure_virtual,
             _ => false,
@@ -147,7 +147,7 @@
     /// If this is a bitfield, how many bits does it need?
     fn bitfield_width(&self) -> Option<u32>;
 
-    /// Is this feild declared public?
+    /// Is this field declared public?
     fn is_public(&self) -> bool;
 
     /// Get the annotations for this field.
@@ -361,7 +361,7 @@
             "`Bitfield::getter_name` called on anonymous field"
         );
         self.getter_name.as_ref().expect(
-            "`Bitfield::getter_name` should only be called after\
+            "`Bitfield::getter_name` should only be called after \
              assigning bitfield accessor names",
         )
     }
@@ -376,7 +376,7 @@
             "`Bitfield::setter_name` called on anonymous field"
         );
         self.setter_name.as_ref().expect(
-            "`Bitfield::setter_name` should only be called\
+            "`Bitfield::setter_name` should only be called \
              after assigning bitfield accessor names",
         )
     }
@@ -560,18 +560,12 @@
         fields: &mut E,
         bitfield_unit_count: &mut usize,
         unit_size_in_bits: usize,
-        unit_align_in_bits: usize,
         bitfields: Vec<Bitfield>,
-        packed: bool,
     ) where
         E: Extend<Field>,
     {
         *bitfield_unit_count += 1;
-        let align = if packed {
-            1
-        } else {
-            bytes_from_bits_pow2(unit_align_in_bits)
-        };
+        let align = 1;
         let size = align_to(unit_size_in_bits, 8) / 8;
         let layout = Layout::new(size, align);
         fields.extend(Some(Field::Bitfields(BitfieldUnit {
@@ -581,70 +575,45 @@
         })));
     }
 
+    // The offset we're in inside the struct, if we know it (we might not know it in presence of
+    // templates).
+    let mut start_offset_in_struct = 0;
     let mut max_align = 0;
-    let mut unfilled_bits_in_unit = 0;
     let mut unit_size_in_bits = 0;
-    let mut unit_align = 0;
     let mut bitfields_in_unit = vec![];
 
-    // TODO(emilio): Determine this from attributes or pragma ms_struct
-    // directives. Also, perhaps we should check if the target is MSVC?
-    const is_ms_struct: bool = false;
-
+    // TODO(emilio): Deal with ms_struct bitfield layout for MSVC?
     for bitfield in raw_bitfields {
         let bitfield_width = bitfield.bitfield_width().unwrap() as usize;
         let bitfield_layout =
             ctx.resolve_type(bitfield.ty()).layout(ctx).ok_or(())?;
-        let bitfield_size = bitfield_layout.size;
         let bitfield_align = bitfield_layout.align;
+        let bitfield_size = bitfield_layout.size;
 
-        let mut offset = unit_size_in_bits;
-        if !packed {
-            if is_ms_struct {
-                if unit_size_in_bits != 0 &&
-                    (bitfield_width == 0 ||
-                        bitfield_width > unfilled_bits_in_unit)
-                {
-                    // We've reached the end of this allocation unit, so flush it
-                    // and its bitfields.
-                    unit_size_in_bits =
-                        align_to(unit_size_in_bits, unit_align * 8);
-                    flush_allocation_unit(
-                        fields,
-                        bitfield_unit_count,
-                        unit_size_in_bits,
-                        unit_align,
-                        mem::take(&mut bitfields_in_unit),
-                        packed,
-                    );
+        if unit_size_in_bits == 0 {
+            start_offset_in_struct = bitfield.offset().unwrap_or(0);
+        }
 
-                    // Now we're working on a fresh bitfield allocation unit, so reset
-                    // the current unit size and alignment.
-                    offset = 0;
-                    unit_align = 0;
-                }
-            } else if offset != 0 &&
-                (bitfield_width == 0 ||
-                    (offset & (bitfield_align * 8 - 1)) + bitfield_width >
-                        bitfield_size * 8)
-            {
-                offset = align_to(offset, bitfield_align * 8);
-            }
+        let mut offset_in_struct =
+            bitfield.offset().unwrap_or(unit_size_in_bits);
+
+        // A zero-width field serves as alignment / padding.
+        if !packed &&
+            offset_in_struct != 0 &&
+            (bitfield_width == 0 ||
+                (offset_in_struct & (bitfield_align * 8 - 1)) +
+                    bitfield_width >
+                    bitfield_size * 8)
+        {
+            offset_in_struct = align_to(offset_in_struct, bitfield_align * 8);
         }
 
-        // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not
-        // affect the alignment of a structure or union". This makes sense: such
-        // bit-fields are only used for padding, and we can't perform an
-        // un-aligned read of something we can't read because we can't even name
-        // it.
+        // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not affect the
+        // alignment of a structure or union". This makes sense: such bit-fields are only used for
+        // padding, and we can't perform an un-aligned read of something we can't read because we
+        // can't even name it.
         if bitfield.name().is_some() {
             max_align = cmp::max(max_align, bitfield_align);
-
-            // NB: The `bitfield_width` here is completely, absolutely
-            // intentional.  Alignment of the allocation unit is based on the
-            // maximum bitfield width, not (directly) on the bitfields' types'
-            // alignment.
-            unit_align = cmp::max(unit_align, bitfield_width);
         }
 
         // Always keep all bitfields around. While unnamed bitifields are used
@@ -652,15 +621,12 @@
         // bitfields over their types size cause weird allocation size behavior from clang.
         // Therefore, all bitfields needed to be kept around in order to check for this
         // and make the struct opaque in this case
-        bitfields_in_unit.push(Bitfield::new(offset, bitfield));
-
-        unit_size_in_bits = offset + bitfield_width;
-
-        // Compute what the physical unit's final size would be given what we
-        // have seen so far, and use that to compute how many bits are still
-        // available in the unit.
-        let data_size = align_to(unit_size_in_bits, bitfield_align * 8);
-        unfilled_bits_in_unit = data_size - unit_size_in_bits;
+        bitfields_in_unit.push(Bitfield::new(
+            offset_in_struct - start_offset_in_struct,
+            bitfield,
+        ));
+        unit_size_in_bits =
+            offset_in_struct - start_offset_in_struct + bitfield_width;
     }
 
     if unit_size_in_bits != 0 {
@@ -669,9 +635,7 @@
             fields,
             bitfield_unit_count,
             unit_size_in_bits,
-            unit_align,
             bitfields_in_unit,
-            packed,
         );
     }
 
@@ -782,7 +746,7 @@
                     getter
                 };
                 let setter = {
-                    let setter = format!("set_{}", bitfield_name);
+                    let setter = format!("set_{bitfield_name}");
                     let mut setter = ctx.rust_mangle(&setter).to_string();
                     if has_method(methods, ctx, &setter) {
                         setter.push_str("_bindgen_bitfield");
@@ -803,9 +767,8 @@
 
                     anon_field_counter += 1;
                     *name = Some(format!(
-                        "{}{}",
+                        "{}{anon_field_counter}",
                         ctx.options().anon_fields_prefix,
-                        anon_field_counter
                     ));
                 }
                 Field::Bitfields(ref mut bu) => {
@@ -825,6 +788,23 @@
             }
         }
     }
+
+    /// Return the flex array member for the struct/class, if any.
+    fn flex_array_member(&self, ctx: &BindgenContext) -> Option<TypeId> {
+        let fields = match self {
+            CompFields::Before(_) => panic!("raw fields"),
+            CompFields::After { fields, .. } => fields,
+            CompFields::Error => return None, // panic?
+        };
+
+        match fields.last()? {
+            Field::Bitfields(..) => None,
+            Field::DataMember(FieldData { ty, .. }) => ctx
+                .resolve_type(*ty)
+                .is_incomplete_array(ctx)
+                .map(|item| item.expect_type_id(ctx)),
+        }
+    }
 }
 
 impl Trace for CompFields {
@@ -931,7 +911,7 @@
     pub(crate) kind: BaseKind,
     /// Name of the field in which this base should be stored.
     pub(crate) field_name: String,
-    /// Whether this base is inherited from publically.
+    /// Whether this base is inherited from publicly.
     pub(crate) is_pub: bool,
 }
 
@@ -961,7 +941,7 @@
         true
     }
 
-    /// Whether this base is inherited from publically.
+    /// Whether this base is inherited from publicly.
     pub(crate) fn is_public(&self) -> bool {
         self.is_pub
     }
@@ -1001,6 +981,7 @@
 
     /// The inner types that were declared inside this class, in something like:
     ///
+    /// ```c++
     /// class Foo {
     ///     typedef int FooTy;
     ///     struct Bar {
@@ -1009,6 +990,7 @@
     /// }
     ///
     /// static Foo::Bar const = {3};
+    /// ```
     inner_types: Vec<TypeId>,
 
     /// Set of static constants declared inside this class.
@@ -1027,7 +1009,7 @@
     has_nonempty_base: bool,
 
     /// If this type has a template parameter which is not a type (e.g.: a
-    /// size_t)
+    /// `size_t`)
     has_non_type_template_params: bool,
 
     /// Whether this type has a bit field member whose width couldn't be
@@ -1040,7 +1022,7 @@
 
     /// Used to know if we've found an opaque attribute that could cause us to
     /// generate a type with invalid layout. This is explicitly used to avoid us
-    /// generating bad alignments when parsing types like max_align_t.
+    /// generating bad alignments when parsing types like `max_align_t`.
     ///
     /// It's not clear what the behavior should be here, if generating the item
     /// and pray, or behave as an opaque type.
@@ -1082,7 +1064,7 @@
     ///
     /// If we're a union without known layout, we try to compute it from our
     /// members. This is not ideal, but clang fails to report the size for these
-    /// kind of unions, see test/headers/template_union.hpp
+    /// kind of unions, see `test/headers/template_union.hpp`
     pub(crate) fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
         // We can't do better than clang here, sorry.
         if self.kind == CompKind::Struct {
@@ -1122,6 +1104,14 @@
         }
     }
 
+    /// Return the flex array member and its element type if any
+    pub(crate) fn flex_array_member(
+        &self,
+        ctx: &BindgenContext,
+    ) -> Option<TypeId> {
+        self.fields.flex_array_member(ctx)
+    }
+
     fn has_fields(&self) -> bool {
         match self.fields {
             CompFields::Error => false,
@@ -1138,14 +1128,14 @@
         match self.fields {
             CompFields::Error => {}
             CompFields::After { ref fields, .. } => {
-                for field in fields.iter() {
+                for field in fields {
                     if let Some(layout) = field.layout(ctx) {
                         callback(layout);
                     }
                 }
             }
             CompFields::Before(ref raw_fields) => {
-                for field in raw_fields.iter() {
+                for field in raw_fields {
                     let field_ty = ctx.resolve_type(field.0.ty);
                     if let Some(layout) = field_ty.layout(ctx) {
                         callback(layout);
@@ -1155,7 +1145,8 @@
         }
     }
 
-    fn has_bitfields(&self) -> bool {
+    /// Returns whether we have any bitfield within the struct.
+    pub(crate) fn has_bitfields(&self) -> bool {
         match self.fields {
             CompFields::Error => false,
             CompFields::After {
@@ -1189,7 +1180,7 @@
     }
 
     /// Do we see a virtual function during parsing?
-    /// Get the has_own_virtual_method boolean.
+    /// Get the `has_own_virtual_method` boolean.
     pub(crate) fn has_own_virtual_method(&self) -> bool {
         self.has_own_virtual_method
     }
@@ -1253,7 +1244,7 @@
 
         let kind = kind?;
 
-        debug!("CompInfo::from_ty({:?}, {:?})", kind, cursor);
+        debug!("CompInfo::from_ty({kind:?}, {cursor:?})");
 
         let mut ci = CompInfo::new(kind);
         ci.is_forward_declaration =
@@ -1424,7 +1415,7 @@
                 }
                 CXCursor_TemplateTypeParameter => {
                     let param = Item::type_param(None, cur, ctx).expect(
-                        "Item::type_param should't fail when pointing \
+                        "Item::type_param shouldn't fail when pointing \
                          at a TemplateTypeParameter",
                     );
                     ci.template_params.push(param);
@@ -1441,7 +1432,7 @@
 
                     let field_name = match ci.base_members.len() {
                         0 => "_base".into(),
-                        n => format!("_base_{}", n),
+                        n => format!("_base_{n}"),
                     };
                     let type_id =
                         Item::from_ty_or_ref(cur.cur_type(), cur, None, ctx);
@@ -1449,8 +1440,7 @@
                         ty: type_id,
                         kind,
                         field_name,
-                        is_pub: cur.access_specifier() ==
-                            clang_sys::CX_CXXPublic,
+                        is_pub: cur.access_specifier() == CX_CXXPublic,
                     });
                 }
                 CXCursor_Constructor | CXCursor_Destructor |
@@ -1589,7 +1579,7 @@
                 _ => CompKind::Struct,
             },
             _ => {
-                warn!("Unknown kind for comp type: {:?}", cursor);
+                warn!("Unknown kind for comp type: {cursor:?}");
                 return Err(ParseError::Continue);
             }
         })
@@ -1649,7 +1639,7 @@
     pub(crate) fn already_packed(&self, ctx: &BindgenContext) -> Option<bool> {
         let mut total_size: usize = 0;
 
-        for field in self.fields().iter() {
+        for field in self.fields() {
             let layout = field.layout(ctx)?;
 
             if layout.align != 0 && total_size % layout.align != 0 {
@@ -1674,7 +1664,7 @@
         layout: Option<&Layout>,
     ) {
         let packed = self.is_packed(ctx, layout);
-        self.fields.compute_bitfield_units(ctx, packed)
+        self.fields.compute_bitfield_units(ctx, packed);
     }
 
     /// Assign for each anonymous field a generated name.
@@ -1685,12 +1675,12 @@
     /// Returns whether the current union can be represented as a Rust `union`
     ///
     /// Requirements:
-    ///     1. Current RustTarget allows for `untagged_union`
-    ///     2. Each field can derive `Copy` or we use ManuallyDrop.
+    ///     1. Current `RustTarget` allows for `untagged_union`
+    ///     2. Each field can derive `Copy` or we use `ManuallyDrop`.
     ///     3. It's not zero-sized.
     ///
     /// Second boolean returns whether all fields can be copied (and thus
-    /// ManuallyDrop is not needed).
+    /// `ManuallyDrop` is not needed).
     pub(crate) fn is_rust_union(
         &self,
         ctx: &BindgenContext,
@@ -1728,7 +1718,7 @@
             return (false, false);
         }
 
-        if layout.map_or(false, |l| l.size == 0) {
+        if layout.is_some_and(|l| l.size == 0) {
             return (false, false);
         }
 
@@ -1792,7 +1782,11 @@
 impl IsOpaque for CompInfo {
     type Extra = Option<Layout>;
 
-    fn is_opaque(&self, ctx: &BindgenContext, layout: &Option<Layout>) -> bool {
+    fn is_opaque(
+        &self,
+        ctx: &BindgenContext,
+        _layout: &Option<Layout>,
+    ) -> bool {
         if self.has_non_type_template_params ||
             self.has_unevaluable_bit_field_width
         {
@@ -1821,23 +1815,6 @@
             }),
         }) {
             return true;
-        }
-
-        if !ctx.options().rust_features().repr_packed_n {
-            // If we don't have `#[repr(packed(N)]`, the best we can
-            // do is make this struct opaque.
-            //
-            // See https://github.com/rust-lang/rust-bindgen/issues/537 and
-            // https://github.com/rust-lang/rust/issues/33158
-            if self.is_packed(ctx, layout.as_ref()) &&
-                layout.map_or(false, |l| l.align > 1)
-            {
-                warn!("Found a type that is both packed and aligned to greater than \
-                       1; Rust before version 1.33 doesn't have `#[repr(packed(N))]`, so we \
-                       are treating it as opaque. You may wish to set bindgen's rust target \
-                       version to 1.33 or later to enable `#[repr(packed(N))]` support.");
-                return true;
-            }
         }
 
         false
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/context.rs firefox-140.10.2/third_party/rust/bindgen/ir/context.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/context.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/context.rs	Mon May 11 04:49:32 2026
@@ -29,14 +29,14 @@
 use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
 use std::collections::{BTreeSet, HashMap as StdHashMap};
-use std::iter::IntoIterator;
 use std::mem;
+use std::path::Path;
 
 /// An identifier for some kind of IR item.
 #[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)]
 pub(crate) struct ItemId(usize);
 
-/// Declare a newtype around `ItemId` with convesion methods.
+/// Declare a newtype around `ItemId` with conversion methods.
 macro_rules! item_id_newtype {
     (
         $( #[$attr:meta] )*
@@ -196,8 +196,8 @@
 
 impl ItemId {
     /// Get a numeric representation of this ID.
-    pub(crate) fn as_usize(&self) -> usize {
-        (*self).into()
+    pub(crate) fn as_usize(self) -> usize {
+        self.into()
     }
 }
 
@@ -308,7 +308,7 @@
 /// A context used during parsing and generation of structs.
 #[derive(Debug)]
 pub(crate) struct BindgenContext {
-    /// The map of all the items parsed so far, keyed off ItemId.
+    /// The map of all the items parsed so far, keyed off `ItemId`.
     items: Vec<Option<Item>>,
 
     /// Clang USR to type map. This is needed to be able to associate types with
@@ -317,7 +317,7 @@
 
     /// Maps from a cursor to the item ID of the named template type parameter
     /// for that cursor.
-    type_params: HashMap<clang::Cursor, TypeId>,
+    type_params: HashMap<Cursor, TypeId>,
 
     /// A cursor to module map. Similar reason than above.
     modules: HashMap<Cursor, ModuleId>,
@@ -328,13 +328,13 @@
     /// Current module being traversed.
     current_module: ModuleId,
 
-    /// A HashMap keyed on a type definition, and whose value is the parent ID
+    /// A `HashMap` keyed on a type definition, and whose value is the parent ID
     /// of the declaration.
     ///
     /// This is used to handle the cases where the semantic and the lexical
     /// parents of the cursor differ, like when a nested class is defined
     /// outside of the parent class.
-    semantic_parents: HashMap<clang::Cursor, ItemId>,
+    semantic_parents: HashMap<Cursor, ItemId>,
 
     /// A stack with the current type declarations and types we're parsing. This
     /// is needed to avoid infinite recursion when parsing a type like:
@@ -344,7 +344,7 @@
     /// This means effectively, that a type has a potential ID before knowing if
     /// it's a correct type. But that's not important in practice.
     ///
-    /// We could also use the `types` HashMap, but my intention with it is that
+    /// We could also use the `types` `HashMap`, but my intention with it is that
     /// only valid types and declarations end up there, and this could
     /// potentially break that assumption.
     currently_parsed_types: Vec<PartialType>,
@@ -353,7 +353,7 @@
     /// hard errors while parsing duplicated macros, as well to allow macro
     /// expression parsing.
     ///
-    /// This needs to be an std::HashMap because the cexpr API requires it.
+    /// This needs to be an `std::HashMap` because the `cexpr` API requires it.
     parsed_macros: StdHashMap<Vec<u8>, cexpr::expr::EvalResult>,
 
     /// A map with all include locations.
@@ -377,12 +377,18 @@
     /// The translation unit for parsing.
     translation_unit: clang::TranslationUnit,
 
+    /// The translation unit for macro fallback parsing.
+    fallback_tu: Option<clang::FallbackTranslationUnit>,
+
     /// Target information that can be useful for some stuff.
     target_info: clang::TargetInfo,
 
     /// The options given by the user via cli or other medium.
     options: BindgenOptions,
 
+    /// Whether an opaque array was generated
+    generated_opaque_array: RefCell<HashSet<usize>>,
+
     /// Whether a bindgen complex was generated
     generated_bindgen_complex: Cell<bool>,
 
@@ -496,7 +502,7 @@
     traversal: ItemTraversal<'ctx, ItemSet, Vec<ItemId>>,
 }
 
-impl<'ctx> Iterator for AllowlistedItemsTraversal<'ctx> {
+impl Iterator for AllowlistedItemsTraversal<'_> {
     type Item = ItemId;
 
     fn next(&mut self) -> Option<ItemId> {
@@ -585,10 +591,12 @@
             collected_typerefs: false,
             in_codegen: false,
             translation_unit,
+            fallback_tu: None,
             target_info,
             options,
             generated_bindgen_complex: Cell::new(false),
             generated_bindgen_float16: Cell::new(false),
+            generated_opaque_array: Default::default(),
             allowlisted: None,
             blocklisted_types_implement_traits: Default::default(),
             codegen_items: None,
@@ -613,7 +621,7 @@
         self.target_info.triple.starts_with("wasm32-")
     }
 
-    /// Creates a timer for the current bindgen phase. If time_phases is `true`,
+    /// Creates a timer for the current bindgen phase. If `time_phases` is `true`,
     /// the timer will print to stderr when it is dropped, otherwise it will do
     /// nothing.
     pub(crate) fn timer<'a>(&self, name: &'a str) -> Timer<'a> {
@@ -692,10 +700,7 @@
         declaration: Option<Cursor>,
         location: Option<Cursor>,
     ) {
-        debug!(
-            "BindgenContext::add_item({:?}, declaration: {:?}, loc: {:?}",
-            item, declaration, location
-        );
+        debug!("BindgenContext::add_item({item:?}, declaration: {declaration:?}, loc: {location:?}");
         debug_assert!(
             declaration.is_some() ||
                 !item.kind().is_type() ||
@@ -719,7 +724,7 @@
             self.need_bitfield_allocation.push(id);
         }
 
-        let old_item = mem::replace(&mut self.items[id.0], Some(item));
+        let old_item = self.items[id.0].replace(item);
         assert!(
             old_item.is_none(),
             "should not have already associated an item with the given id"
@@ -747,8 +752,7 @@
                 // Fortunately, we don't care about those types being
                 // duplicated, so we can just ignore them.
                 debug!(
-                    "Invalid declaration {:?} found for type {:?}",
-                    declaration,
+                    "Invalid declaration {declaration:?} found for type {:?}",
                     self.resolve_item_fallible(id)
                         .unwrap()
                         .kind()
@@ -762,10 +766,7 @@
             } else if let Some(usr) = declaration.usr() {
                 TypeKey::Usr(usr)
             } else {
-                warn!(
-                    "Valid declaration with no USR: {:?}, {:?}",
-                    declaration, location
-                );
+                warn!("Valid declaration with no USR: {declaration:?}, {location:?}");
                 TypeKey::Declaration(declaration)
             };
 
@@ -779,7 +780,7 @@
     /// codegen'd, even if its parent is not allowlisted. See issue #769 for
     /// details.
     fn add_item_to_module(&mut self, item: &Item) {
-        assert!(item.id() != self.root_module);
+        assert_ne!(item.id(), self.root_module);
         assert!(self.resolve_item_fallible(item.id()).is_none());
 
         if let Some(ref mut parent) = self.items[item.parent_id().0] {
@@ -801,7 +802,7 @@
             self.current_module
         );
 
-        self.items[(self.current_module.0).0]
+        self.items[self.current_module.0 .0]
             .as_mut()
             .expect("Should always have an item for self.current_module")
             .as_module_mut()
@@ -811,15 +812,8 @@
     }
 
     /// Add a new named template type parameter to this context's item set.
-    pub(crate) fn add_type_param(
-        &mut self,
-        item: Item,
-        definition: clang::Cursor,
-    ) {
-        debug!(
-            "BindgenContext::add_type_param: item = {:?}; definition = {:?}",
-            item, definition
-        );
+    pub(crate) fn add_type_param(&mut self, item: Item, definition: Cursor) {
+        debug!("BindgenContext::add_type_param: item = {item:?}; definition = {definition:?}");
 
         assert!(
             item.expect_type().is_type_param(),
@@ -833,7 +827,7 @@
         self.add_item_to_module(&item);
 
         let id = item.id();
-        let old_item = mem::replace(&mut self.items[id.0], Some(item));
+        let old_item = self.items[id.0].replace(item);
         assert!(
             old_item.is_none(),
             "should not have already associated an item with the given id"
@@ -850,15 +844,12 @@
 
     /// Get the named type defined at the given cursor location, if we've
     /// already added one.
-    pub(crate) fn get_type_param(
-        &self,
-        definition: &clang::Cursor,
-    ) -> Option<TypeId> {
+    pub(crate) fn get_type_param(&self, definition: &Cursor) -> Option<TypeId> {
         assert_eq!(
             definition.kind(),
             clang_sys::CXCursor_TemplateTypeParameter
         );
-        self.type_params.get(definition).cloned()
+        self.type_params.get(definition).copied()
     }
 
     // TODO: Move all this syntax crap to other part of the code.
@@ -874,7 +865,7 @@
                 "abstract" | "alignof" | "as" | "async" | "await" | "become" |
                     "box" | "break" | "const" | "continue" | "crate" | "do" |
                     "dyn" | "else" | "enum" | "extern" | "false" | "final" |
-                    "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" |
+                    "fn" | "for" | "gen" | "if" | "impl" | "in" | "let" | "loop" |
                     "macro" | "match" | "mod" | "move" | "mut" | "offsetof" |
                     "override" | "priv" | "proc" | "pub" | "pure" | "ref" |
                     "return" | "Self" | "self" | "sizeof" | "static" |
@@ -927,23 +918,20 @@
     /// Gather all the unresolved type references.
     fn collect_typerefs(
         &mut self,
-    ) -> Vec<(ItemId, clang::Type, clang::Cursor, Option<ItemId>)> {
+    ) -> Vec<(ItemId, clang::Type, Cursor, Option<ItemId>)> {
         debug_assert!(!self.collected_typerefs);
         self.collected_typerefs = true;
         let mut typerefs = vec![];
 
         for (id, item) in self.items() {
             let kind = item.kind();
-            let ty = match kind.as_type() {
-                Some(ty) => ty,
-                None => continue,
-            };
+            let Some(ty) = kind.as_type() else { continue };
 
             if let TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) =
                 *ty.kind()
             {
                 typerefs.push((id, *ty, loc, parent_id));
-            };
+            }
         }
         typerefs
     }
@@ -999,7 +987,7 @@
 
         let result = f(self, &mut item);
 
-        let existing = mem::replace(&mut self.items[id.0], Some(item));
+        let existing = self.items[id.0].replace(item);
         assert!(existing.is_none());
 
         result
@@ -1074,9 +1062,8 @@
 
             // Calls to `canonical_name` are expensive, so eagerly filter out
             // items that cannot be replaced.
-            let ty = match item.kind().as_type() {
-                Some(ty) => ty,
-                None => continue,
+            let Some(ty) = item.kind().as_type() else {
+                continue;
             };
 
             match *ty.kind() {
@@ -1105,7 +1092,7 @@
         }
 
         for (id, replacement_id) in replacements {
-            debug!("Replacing {:?} with {:?}", id, replacement_id);
+            debug!("Replacing {id:?} with {replacement_id:?}");
             let new_parent = {
                 let item_id: ItemId = id.into();
                 let item = self.items[item_id.0].as_mut().unwrap();
@@ -1142,7 +1129,7 @@
                     .chain(Some(immut_self.root_module.into()))
                     .find(|id| {
                         let item = immut_self.resolve_item(*id);
-                        item.as_module().map_or(false, |m| {
+                        item.as_module().is_some_and(|m| {
                             m.children().contains(&replacement_id.into())
                         })
                     })
@@ -1230,7 +1217,7 @@
 
     /// When the `__testing_only_extra_assertions` feature is enabled, this
     /// function walks the IR graph and asserts that we do not have any edges
-    /// referencing an ItemId for which we do not have an associated IR item.
+    /// referencing an `ItemId` for which we do not have an associated IR item.
     fn assert_no_dangling_references(&self) {
         if cfg!(feature = "__testing_only_extra_assertions") {
             for _ in self.assert_no_dangling_item_traversal() {
@@ -1241,9 +1228,9 @@
 
     fn assert_no_dangling_item_traversal(
         &self,
-    ) -> traversal::AssertNoDanglingItemsTraversal {
+    ) -> traversal::AssertNoDanglingItemsTraversal<'_> {
         assert!(self.in_codegen_phase());
-        assert!(self.current_module == self.root_module);
+        assert_eq!(self.current_module, self.root_module);
 
         let roots = self.items().map(|(id, _)| id);
         traversal::AssertNoDanglingItemsTraversal::new(
@@ -1259,7 +1246,7 @@
     fn assert_every_item_in_a_module(&self) {
         if cfg!(feature = "__testing_only_extra_assertions") {
             assert!(self.in_codegen_phase());
-            assert!(self.current_module == self.root_module);
+            assert_eq!(self.current_module, self.root_module);
 
             for (id, _item) in self.items() {
                 if id == self.root_module {
@@ -1277,19 +1264,13 @@
                         id.ancestors(self)
                             .chain(Some(self.root_module.into()))
                             .any(|ancestor| {
-                                debug!(
-                                    "Checking if {:?} is a child of {:?}",
-                                    id, ancestor
-                                );
+                                debug!("Checking if {id:?} is a child of {ancestor:?}");
                                 self.resolve_item(ancestor)
                                     .as_module()
-                                    .map_or(false, |m| {
-                                        m.children().contains(&id)
-                                    })
+                                    .is_some_and(|m| m.children().contains(&id))
                             })
                     },
-                    "{:?} should be in some ancestor module's children set",
-                    id
+                    "{id:?} should be in some ancestor module's children set"
                 );
             }
         }
@@ -1314,7 +1295,7 @@
             .as_ref()
             .unwrap()
             .get(&id)
-            .cloned()
+            .copied()
             .unwrap_or(SizednessResult::ZeroSized)
     }
 
@@ -1338,7 +1319,7 @@
             .as_ref()
             .unwrap()
             .get(&id.into())
-            .cloned()
+            .copied()
             .unwrap_or(HasVtableResult::No)
     }
 
@@ -1418,8 +1399,7 @@
         self.used_template_parameters
             .as_ref()
             .expect("should have found template parameter usage if we're in codegen")
-            .get(&item)
-            .map_or(false, |items_used_params| items_used_params.contains(&template_param))
+            .get(&item).is_some_and(|items_used_params| items_used_params.contains(&template_param))
     }
 
     /// Return `true` if `item` uses any unbound, generic template parameters,
@@ -1438,7 +1418,7 @@
                 "should have template parameter usage info in codegen phase",
             )
             .get(&item)
-            .map_or(false, |used| !used.is_empty())
+            .is_some_and(|used| !used.is_empty())
     }
 
     // This deserves a comment. Builtin types don't get a valid declaration, so
@@ -1450,11 +1430,11 @@
     // If at some point we care about the memory here, probably a map TypeKind
     // -> builtin type ItemId would be the best to improve that.
     fn add_builtin_item(&mut self, item: Item) {
-        debug!("add_builtin_item: item = {:?}", item);
+        debug!("add_builtin_item: item = {item:?}");
         debug_assert!(item.kind().is_type());
         self.add_item_to_module(&item);
         let id = item.id();
-        let old_item = mem::replace(&mut self.items[id.0], Some(item));
+        let old_item = self.items[id.0].replace(item);
         assert!(old_item.is_none(), "Inserted type twice?");
     }
 
@@ -1509,7 +1489,7 @@
         let item_id = item_id.into();
         match self.resolve_item_fallible(item_id) {
             Some(item) => item,
-            None => panic!("Not an item: {:?}", item_id),
+            None => panic!("Not an item: {item_id:?}"),
         }
     }
 
@@ -1524,11 +1504,11 @@
     /// correct type definition afterwards.
     ///
     /// TODO(emilio): We could consider doing this only when
-    /// declaration.lexical_parent() != definition.lexical_parent(), but it's
+    /// `declaration.lexical_parent() != definition.lexical_parent()`, but it's
     /// not sure it's worth it.
     pub(crate) fn add_semantic_parent(
         &mut self,
-        definition: clang::Cursor,
+        definition: Cursor,
         parent_id: ItemId,
     ) {
         self.semantic_parents.insert(definition, parent_id);
@@ -1537,9 +1517,9 @@
     /// Returns a known semantic parent for a given definition.
     pub(crate) fn known_semantic_parent(
         &self,
-        definition: clang::Cursor,
+        definition: Cursor,
     ) -> Option<ItemId> {
-        self.semantic_parents.get(&definition).cloned()
+        self.semantic_parents.get(&definition).copied()
     }
 
     /// Given a cursor pointing to the location of a template instantiation,
@@ -1587,7 +1567,6 @@
                         self.currently_parsed_types()
                             .iter()
                             .find(|partial_ty| *partial_ty.decl() == referenced)
-                            .cloned()
                     })
                     .and_then(|template_decl| {
                         let num_template_params =
@@ -1612,7 +1591,7 @@
     /// function template declarations(!?!??!).
     ///
     /// The only way to do this is manually inspecting the AST and looking for
-    /// TypeRefs and TemplateRefs inside. This, unfortunately, doesn't work for
+    /// `TypeRefs` and `TemplateRefs` inside. This, unfortunately, doesn't work for
     /// more complex cases, see the comment on the assertion below.
     ///
     /// To add insult to injury, the AST itself has structure that doesn't make
@@ -1643,7 +1622,7 @@
         with_id: ItemId,
         template: TypeId,
         ty: &clang::Type,
-        location: clang::Cursor,
+        location: Cursor,
     ) -> Option<TypeId> {
         let num_expected_args =
             self.resolve_type(template).num_self_template_params(self);
@@ -1776,8 +1755,7 @@
                         // Bypass all the validations in add_item explicitly.
                         debug!(
                             "instantiate_template: inserting nested \
-                             instantiation item: {:?}",
-                            sub_item
+                             instantiation item: {sub_item:?}"
                         );
                         self.add_item_to_module(&sub_item);
                         debug_assert_eq!(sub_id, sub_item.id());
@@ -1787,8 +1765,7 @@
                 }
                 _ => {
                     warn!(
-                        "Found template arg cursor we can't handle: {:?}",
-                        child
+                        "Found template arg cursor we can't handle: {child:?}"
                     );
                     found_const_arg = true;
                 }
@@ -1839,7 +1816,7 @@
         );
 
         // Bypass all the validations in add_item explicitly.
-        debug!("instantiate_template: inserting item: {:?}", item);
+        debug!("instantiate_template: inserting item: {item:?}");
         self.add_item_to_module(&item);
         debug_assert_eq!(with_id, item.id());
         self.items[with_id.0] = Some(item);
@@ -1859,7 +1836,7 @@
                     .usr()
                     .and_then(|usr| self.types.get(&TypeKey::Usr(usr)))
             })
-            .cloned()
+            .copied()
     }
 
     /// Looks up for an already resolved type, either because it's builtin, or
@@ -1869,19 +1846,15 @@
         with_id: ItemId,
         parent_id: Option<ItemId>,
         ty: &clang::Type,
-        location: Option<clang::Cursor>,
+        location: Option<Cursor>,
     ) -> Option<TypeId> {
         use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef};
-        debug!(
-            "builtin_or_resolved_ty: {:?}, {:?}, {:?}, {:?}",
-            ty, location, with_id, parent_id
-        );
+        debug!("builtin_or_resolved_ty: {ty:?}, {location:?}, {with_id:?}, {parent_id:?}");
 
         if let Some(decl) = ty.canonical_declaration(location.as_ref()) {
             if let Some(id) = self.get_resolved_type(&decl) {
                 debug!(
-                    "Already resolved ty {:?}, {:?}, {:?} {:?}",
-                    id, decl, ty, location
+                    "Already resolved ty {id:?}, {decl:?}, {ty:?} {location:?}"
                 );
                 // If the declaration already exists, then either:
                 //
@@ -2006,6 +1979,9 @@
             CXType_Short => TypeKind::Int(IntKind::Short),
             CXType_UShort => TypeKind::Int(IntKind::UShort),
             CXType_WChar => TypeKind::Int(IntKind::WChar),
+            CXType_Char16 if self.options().use_distinct_char16_t => {
+                TypeKind::Int(IntKind::Char16)
+            }
             CXType_Char16 => TypeKind::Int(IntKind::U16),
             CXType_Char32 => TypeKind::Int(IntKind::U32),
             CXType_Long => TypeKind::Int(IntKind::Long),
@@ -2029,8 +2005,7 @@
                     CXType_LongDouble => FloatKind::LongDouble,
                     CXType_Float128 => FloatKind::Float128,
                     _ => panic!(
-                        "Non floating-type complex? {:?}, {:?}",
-                        ty, float_type,
+                        "Non floating-type complex? {ty:?}, {float_type:?}",
                     ),
                 };
                 TypeKind::Complex(float_kind)
@@ -2061,6 +2036,93 @@
         &self.translation_unit
     }
 
+    /// Initialize fallback translation unit if it does not exist and
+    /// then return a mutable reference to the fallback translation unit.
+    pub(crate) fn try_ensure_fallback_translation_unit(
+        &mut self,
+    ) -> Option<&mut clang::FallbackTranslationUnit> {
+        if self.fallback_tu.is_none() {
+            let file = format!(
+                "{}/.macro_eval.c",
+                match self.options().clang_macro_fallback_build_dir {
+                    Some(ref path) => path.as_os_str().to_str()?,
+                    None => ".",
+                }
+            );
+
+            let index = clang::Index::new(false, false);
+
+            let mut header_names_to_compile = Vec::new();
+            let mut header_paths = Vec::new();
+            let mut header_includes = Vec::new();
+            let single_header = self.options().input_headers.last().cloned()?;
+            for input_header in &self.options.input_headers
+                [..self.options.input_headers.len() - 1]
+            {
+                let path = Path::new(input_header.as_ref());
+                if let Some(header_path) = path.parent() {
+                    if header_path == Path::new("") {
+                        header_paths.push(".");
+                    } else {
+                        header_paths.push(header_path.as_os_str().to_str()?);
+                    }
+                } else {
+                    header_paths.push(".");
+                }
+                let header_name = path.file_name()?.to_str()?;
+                header_includes.push(header_name.to_string());
+                header_names_to_compile
+                    .push(header_name.split(".h").next()?.to_string());
+            }
+            let pch = format!(
+                "{}/{}",
+                match self.options().clang_macro_fallback_build_dir {
+                    Some(ref path) => path.as_os_str().to_str()?,
+                    None => ".",
+                },
+                header_names_to_compile.join("-") + "-precompile.h.pch"
+            );
+
+            let mut c_args = self.options.fallback_clang_args.clone();
+            c_args.push("-x".to_string().into_boxed_str());
+            c_args.push("c-header".to_string().into_boxed_str());
+            for header_path in header_paths {
+                c_args.push(format!("-I{header_path}").into_boxed_str());
+            }
+            for header_include in header_includes {
+                c_args.push("-include".to_string().into_boxed_str());
+                c_args.push(header_include.into_boxed_str());
+            }
+            let mut tu = clang::TranslationUnit::parse(
+                &index,
+                &single_header,
+                &c_args,
+                &[],
+                clang_sys::CXTranslationUnit_ForSerialization,
+            )?;
+            tu.save(&pch).ok()?;
+
+            let mut c_args = vec![
+                "-include-pch".to_string().into_boxed_str(),
+                pch.clone().into_boxed_str(),
+            ];
+            let mut skip_next = false;
+            for arg in &self.options.fallback_clang_args {
+                if arg.as_ref() == "-include" {
+                    skip_next = true;
+                } else if skip_next {
+                    skip_next = false;
+                } else {
+                    c_args.push(arg.clone());
+                }
+            }
+            self.fallback_tu =
+                Some(clang::FallbackTranslationUnit::new(file, pch, &c_args)?);
+        }
+
+        self.fallback_tu.as_mut()
+    }
+
     /// Have we parsed the macro named `macro_name` already?
     pub(crate) fn parsed_macro(&self, macro_name: &[u8]) -> bool {
         self.parsed_macros.contains_key(macro_name)
@@ -2096,19 +2158,14 @@
     pub(crate) fn replace(&mut self, name: &[String], potential_ty: ItemId) {
         match self.replacements.entry(name.into()) {
             Entry::Vacant(entry) => {
-                debug!(
-                    "Defining replacement for {:?} as {:?}",
-                    name, potential_ty
-                );
+                debug!("Defining replacement for {name:?} as {potential_ty:?}");
                 entry.insert(potential_ty);
             }
             Entry::Occupied(occupied) => {
                 warn!(
-                    "Replacement for {:?} already defined as {:?}; \
-                     ignoring duplicate replacement definition as {:?}",
-                    name,
+                    "Replacement for {name:?} already defined as {:?}; \
+                     ignoring duplicate replacement definition as {potential_ty:?}",
                     occupied.get(),
-                    potential_ty
                 );
             }
         }
@@ -2143,7 +2200,7 @@
     /// namespace.
     fn tokenize_namespace(
         &self,
-        cursor: &clang::Cursor,
+        cursor: &Cursor,
     ) -> (Option<String>, ModuleKind) {
         assert_eq!(
             cursor.kind(),
@@ -2154,7 +2211,7 @@
         let mut module_name = None;
         let spelling = cursor.spelling();
         if !spelling.is_empty() {
-            module_name = Some(spelling)
+            module_name = Some(spelling);
         }
 
         let mut kind = ModuleKind::Normal;
@@ -2194,33 +2251,31 @@
                             );
                         }
                         break;
-                    } else {
-                        // This is _likely_, but not certainly, a macro that's
-                        // been placed just before the namespace keyword.
-                        // Unfortunately, clang tokens don't let us easily see
-                        // through the ifdef tokens, so we don't know what this
-                        // token should really be. Instead of panicking though,
-                        // we warn the user that we assumed the token was blank,
-                        // and then move on.
-                        //
-                        // See also https://github.com/rust-lang/rust-bindgen/issues/1676.
-                        warn!(
-                            "Ignored unknown namespace prefix '{}' at {:?} in {:?}",
-                            String::from_utf8_lossy(name),
-                            token,
-                            cursor
-                        );
                     }
+                    // This is _likely_, but not certainly, a macro that's
+                    // been placed just before the namespace keyword.
+                    // Unfortunately, clang tokens don't let us easily see
+                    // through the ifdef tokens, so we don't know what this
+                    // token should really be. Instead of panicking though,
+                    // we warn the user that we assumed the token was blank,
+                    // and then move on.
+                    //
+                    // See also https://github.com/rust-lang/rust-bindgen/issues/1676.
+                    warn!("Ignored unknown namespace prefix '{}' at {token:?} in {cursor:?}", String::from_utf8_lossy(name));
                 }
             }
         }
 
+        if cursor.is_inline_namespace() {
+            kind = ModuleKind::Inline;
+        }
+
         (module_name, kind)
     }
 
-    /// Given a CXCursor_Namespace cursor, return the item ID of the
+    /// Given a `CXCursor_Namespace` cursor, return the item ID of the
     /// corresponding module, or create one on the fly.
-    pub(crate) fn module(&mut self, cursor: clang::Cursor) -> ModuleId {
+    pub(crate) fn module(&mut self, cursor: Cursor) -> ModuleId {
         use clang_sys::*;
         assert_eq!(cursor.kind(), CXCursor_Namespace, "Be a nice person");
         let cursor = cursor.canonical();
@@ -2271,7 +2326,7 @@
     /// allowlisted.
     pub(crate) fn allowlisted_items(&self) -> &ItemSet {
         assert!(self.in_codegen_phase());
-        assert!(self.current_module == self.root_module);
+        assert_eq!(self.current_module, self.root_module);
 
         self.allowlisted.as_ref().unwrap()
     }
@@ -2284,7 +2339,7 @@
         derive_trait: DeriveTrait,
     ) -> CanDerive {
         assert!(self.in_codegen_phase());
-        assert!(self.current_module == self.root_module);
+        assert_eq!(self.current_module, self.root_module);
 
         *self
             .blocklisted_types_implement_traits
@@ -2332,14 +2387,14 @@
     /// Get a reference to the set of items we should generate.
     pub(crate) fn codegen_items(&self) -> &ItemSet {
         assert!(self.in_codegen_phase());
-        assert!(self.current_module == self.root_module);
+        assert_eq!(self.current_module, self.root_module);
         self.codegen_items.as_ref().unwrap()
     }
 
     /// Compute the allowlisted items set and populate `self.allowlisted`.
     fn compute_allowlisted_and_codegen_items(&mut self) {
         assert!(self.in_codegen_phase());
-        assert!(self.current_module == self.root_module);
+        assert_eq!(self.current_module, self.root_module);
         assert!(self.allowlisted.is_none());
         let _t = self.timer("compute_allowlisted_and_codegen_items");
 
@@ -2384,7 +2439,7 @@
                     }
 
                     let name = item.path_for_allowlisting(self)[1..].join("::");
-                    debug!("allowlisted_items: testing {:?}", name);
+                    debug!("allowlisted_items: testing {name:?}");
 
                     if self.options().allowlisted_items.matches(&name) {
                         return true;
@@ -2438,9 +2493,8 @@
                                 return false;
                             }
 
-                            let enum_ = match *ty.kind() {
-                                TypeKind::Enum(ref e) => e,
-                                _ => return false,
+                            let TypeKind::Enum(ref enum_) = *ty.kind() else {
+                                return false;
                             };
 
                             if ty.name().is_some() {
@@ -2455,7 +2509,11 @@
                                 );
                                 let name = prefix_path[1..].join("::");
                                 prefix_path.pop().unwrap();
-                                self.options().allowlisted_vars.matches(name)
+                                self.options().allowlisted_vars.matches(&name)
+                                    || self
+                                        .options()
+                                        .allowlisted_items
+                                        .matches(name)
                             })
                         }
                     }
@@ -2529,9 +2587,26 @@
         }
     }
 
+    /// Call if an opaque array is generated
+    pub(crate) fn generated_opaque_array(&self, align: usize) {
+        self.generated_opaque_array.borrow_mut().insert(align);
+    }
+
+    /// Whether we need to generate the opaque array type
+    pub(crate) fn opaque_array_types_needed(&self) -> Vec<usize> {
+        let mut alignments = self
+            .generated_opaque_array
+            .borrow()
+            .iter()
+            .copied()
+            .collect::<Vec<_>>();
+        alignments.sort_unstable();
+        alignments
+    }
+
     /// Call if a bindgen complex is generated
     pub(crate) fn generated_bindgen_complex(&self) {
-        self.generated_bindgen_complex.set(true)
+        self.generated_bindgen_complex.set(true);
     }
 
     /// Whether we need to generate the bindgen complex type
@@ -2541,7 +2616,7 @@
 
     /// Call if a bindgen float16 is generated
     pub(crate) fn generated_bindgen_float16(&self) {
-        self.generated_bindgen_float16.set(true)
+        self.generated_bindgen_float16.set(true);
     }
 
     /// Whether we need to generate the bindgen float16 type
@@ -2714,7 +2789,7 @@
         !self.cannot_derive_hash.as_ref().unwrap().contains(&id)
     }
 
-    /// Compute whether we can derive PartialOrd, PartialEq or Eq.
+    /// Compute whether we can derive `PartialOrd`, `PartialEq` or `Eq`.
     fn compute_cannot_derive_partialord_partialeq_or_eq(&mut self) {
         let _t = self.timer("compute_cannot_derive_partialord_partialeq_or_eq");
         assert!(self.cannot_derive_partialeq_or_partialord.is_none());
@@ -2749,7 +2824,7 @@
             .as_ref()
             .unwrap()
             .get(&id)
-            .cloned()
+            .copied()
             .unwrap_or(CanDerive::Yes)
     }
 
@@ -3007,7 +3082,7 @@
                             num_params += 1;
                         }
                         _ => {}
-                    };
+                    }
                     clang_sys::CXChildVisit_Continue
                 });
                 num_params
@@ -3018,7 +3093,7 @@
 }
 
 fn unused_regex_diagnostic(item: &str, name: &str, _ctx: &BindgenContext) {
-    warn!("unused option: {} {}", name, item);
+    warn!("unused option: {name} {item}");
 
     #[cfg(feature = "experimental")]
     if _ctx.options().emit_diagnostics {
@@ -3026,11 +3101,11 @@
 
         Diagnostic::default()
             .with_title(
-                format!("Unused regular expression: `{}`.", item),
-                Level::Warn,
+                format!("Unused regular expression: `{item}`."),
+                Level::Warning,
             )
             .add_annotation(
-                format!("This regular expression was passed to `{}`.", name),
+                format!("This regular expression was passed to `{name}`."),
                 Level::Note,
             )
             .display();
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/derive.rs firefox-140.10.2/third_party/rust/bindgen/ir/derive.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/derive.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/derive.rs	Mon May 11 04:49:32 2026
@@ -3,10 +3,10 @@
 //! These traits tend to come in pairs:
 //!
 //! 1. A "trivial" version, whose implementations aren't allowed to recursively
-//! look at other types or the results of fix point analyses.
+//!    look at other types or the results of fix point analyses.
 //!
 //! 2. A "normal" version, whose implementations simply query the results of a
-//! fix point analysis.
+//!    fix point analysis.
 //!
 //! The former is used by the analyses when creating the results queried by the
 //! second.
@@ -92,9 +92,10 @@
 ///
 /// Initially we assume that we can derive trait for all types and then
 /// update our understanding as we learn more about each type.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
 pub enum CanDerive {
     /// Yes, we can derive automatically.
+    #[default]
     Yes,
 
     /// The only thing that stops us from automatically deriving is that
@@ -107,12 +108,6 @@
     No,
 }
 
-impl Default for CanDerive {
-    fn default() -> CanDerive {
-        CanDerive::Yes
-    }
-}
-
 impl CanDerive {
     /// Take the least upper bound of `self` and `rhs`.
     pub(crate) fn join(self, rhs: Self) -> Self {
@@ -130,6 +125,6 @@
 
 impl ops::BitOrAssign for CanDerive {
     fn bitor_assign(&mut self, rhs: Self) {
-        *self = self.join(rhs)
+        *self = self.join(rhs);
     }
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/dot.rs firefox-140.10.2/third_party/rust/bindgen/ir/dot.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/dot.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/dot.rs	Mon May 11 04:49:32 2026
@@ -17,7 +17,7 @@
         out: &mut W,
     ) -> io::Result<()>
     where
-        W: io::Write;
+        W: Write;
 }
 
 /// Write a graphviz dot file containing our IR.
@@ -41,7 +41,7 @@
             if is_allowlisted { "black" } else { "gray" }
         )?;
         item.dot_attributes(ctx, &mut dot_file)?;
-        writeln!(&mut dot_file, r#"</table> >];"#)?;
+        writeln!(&mut dot_file, "</table> >];")?;
 
         item.trace(
             ctx,
@@ -52,10 +52,9 @@
 
                 match writeln!(
                     &mut dot_file,
-                    "{} -> {} [label={:?}, color={}];",
+                    "{} -> {} [label={edge_kind:?}, color={}];",
                     id.as_usize(),
                     sub_id.as_usize(),
-                    edge_kind,
                     if is_allowlisted { "black" } else { "gray" }
                 ) {
                     Ok(_) => {}
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/enum_ty.rs firefox-140.10.2/third_party/rust/bindgen/ir/enum_ty.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/enum_ty.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/enum_ty.rs	Mon May 11 04:49:32 2026
@@ -59,7 +59,7 @@
         ctx: &mut BindgenContext,
     ) -> Result<Self, ParseError> {
         use clang_sys::*;
-        debug!("Enum::from_ty {:?}", ty);
+        debug!("Enum::from_ty {ty:?}");
 
         if ty.kind() != CXType_Enum {
             return Err(ParseError::Continue);
@@ -73,13 +73,13 @@
 
         let variant_ty =
             repr.and_then(|r| ctx.resolve_type(r).safe_canonical_type(ctx));
-        let is_bool = variant_ty.map_or(false, Type::is_bool);
+        let is_bool = variant_ty.is_some_and(Type::is_bool);
 
         // Assume signedness since the default type by the C standard is an int.
         let is_signed = variant_ty.map_or(true, |ty| match *ty.kind() {
             TypeKind::Int(ref int_kind) => int_kind.is_signed(),
             ref other => {
-                panic!("Since when enums can be non-integers? {:?}", other)
+                panic!("Since when enums can be non-integers? {other:?}")
             }
         });
 
@@ -310,14 +310,12 @@
     /// Returns whether this variant should be enforced to be a constant by code
     /// generation.
     pub(crate) fn force_constification(&self) -> bool {
-        self.custom_behavior
-            .map_or(false, |b| b == EnumVariantCustomBehavior::Constify)
+        self.custom_behavior == Some(EnumVariantCustomBehavior::Constify)
     }
 
     /// Returns whether the current variant should be hidden completely from the
     /// resulting rust enum.
     pub(crate) fn hidden(&self) -> bool {
-        self.custom_behavior
-            .map_or(false, |b| b == EnumVariantCustomBehavior::Hide)
+        self.custom_behavior == Some(EnumVariantCustomBehavior::Hide)
     }
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/function.rs firefox-140.10.2/third_party/rust/bindgen/ir/function.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/function.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/function.rs	Mon May 11 04:49:32 2026
@@ -9,7 +9,7 @@
 use crate::callbacks::{ItemInfo, ItemKind};
 use crate::clang::{self, ABIKind, Attribute};
 use crate::parse::{ClangSubItemParser, ParseError, ParseResult};
-use clang_sys::{self, CXCallingConv};
+use clang_sys::CXCallingConv;
 
 use quote::TokenStreamExt;
 use std::io;
@@ -17,7 +17,7 @@
 
 const RUST_DERIVE_FUNPTR_LIMIT: usize = 12;
 
-/// What kind of a function are we looking at?
+/// What kind of function are we looking at?
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub(crate) enum FunctionKind {
     /// A plain, free function.
@@ -82,7 +82,7 @@
     /// The mangled name, that is, the symbol.
     mangled_name: Option<String>,
 
-    /// The link name. If specified, overwrite mangled_name.
+    /// The link name. If specified, overwrite `mangled_name`.
     link_name: Option<String>,
 
     /// The ID pointing to the current function signature.
@@ -158,11 +158,7 @@
         if let Some(ref mangled) = self.mangled_name {
             let mangled: String =
                 mangled.chars().flat_map(|c| c.escape_default()).collect();
-            writeln!(
-                out,
-                "<tr><td>mangled name</td><td>{}</td></tr>",
-                mangled
-            )?;
+            writeln!(out, "<tr><td>mangled name</td><td>{mangled}</td></tr>")?;
         }
 
         Ok(())
@@ -209,7 +205,7 @@
             "win64" => Ok(Self::Win64),
             "C-unwind" => Ok(Self::CUnwind),
             "system" => Ok(Self::System),
-            _ => Err(format!("Invalid or unknown ABI {:?}", s)),
+            _ => Err(format!("Invalid or unknown ABI {s:?}")),
         }
     }
 }
@@ -251,8 +247,8 @@
 
 impl ClangAbi {
     /// Returns whether this Abi is known or not.
-    fn is_unknown(&self) -> bool {
-        matches!(*self, ClangAbi::Unknown(..))
+    fn is_unknown(self) -> bool {
+        matches!(self, ClangAbi::Unknown(..))
     }
 }
 
@@ -261,8 +257,7 @@
         match *self {
             Self::Known(abi) => abi.to_tokens(tokens),
             Self::Unknown(cc) => panic!(
-                "Cannot turn unknown calling convention to tokens: {:?}",
-                cc
+                "Cannot turn unknown calling convention to tokens: {cc:?}"
             ),
         }
     }
@@ -295,15 +290,15 @@
 fn get_abi(cc: CXCallingConv) -> ClangAbi {
     use clang_sys::*;
     match cc {
-        CXCallingConv_Default => ClangAbi::Known(Abi::C),
-        CXCallingConv_C => ClangAbi::Known(Abi::C),
+        CXCallingConv_Default | CXCallingConv_C => ClangAbi::Known(Abi::C),
         CXCallingConv_X86StdCall => ClangAbi::Known(Abi::Stdcall),
         CXCallingConv_X86FastCall => ClangAbi::Known(Abi::Fastcall),
         CXCallingConv_X86ThisCall => ClangAbi::Known(Abi::ThisCall),
-        CXCallingConv_X86VectorCall => ClangAbi::Known(Abi::Vectorcall),
+        CXCallingConv_X86VectorCall | CXCallingConv_AArch64VectorCall => {
+            ClangAbi::Known(Abi::Vectorcall)
+        }
         CXCallingConv_AAPCS => ClangAbi::Known(Abi::Aapcs),
         CXCallingConv_X86_64Win64 => ClangAbi::Known(Abi::Win64),
-        CXCallingConv_AArch64VectorCall => ClangAbi::Known(Abi::Vectorcall),
         other => ClangAbi::Unknown(other),
     }
 }
@@ -423,7 +418,7 @@
         ctx: &mut BindgenContext,
     ) -> Result<Self, ParseError> {
         use clang_sys::*;
-        debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor);
+        debug!("FunctionSig::from_ty {ty:?} {cursor:?}");
 
         // Skip function templates
         let kind = cursor.kind();
@@ -438,7 +433,7 @@
             spelling.starts_with("operator") &&
                 !clang::is_valid_identifier(spelling)
         };
-        if is_operator(&spelling) {
+        if is_operator(&spelling) && !ctx.options().represent_cxx_operators {
             return Err(ParseError::Continue);
         }
 
@@ -538,7 +533,10 @@
             let is_const = is_method && cursor.method_is_const();
             let is_virtual = is_method && cursor.method_is_virtual();
             let is_static = is_method && cursor.method_is_static();
-            if !is_static && !is_virtual {
+            if !is_static &&
+                (!is_virtual ||
+                    ctx.options().use_specific_virtual_function_receiver)
+            {
                 let parent = cursor.semantic_parent();
                 let class = Item::parse(parent, None, ctx)
                     .expect("Expected to parse the class");
@@ -601,7 +599,7 @@
         let abi = get_abi(call_conv);
 
         if abi.is_unknown() {
-            warn!("Unknown calling convention: {:?}", call_conv);
+            warn!("Unknown calling convention: {call_conv:?}");
         }
 
         Ok(Self {
@@ -726,18 +724,18 @@
     ) -> Result<ParseResult<Self>, ParseError> {
         use clang_sys::*;
 
-        let kind = match FunctionKind::from_cursor(&cursor) {
-            None => return Err(ParseError::Continue),
-            Some(k) => k,
+        let Some(kind) = FunctionKind::from_cursor(&cursor) else {
+            return Err(ParseError::Continue);
         };
 
-        debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type());
+        debug!("Function::parse({cursor:?}, {:?})", cursor.cur_type());
         let visibility = cursor.visibility();
         if visibility != CXVisibility_Default {
             return Err(ParseError::Continue);
         }
-
-        if cursor.access_specifier() == CX_CXXPrivate {
+        if cursor.access_specifier() == CX_CXXPrivate &&
+            !context.options().generate_private_functions
+        {
             return Err(ParseError::Continue);
         }
 
@@ -749,9 +747,7 @@
         };
 
         if cursor.is_inlined_function() ||
-            cursor
-                .definition()
-                .map_or(false, |x| x.is_inlined_function())
+            cursor.definition().is_some_and(|x| x.is_inlined_function())
         {
             if !context.options().generate_inline_functions &&
                 !context.options().wrap_static_fns
@@ -759,7 +755,9 @@
                 return Err(ParseError::Continue);
             }
 
-            if cursor.is_deleted_function() {
+            if cursor.is_deleted_function() &&
+                !context.options().generate_deleted_functions
+            {
                 return Err(ParseError::Continue);
             }
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/int.rs firefox-140.10.2/third_party/rust/bindgen/ir/int.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/int.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/int.rs	Mon May 11 04:49:32 2026
@@ -54,9 +54,12 @@
     /// A 16-bit signed integer.
     I16,
 
-    /// Either a `char16_t` or a `wchar_t`.
+    /// A 16-bit integer, used only for enum size representation.
     U16,
 
+    /// The C++ type `char16_t`, which is its own type (unlike in C).
+    Char16,
+
     /// A 32-bit signed integer.
     I32,
 
@@ -94,14 +97,12 @@
             // to know whether it is or not right now (unlike char, there's no
             // WChar_S / WChar_U).
             Bool | UChar | UShort | UInt | ULong | ULongLong | U8 | U16 |
-            WChar | U32 | U64 | U128 => false,
+            Char16 | WChar | U32 | U64 | U128 => false,
 
             SChar | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 |
             I128 => true,
 
-            Char { is_signed } => is_signed,
-
-            Custom { is_signed, .. } => is_signed,
+            Char { is_signed } | Custom { is_signed, .. } => is_signed,
         }
     }
 
@@ -112,7 +113,7 @@
         use self::IntKind::*;
         Some(match *self {
             Bool | UChar | SChar | U8 | I8 | Char { .. } => 1,
-            U16 | I16 => 2,
+            U16 | I16 | Char16 => 2,
             U32 | I32 => 4,
             U64 | I64 => 8,
             I128 | U128 => 16,
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/item.rs firefox-140.10.2/third_party/rust/bindgen/ir/item.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/item.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/item.rs	Mon May 11 04:49:32 2026
@@ -12,21 +12,20 @@
 use super::dot::DotAttributes;
 use super::function::{Function, FunctionKind};
 use super::item_kind::ItemKind;
-use super::layout::Opaque;
 use super::module::Module;
 use super::template::{AsTemplateParam, TemplateParameters};
 use super::traversal::{EdgeKind, Trace, Tracer};
 use super::ty::{Type, TypeKind};
+use crate::callbacks::ItemInfo;
 use crate::clang;
 use crate::parse::{ClangSubItemParser, ParseError, ParseResult};
 
-use lazycell::LazyCell;
-
-use std::cell::Cell;
+use std::cell::{Cell, OnceCell};
 use std::collections::BTreeSet;
 use std::fmt::Write;
 use std::io;
 use std::iter;
+use std::sync::OnceLock;
 
 /// A trait to get the canonical name from an item.
 ///
@@ -45,7 +44,7 @@
 
 /// The same, but specifies the path that needs to be followed to reach an item.
 ///
-/// To contrast with canonical_name, here's an example:
+/// To contrast with `canonical_name`, here's an example:
 ///
 /// ```c++
 /// namespace foo {
@@ -85,13 +84,6 @@
     fn has_type_param_in_array(&self, ctx: &BindgenContext) -> bool;
 }
 
-#[allow(dead_code)]
-/// A trait for determining if some IR thing has float or not.
-pub(crate) trait HasFloat {
-    /// Returns `true` if the thing has float, and `false` otherwise.
-    fn has_float(&self, ctx: &BindgenContext) -> bool;
-}
-
 /// A trait for iterating over an item and its parents and up its ancestor chain
 /// up to (but not including) the implicit root module.
 pub(crate) trait ItemAncestors {
@@ -111,6 +103,7 @@
         DebugOnlyItemSet
     }
 
+    #[allow(clippy::trivially_copy_pass_by_ref)]
     fn contains(&self, _id: &ItemId) -> bool {
         false
     }
@@ -135,7 +128,7 @@
     }
 }
 
-impl<'a> Iterator for ItemAncestorsIter<'a> {
+impl Iterator for ItemAncestorsIter<'_> {
     type Item = ItemId;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -383,11 +376,11 @@
     /// The item's local ID, unique only amongst its siblings. Only used for
     /// anonymous items.
     ///
-    /// Lazily initialized in local_id().
+    /// Lazily initialized in `local_id()`.
     ///
     /// Note that only structs, unions, and enums get a local type ID. In any
     /// case this is an implementation detail.
-    local_id: LazyCell<usize>,
+    local_id: OnceCell<usize>,
 
     /// The next local ID to use for a child or template instantiation.
     next_child_local_id: Cell<usize>,
@@ -396,11 +389,11 @@
     ///
     /// This is a fairly used operation during codegen so this makes bindgen
     /// considerably faster in those cases.
-    canonical_name: LazyCell<String>,
+    canonical_name: OnceCell<String>,
 
     /// The path to use for allowlisting and other name-based checks, as
     /// returned by `path_for_allowlisting`, lazily constructed.
-    path_for_allowlisting: LazyCell<Vec<String>>,
+    path_for_allowlisting: OnceCell<Vec<String>>,
 
     /// A doc comment over the item, if any.
     comment: Option<String>,
@@ -438,10 +431,10 @@
         debug_assert!(id != parent_id || kind.is_module());
         Item {
             id,
-            local_id: LazyCell::new(),
+            local_id: OnceCell::new(),
             next_child_local_id: Cell::new(1),
-            canonical_name: LazyCell::new(),
-            path_for_allowlisting: LazyCell::new(),
+            canonical_name: OnceCell::new(),
+            path_for_allowlisting: OnceCell::new(),
             parent_id,
             comment,
             annotations: annotations.unwrap_or_default(),
@@ -457,7 +450,7 @@
         ctx: &mut BindgenContext,
     ) -> TypeId {
         let location = ty.declaration().location();
-        let ty = Opaque::from_clang_ty(ty, ctx);
+        let ty = Type::new_opaque_from_clang_ty(ty, ctx);
         let kind = ItemKind::Type(ty);
         let parent = ctx.root_module().into();
         ctx.add_item(
@@ -500,7 +493,7 @@
 
         self.ancestors(ctx)
             .filter(|id| {
-                ctx.resolve_item(*id).as_module().map_or(false, |module| {
+                ctx.resolve_item(*id).as_module().is_some_and(|module| {
                     !module.is_inline() ||
                         ctx.options().conservative_inline_namespaces
                 })
@@ -542,7 +535,7 @@
     /// below this item's lexical scope, meaning that this can be useful for
     /// generating relatively stable identifiers within a scope.
     pub(crate) fn local_id(&self, ctx: &BindgenContext) -> usize {
-        *self.local_id.borrow_with(|| {
+        *self.local_id.get_or_init(|| {
             let parent = ctx.resolve_item(self.parent_id);
             parent.next_child_local_id()
         })
@@ -590,9 +583,8 @@
 
         let mut parent = self.parent_id;
         loop {
-            let parent_item = match ctx.resolve_item_fallible(parent) {
-                Some(item) => item,
-                None => return false,
+            let Some(parent_item) = ctx.resolve_item_fallible(parent) else {
+                return false;
             };
 
             if parent_item.id() == ctx.root_module() {
@@ -677,7 +669,7 @@
             }
     }
 
-    /// Take out item NameOptions
+    /// Take out item `NameOptions`
     pub(crate) fn name<'a>(
         &'a self,
         ctx: &'a BindgenContext,
@@ -725,7 +717,7 @@
         s
     }
 
-    /// Helper function for full_disambiguated_name
+    /// Helper function for `full_disambiguated_name`
     fn push_disambiguated_name(
         &self,
         ctx: &BindgenContext,
@@ -735,7 +727,7 @@
         to.push_str(&self.canonical_name(ctx));
         if let ItemKind::Type(ref ty) = *self.kind() {
             if let TypeKind::TemplateInstantiation(ref inst) = *ty.kind() {
-                to.push_str(&format!("_open{}_", level));
+                let _ = write!(to, "_open{level}_");
                 for arg in inst.template_arguments() {
                     arg.into_resolver()
                         .through_type_refs()
@@ -743,7 +735,7 @@
                         .push_disambiguated_name(ctx, to, level + 1);
                     to.push('_');
                 }
-                to.push_str(&format!("close{}", level));
+                let _ = write!(to, "close{level}");
             }
         }
     }
@@ -794,22 +786,20 @@
 
         match *self.kind() {
             ItemKind::Var(ref var) => var.name().to_owned(),
-            ItemKind::Module(ref module) => {
-                module.name().map(ToOwned::to_owned).unwrap_or_else(|| {
-                    format!("_bindgen_mod_{}", self.exposed_id(ctx))
-                })
-            }
-            ItemKind::Type(ref ty) => {
-                ty.sanitized_name(ctx).map(Into::into).unwrap_or_else(|| {
-                    format!("_bindgen_ty_{}", self.exposed_id(ctx))
-                })
-            }
+            ItemKind::Module(ref module) => module.name().map_or_else(
+                || format!("_bindgen_mod_{}", self.exposed_id(ctx)),
+                ToOwned::to_owned,
+            ),
+            ItemKind::Type(ref ty) => ty.sanitized_name(ctx).map_or_else(
+                || format!("_bindgen_ty_{}", self.exposed_id(ctx)),
+                Into::into,
+            ),
             ItemKind::Function(ref fun) => {
                 let mut name = fun.name().to_owned();
 
                 if let Some(idx) = self.overload_index(ctx) {
                     if idx > 0 {
-                        write!(&mut name, "{}", idx).unwrap();
+                        write!(&mut name, "{idx}").unwrap();
                     }
                 }
 
@@ -932,8 +922,19 @@
         let name = names.join("_");
 
         let name = if opt.user_mangled == UserMangled::Yes {
+            let item_info = ItemInfo {
+                name: &name,
+                kind: match self.kind() {
+                    ItemKind::Module(..) => crate::callbacks::ItemKind::Module,
+                    ItemKind::Type(..) => crate::callbacks::ItemKind::Type,
+                    ItemKind::Function(..) => {
+                        crate::callbacks::ItemKind::Function
+                    }
+                    ItemKind::Var(..) => crate::callbacks::ItemKind::Var,
+                },
+            };
             ctx.options()
-                .last_callback(|callbacks| callbacks.item_name(&name))
+                .last_callback(|callbacks| callbacks.item_name(item_info))
                 .unwrap_or(name)
         } else {
             name
@@ -948,13 +949,13 @@
         // Only use local ids for enums, classes, structs and union types.  All
         // other items use their global ID.
         let ty_kind = self.kind().as_type().map(|t| t.kind());
-        if let Some(ty_kind) = ty_kind {
-            match *ty_kind {
-                TypeKind::Comp(..) |
-                TypeKind::TemplateInstantiation(..) |
-                TypeKind::Enum(..) => return self.local_id(ctx).to_string(),
-                _ => {}
-            }
+        if let Some(
+            TypeKind::Comp(..) |
+            TypeKind::TemplateInstantiation(..) |
+            TypeKind::Enum(..),
+        ) = ty_kind
+        {
+            return self.local_id(ctx).to_string();
         }
 
         // Note that this `id_` prefix prevents (really unlikely) collisions
@@ -986,9 +987,8 @@
         // Do not jump through aliases, except for aliases that point to a type
         // with the same name, since we dont generate coe for them.
         let item = self.id.into_resolver().through_type_refs().resolve(ctx);
-        let type_ = match *item.kind() {
-            ItemKind::Type(ref type_) => type_,
-            _ => return false,
+        let ItemKind::Type(ref type_) = *item.kind() else {
+            return false;
         };
 
         match *type_.kind() {
@@ -1024,15 +1024,15 @@
                 FunctionKind::Method(MethodKind::Constructor) => {
                     cc.constructors()
                 }
-                FunctionKind::Method(MethodKind::Destructor) |
-                FunctionKind::Method(MethodKind::VirtualDestructor {
-                    ..
-                }) => cc.destructors(),
-                FunctionKind::Method(MethodKind::Static) |
-                FunctionKind::Method(MethodKind::Normal) |
-                FunctionKind::Method(MethodKind::Virtual { .. }) => {
-                    cc.methods()
-                }
+                FunctionKind::Method(
+                    MethodKind::Destructor |
+                    MethodKind::VirtualDestructor { .. },
+                ) => cc.destructors(),
+                FunctionKind::Method(
+                    MethodKind::Static |
+                    MethodKind::Normal |
+                    MethodKind::Virtual { .. },
+                ) => cc.methods(),
             },
         }
     }
@@ -1044,7 +1044,7 @@
         ctx: &BindgenContext,
     ) -> &Vec<String> {
         self.path_for_allowlisting
-            .borrow_with(|| self.compute_path(ctx, UserMangled::No))
+            .get_or_init(|| self.compute_path(ctx, UserMangled::No))
     }
 
     fn compute_path(
@@ -1066,7 +1066,7 @@
             .map(|id| ctx.resolve_item(id))
             .filter(|item| {
                 item.id() == target.id() ||
-                    item.as_module().map_or(false, |module| {
+                    item.as_module().is_some_and(|module| {
                         !module.is_inline() ||
                             ctx.options().conservative_inline_namespaces
                     })
@@ -1085,9 +1085,8 @@
 
     /// Returns a prefix for the canonical name when C naming is enabled.
     fn c_naming_prefix(&self) -> Option<&str> {
-        let ty = match self.kind {
-            ItemKind::Type(ref ty) => ty,
-            _ => return None,
+        let ItemKind::Type(ref ty) = self.kind else {
+            return None;
         };
 
         Some(match ty.kind() {
@@ -1130,7 +1129,7 @@
             "You're not supposed to call this yet"
         );
         self.annotations.opaque() ||
-            self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) ||
+            self.as_type().is_some_and(|ty| ty.is_opaque(ctx, self)) ||
             ctx.opaque_by_name(self.path_for_allowlisting(ctx))
     }
 }
@@ -1141,14 +1140,14 @@
 {
     fn has_vtable(&self, ctx: &BindgenContext) -> bool {
         let id: ItemId = (*self).into();
-        id.as_type_id(ctx).map_or(false, |id| {
+        id.as_type_id(ctx).is_some_and(|id| {
             !matches!(ctx.lookup_has_vtable(id), HasVtableResult::No)
         })
     }
 
     fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool {
         let id: ItemId = (*self).into();
-        id.as_type_id(ctx).map_or(false, |id| {
+        id.as_type_id(ctx).is_some_and(|id| {
             matches!(ctx.lookup_has_vtable(id), HasVtableResult::SelfHasVtable)
         })
     }
@@ -1204,29 +1203,6 @@
     }
 }
 
-impl<T> HasFloat for T
-where
-    T: Copy + Into<ItemId>,
-{
-    fn has_float(&self, ctx: &BindgenContext) -> bool {
-        debug_assert!(
-            ctx.in_codegen_phase(),
-            "You're not supposed to call this yet"
-        );
-        ctx.lookup_has_float(*self)
-    }
-}
-
-impl HasFloat for Item {
-    fn has_float(&self, ctx: &BindgenContext) -> bool {
-        debug_assert!(
-            ctx.in_codegen_phase(),
-            "You're not supposed to call this yet"
-        );
-        ctx.lookup_has_float(self.id())
-    }
-}
-
 /// A set of items.
 pub(crate) type ItemSet = BTreeSet<ItemId>;
 
@@ -1451,11 +1427,7 @@
             CXCursor_UsingDirective |
             CXCursor_StaticAssert |
             CXCursor_FunctionTemplate => {
-                debug!(
-                    "Unhandled cursor kind {:?}: {:?}",
-                    cursor.kind(),
-                    cursor
-                );
+                debug!("Unhandled cursor kind {:?}: {cursor:?}", cursor.kind());
                 Err(ParseError::Continue)
             }
 
@@ -1463,7 +1435,7 @@
                 let file = cursor.get_included_file_name();
                 match file {
                     None => {
-                        warn!("Inclusion of a nameless file in {:?}", cursor);
+                        warn!("Inclusion of a nameless file in {cursor:?}");
                     }
                     Some(included_file) => {
                         for cb in &ctx.options().parse_callbacks {
@@ -1481,9 +1453,8 @@
                 let spelling = cursor.spelling();
                 if !spelling.starts_with("operator") {
                     warn!(
-                        "Unhandled cursor kind {:?}: {:?}",
+                        "Unhandled cursor kind {:?}: {cursor:?}",
                         cursor.kind(),
-                        cursor
                     );
                 }
                 Err(ParseError::Continue)
@@ -1520,10 +1491,7 @@
         parent_id: Option<ItemId>,
         ctx: &mut BindgenContext,
     ) -> TypeId {
-        debug!(
-            "from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}",
-            potential_id, ty, location, parent_id
-        );
+        debug!("from_ty_or_ref_with_id: {potential_id:?} {ty:?}, {location:?}, {parent_id:?}");
 
         if ctx.collected_typerefs() {
             debug!("refs already collected, resolving directly");
@@ -1543,11 +1511,11 @@
             &ty,
             Some(location),
         ) {
-            debug!("{:?} already resolved: {:?}", ty, location);
+            debug!("{ty:?} already resolved: {location:?}");
             return ty;
         }
 
-        debug!("New unresolved type reference: {:?}, {:?}", ty, location);
+        debug!("New unresolved type reference: {ty:?}, {location:?}");
 
         let is_const = ty.is_const();
         let kind = TypeKind::UnresolvedTypeRef(ty, location, parent_id);
@@ -1597,14 +1565,13 @@
         use clang_sys::*;
 
         debug!(
-            "Item::from_ty_with_id: {:?}\n\
-             \tty = {:?},\n\
-             \tlocation = {:?}",
-            id, ty, location
+            "Item::from_ty_with_id: {id:?}\n\
+             \tty = {ty:?},\n\
+             \tlocation = {location:?}",
         );
 
-        if ty.kind() == clang_sys::CXType_Unexposed ||
-            location.cur_type().kind() == clang_sys::CXType_Unexposed
+        if ty.kind() == CXType_Unexposed ||
+            location.cur_type().kind() == CXType_Unexposed
         {
             if ty.is_associated_type() ||
                 location.cur_type().is_associated_type()
@@ -1624,7 +1591,7 @@
         // ignore function bodies. See issue #2036.)
         if let Some(ref parent) = ty.declaration().fallible_semantic_parent() {
             if FunctionKind::from_cursor(parent).is_some() {
-                debug!("Skipping type declared inside function: {:?}", ty);
+                debug!("Skipping type declared inside function: {ty:?}");
                 return Ok(Item::new_opaque_type(id, ty, ctx));
             }
         }
@@ -1634,10 +1601,7 @@
             canonical_def.unwrap_or_else(|| ty.declaration())
         };
 
-        let comment = location
-            .raw_comment()
-            .or_else(|| decl.raw_comment())
-            .or_else(|| location.raw_comment());
+        let comment = location.raw_comment().or_else(|| decl.raw_comment());
 
         let annotations =
             Annotations::new(&decl).or_else(|| Annotations::new(&location));
@@ -1671,7 +1635,7 @@
                 .iter()
                 .find(|ty| *ty.decl() == declaration_to_look_for)
             {
-                debug!("Avoiding recursion parsing type: {:?}", ty);
+                debug!("Avoiding recursion parsing type: {ty:?}");
                 // Unchecked because we haven't finished this type yet.
                 return Ok(partial.id().as_type_id_unchecked());
             }
@@ -1742,8 +1706,7 @@
                         ty.spelling()
                     );
                     Item::type_param(Some(id), location, ctx)
-                        .map(Ok)
-                        .unwrap_or(Err(ParseError::Recurse))
+                        .ok_or(ParseError::Recurse)
                 } else {
                     result
                 }
@@ -1837,10 +1800,10 @@
             refd: &clang::Cursor,
             spelling: &str,
         ) -> bool {
-            lazy_static! {
-                static ref ANON_TYPE_PARAM_RE: regex::Regex =
-                    regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap();
-            }
+            static ANON_TYPE_PARAM_RE: OnceLock<regex::Regex> = OnceLock::new();
+            let anon_type_param_re = ANON_TYPE_PARAM_RE.get_or_init(|| {
+                regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap()
+            });
 
             if refd.kind() != clang_sys::CXCursor_TemplateTypeParameter {
                 return false;
@@ -1849,7 +1812,7 @@
             let refd_spelling = refd.spelling();
             refd_spelling == spelling ||
                 // Allow for anonymous template parameters.
-                (refd_spelling.is_empty() && ANON_TYPE_PARAM_RE.is_match(spelling.as_ref()))
+                (refd_spelling.is_empty() && anon_type_param_re.is_match(spelling.as_ref()))
         }
 
         let definition = if is_template_with_spelling(&location, &ty_spelling) {
@@ -1902,16 +1865,11 @@
         let parent = ctx.root_module().into();
 
         if let Some(id) = ctx.get_type_param(&definition) {
-            if let Some(with_id) = with_id {
-                return Some(ctx.build_ty_wrapper(
-                    with_id,
-                    id,
-                    Some(parent),
-                    &ty,
-                ));
+            return Some(if let Some(with_id) = with_id {
+                ctx.build_ty_wrapper(with_id, id, Some(parent), &ty)
             } else {
-                return Some(id);
-            }
+                id
+            });
         }
 
         // See tests/headers/const_tparam.hpp and
@@ -1939,7 +1897,7 @@
             "You're not supposed to call this yet"
         );
         self.canonical_name
-            .borrow_with(|| {
+            .get_or_init(|| {
                 let in_namespace = ctx.options().enable_cxx_namespaces ||
                     ctx.options().disable_name_namespacing;
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/item_kind.rs firefox-140.10.2/third_party/rust/bindgen/ir/item_kind.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/item_kind.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/item_kind.rs	Mon May 11 04:49:32 2026
@@ -26,7 +26,7 @@
 }
 
 impl ItemKind {
-    /// Get a reference to this `ItemKind`'s underying `Module`, or `None` if it
+    /// Get a reference to this `ItemKind`'s underlying `Module`, or `None` if it
     /// is some other kind.
     pub(crate) fn as_module(&self) -> Option<&Module> {
         match *self {
@@ -50,7 +50,7 @@
         self.as_module().is_some()
     }
 
-    /// Get a reference to this `ItemKind`'s underying `Function`, or `None` if
+    /// Get a reference to this `ItemKind`'s underlying `Function`, or `None` if
     /// it is some other kind.
     pub(crate) fn as_function(&self) -> Option<&Function> {
         match *self {
@@ -64,13 +64,13 @@
         self.as_function().is_some()
     }
 
-    /// Get a reference to this `ItemKind`'s underying `Function`, or panic if
+    /// Get a reference to this `ItemKind`'s underlying `Function`, or panic if
     /// it is some other kind.
     pub(crate) fn expect_function(&self) -> &Function {
         self.as_function().expect("Not a function")
     }
 
-    /// Get a reference to this `ItemKind`'s underying `Type`, or `None` if
+    /// Get a reference to this `ItemKind`'s underlying `Type`, or `None` if
     /// it is some other kind.
     pub(crate) fn as_type(&self) -> Option<&Type> {
         match *self {
@@ -79,7 +79,7 @@
         }
     }
 
-    /// Get a mutable reference to this `ItemKind`'s underying `Type`, or `None`
+    /// Get a mutable reference to this `ItemKind`'s underlying `Type`, or `None`
     /// if it is some other kind.
     pub(crate) fn as_type_mut(&mut self) -> Option<&mut Type> {
         match *self {
@@ -93,13 +93,13 @@
         self.as_type().is_some()
     }
 
-    /// Get a reference to this `ItemKind`'s underying `Type`, or panic if it is
+    /// Get a reference to this `ItemKind`'s underlying `Type`, or panic if it is
     /// some other kind.
     pub(crate) fn expect_type(&self) -> &Type {
         self.as_type().expect("Not a type")
     }
 
-    /// Get a reference to this `ItemKind`'s underying `Var`, or `None` if it is
+    /// Get a reference to this `ItemKind`'s underlying `Var`, or `None` if it is
     /// some other kind.
     pub(crate) fn as_var(&self) -> Option<&Var> {
         match *self {
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/layout.rs firefox-140.10.2/third_party/rust/bindgen/ir/layout.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/layout.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/layout.rs	Mon May 11 04:49:32 2026
@@ -1,10 +1,6 @@
 //! Intermediate representation for the physical layout of some type.
 
-use super::derive::CanDerive;
-use super::ty::{Type, TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
-use crate::clang;
 use crate::ir::context::BindgenContext;
-use std::cmp;
 
 /// A type that represents the struct layout of a type.
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -19,9 +15,8 @@
 
 #[test]
 fn test_layout_for_size() {
-    use std::mem;
-
-    let ptr_size = mem::size_of::<*mut ()>();
+    use std::mem::size_of;
+    let ptr_size = size_of::<*mut ()>();
     assert_eq!(
         Layout::for_size_internal(ptr_size, ptr_size),
         Layout::new(ptr_size, ptr_size)
@@ -34,14 +29,9 @@
 
 impl Layout {
     /// Gets the integer type name for a given known size.
-    pub(crate) fn known_type_for_size(
-        ctx: &BindgenContext,
-        size: usize,
-    ) -> Option<syn::Type> {
+    pub(crate) fn known_type_for_size(size: usize) -> Option<syn::Type> {
         Some(match size {
-            16 if ctx.options().rust_features.i128_and_u128 => {
-                syn::parse_quote! { u128 }
-            }
+            16 => syn::parse_quote! { u128 },
             8 => syn::parse_quote! { u64 },
             4 => syn::parse_quote! { u32 },
             2 => syn::parse_quote! { u16 },
@@ -76,63 +66,5 @@
     /// alignment possible.
     pub(crate) fn for_size(ctx: &BindgenContext, size: usize) -> Self {
         Self::for_size_internal(ctx.target_pointer_size(), size)
-    }
-
-    /// Get this layout as an opaque type.
-    pub(crate) fn opaque(&self) -> Opaque {
-        Opaque(*self)
-    }
-}
-
-/// When we are treating a type as opaque, it is just a blob with a `Layout`.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub(crate) struct Opaque(pub(crate) Layout);
-
-impl Opaque {
-    /// Construct a new opaque type from the given clang type.
-    pub(crate) fn from_clang_ty(
-        ty: &clang::Type,
-        ctx: &BindgenContext,
-    ) -> Type {
-        let layout = Layout::new(ty.size(ctx), ty.align(ctx));
-        let ty_kind = TypeKind::Opaque;
-        let is_const = ty.is_const();
-        Type::new(None, Some(layout), ty_kind, is_const)
-    }
-
-    /// Return the known rust type we should use to create a correctly-aligned
-    /// field with this layout.
-    pub(crate) fn known_rust_type_for_array(
-        &self,
-        ctx: &BindgenContext,
-    ) -> Option<syn::Type> {
-        Layout::known_type_for_size(ctx, self.0.align)
-    }
-
-    /// Return the array size that an opaque type for this layout should have if
-    /// we know the correct type for it, or `None` otherwise.
-    pub(crate) fn array_size(&self, ctx: &BindgenContext) -> Option<usize> {
-        if self.known_rust_type_for_array(ctx).is_some() {
-            Some(self.0.size / cmp::max(self.0.align, 1))
-        } else {
-            None
-        }
-    }
-
-    /// Return `true` if this opaque layout's array size will fit within the
-    /// maximum number of array elements that Rust allows deriving traits
-    /// with. Return `false` otherwise.
-    pub(crate) fn array_size_within_derive_limit(
-        &self,
-        ctx: &BindgenContext,
-    ) -> CanDerive {
-        if self
-            .array_size(ctx)
-            .map_or(false, |size| size <= RUST_DERIVE_IN_ARRAY_LIMIT)
-        {
-            CanDerive::Yes
-        } else {
-            CanDerive::Manually
-        }
     }
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/module.rs firefox-140.10.2/third_party/rust/bindgen/ir/module.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/module.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/module.rs	Mon May 11 04:49:32 2026
@@ -84,8 +84,8 @@
                 let module_id = ctx.module(cursor);
                 ctx.with_module(module_id, |ctx| {
                     cursor.visit_sorted(ctx, |ctx, child| {
-                        parse_one(ctx, child, Some(module_id.into()))
-                    })
+                        parse_one(ctx, child, Some(module_id.into()));
+                    });
                 });
 
                 Ok(ParseResult::AlreadyResolved(module_id.into()))
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/objc.rs firefox-140.10.2/third_party/rust/bindgen/ir/objc.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/objc.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/objc.rs	Mon May 11 04:49:32 2026
@@ -17,20 +17,20 @@
 use clang_sys::CXCursor_TemplateTypeParameter;
 use proc_macro2::{Ident, Span, TokenStream};
 
-/// Objective C interface as used in TypeKind
+/// Objective-C interface as used in `TypeKind`
 ///
-/// Also protocols and categories are parsed as this type
+/// Also, protocols and categories are parsed as this type
 #[derive(Debug)]
 pub(crate) struct ObjCInterface {
     /// The name
-    /// like, NSObject
+    /// like, `NSObject`
     name: String,
 
     category: Option<String>,
 
     is_protocol: bool,
 
-    /// The list of template names almost always, ObjectType or KeyType
+    /// The list of template names almost always, `ObjectType` or `KeyType`
     pub(crate) template_names: Vec<String>,
 
     /// The list of protocols that this interface conforms to.
@@ -39,7 +39,7 @@
     /// The direct parent for this interface.
     pub(crate) parent_class: Option<ItemId>,
 
-    /// List of the methods defined in this interfae
+    /// List of the methods defined in this interface
     methods: Vec<ObjCMethod>,
 
     class_methods: Vec<ObjCMethod>,
@@ -53,7 +53,7 @@
     name: String,
 
     /// Method name as converted to rust
-    /// like, dataWithBytes_length_
+    /// like, `dataWithBytes_length`_
     rust_name: String,
 
     signature: FunctionSig,
@@ -77,17 +77,17 @@
     }
 
     /// The name
-    /// like, NSObject
+    /// like, `NSObject`
     pub(crate) fn name(&self) -> &str {
         self.name.as_ref()
     }
 
     /// Formats the name for rust
-    /// Can be like NSObject, but with categories might be like NSObject_NSCoderMethods
-    /// and protocols are like PNSObject
+    /// Can be like `NSObject`, but with categories might be like `NSObject_NSCoderMethods`
+    /// and protocols are like `PNSObject`
     pub(crate) fn rust_name(&self) -> String {
         if let Some(ref cat) = self.category {
-            format!("{}_{}", self.name(), cat)
+            format!("{}_{cat}", self.name())
         } else if self.is_protocol {
             format!("P{}", self.name())
         } else {
@@ -137,7 +137,7 @@
                 CXCursor_ObjCClassRef => {
                     if cursor.kind() == CXCursor_ObjCCategoryDecl {
                         // We are actually a category extension, and we found the reference
-                        // to the original interface, so name this interface approriately
+                        // to the original interface, so name this interface appropriately
                         interface.name = c.spelling();
                         interface.category = Some(cursor.spelling());
                     }
@@ -147,8 +147,8 @@
                     let needle = format!("P{}", c.spelling());
                     let items_map = ctx.items();
                     debug!(
-                        "Interface {} conforms to {}, find the item",
-                        interface.name, needle
+                        "Interface {} conforms to {needle}, find the item",
+                        interface.name,
                     );
 
                     for (id, item) in items_map {
@@ -163,10 +163,7 @@
                                         ty.name()
                                     );
                                     if Some(needle.as_ref()) == ty.name() {
-                                        debug!(
-                                            "Found conforming protocol {:?}",
-                                            item
-                                        );
+                                        debug!("Found conforming protocol {item:?}");
                                         interface.conforms_to.push(id);
                                         break;
                                     }
@@ -230,12 +227,12 @@
     }
 
     /// Method name as converted to rust
-    /// like, dataWithBytes_length_
+    /// like, `dataWithBytes_length`_
     pub(crate) fn rust_name(&self) -> &str {
         self.rust_name.as_ref()
     }
 
-    /// Returns the methods signature as FunctionSig
+    /// Returns the methods signature as `FunctionSig`
     pub(crate) fn signature(&self) -> &FunctionSig {
         &self.signature
     }
@@ -262,10 +259,7 @@
                     // unless it is `crate`, `self`, `super` or `Self`, so we try to add the `_`
                     // suffix to it and parse it.
                     if ["crate", "self", "super", "Self"].contains(&name) {
-                        Some(Ident::new(
-                            &format!("{}_", name),
-                            Span::call_site(),
-                        ))
+                        Some(Ident::new(&format!("{name}_"), Span::call_site()))
                     } else {
                         Some(Ident::new(name, Span::call_site()))
                     }
@@ -278,11 +272,11 @@
                     Some(
                         syn::parse_str::<Ident>(name)
                             .or_else(|err| {
-                                syn::parse_str::<Ident>(&format!("r#{}", name))
+                                syn::parse_str::<Ident>(&format!("r#{name}"))
                                     .map_err(|_| err)
                             })
                             .or_else(|err| {
-                                syn::parse_str::<Ident>(&format!("{}_", name))
+                                syn::parse_str::<Ident>(&format!("{name}_"))
                                     .map_err(|_| err)
                             })
                             .expect("Invalid identifier"),
@@ -300,20 +294,15 @@
         }
 
         // Check right amount of arguments
-        assert!(
-            args.len() == split_name.len() - 1,
-            "Incorrect method name or arguments for objc method, {:?} vs {:?}",
-            args,
-            split_name
-        );
+        assert_eq!(args.len(), split_name.len() - 1, "Incorrect method name or arguments for objc method, {args:?} vs {split_name:?}");
 
         // Get arguments without type signatures to pass to `msg_send!`
         let mut args_without_types = vec![];
-        for arg in args.iter() {
+        for arg in args {
             let arg = arg.to_string();
             let name_and_sig: Vec<&str> = arg.split(' ').collect();
             let name = name_and_sig[0];
-            args_without_types.push(Ident::new(name, Span::call_site()))
+            args_without_types.push(Ident::new(name, Span::call_site()));
         }
 
         let args = split_name.into_iter().zip(args_without_types).map(
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/template.rs firefox-140.10.2/third_party/rust/bindgen/ir/template.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/template.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/template.rs	Mon May 11 04:49:32 2026
@@ -4,7 +4,7 @@
 //! brief definitions:
 //!
 //! * "Template definition": a class/struct/alias/function definition that takes
-//! generic template parameters. For example:
+//!   generic template parameters. For example:
 //!
 //! ```c++
 //! template<typename T>
@@ -14,11 +14,11 @@
 //! ```
 //!
 //! * "Template instantiation": an instantiation is a use of a template with
-//! concrete template arguments. For example, `List<int>`.
+//!   concrete template arguments. For example, `List<int>`.
 //!
 //! * "Template specialization": an alternative template definition providing a
-//! custom definition for instantiations with the matching template
-//! arguments. This C++ feature is unsupported by bindgen. For example:
+//!   custom definition for instantiations with the matching template
+//!   arguments. This C++ feature is unsupported by bindgen. For example:
 //!
 //! ```c++
 //! template<>
@@ -77,27 +77,23 @@
 /// The following table depicts the results of each trait method when invoked on
 /// each of the declarations above:
 ///
-/// +------+----------------------+--------------------------+-------------------------+----
-/// |Decl. | self_template_params | num_self_template_params | all_template_parameters | ...
-/// +------+----------------------+--------------------------+-------------------------+----
-/// |Foo   | T, U                 | 2                        | T, U                    | ...
-/// |Bar   | V                    | 1                        | T, U, V                 | ...
-/// |Inner |                      | 0                        | T, U                    | ...
-/// |Lol   | W                    | 1                        | T, U, W                 | ...
-/// |Wtf   | X                    | 1                        | T, U, X                 | ...
-/// |Qux   |                      | 0                        |                         | ...
-/// +------+----------------------+--------------------------+------------------------+----
+/// |Decl. | self_template_params | num_self_template_params | all_template_parameters |
+/// |------|----------------------|--------------------------|-------------------------|
+/// |Foo   | T, U                 | 2                        | T, U                    |
+/// |Bar   | V                    | 1                        | T, U, V                 |
+/// |Inner |                      | 0                        | T, U                    |
+/// |Lol   | W                    | 1                        | T, U, W                 |
+/// |Wtf   | X                    | 1                        | T, U, X                 |
+/// |Qux   |                      | 0                        |                         |
 ///
-/// ----+------+-----+----------------------+
-/// ... |Decl. | ... | used_template_params |
-/// ----+------+-----+----------------------+
-/// ... |Foo   | ... | T, U                 |
-/// ... |Bar   | ... | V                    |
-/// ... |Inner | ... |                      |
-/// ... |Lol   | ... | T                    |
-/// ... |Wtf   | ... | T                    |
-/// ... |Qux   | ... |                      |
-/// ----+------+-----+----------------------+
+/// | Decl. | used_template_params |
+/// |-------|----------------------|
+/// | Foo   | T, U                 |
+/// | Bar   | V                    |
+/// | Inner |                      |
+/// | Lol   | T                    |
+/// | Wtf   | T                    |
+/// | Qux   |                      |
 pub(crate) trait TemplateParameters: Sized {
     /// Get the set of `ItemId`s that make up this template declaration's free
     /// template parameters.
@@ -266,17 +262,14 @@
             })
         };
 
-        let definition = match definition {
-            Some(def) => def,
-            None => {
-                if !ty.declaration().is_builtin() {
-                    warn!(
-                        "Could not find template definition for template \
+        let Some(definition) = definition else {
+            if !ty.declaration().is_builtin() {
+                warn!(
+                    "Could not find template definition for template \
                          instantiation"
-                    );
-                }
-                return None;
+                );
             }
+            return None;
         };
 
         let template_definition =
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/traversal.rs firefox-140.10.2/third_party/rust/bindgen/ir/traversal.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/traversal.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/traversal.rs	Mon May 11 04:49:32 2026
@@ -235,7 +235,7 @@
 /// outgoing edges might not have been fully traversed yet) in an active
 /// traversal.
 pub(crate) trait TraversalStorage<'ctx> {
-    /// Construct a new instance of this TraversalStorage, for a new traversal.
+    /// Construct a new instance of this `TraversalStorage`, for a new traversal.
     fn new(ctx: &'ctx BindgenContext) -> Self;
 
     /// Add the given item to the storage. If the item has never been seen
@@ -287,8 +287,7 @@
             }
             path.reverse();
             panic!(
-                "Found reference to dangling id = {:?}\nvia path = {:?}",
-                item, path
+                "Found reference to dangling id = {item:?}\nvia path = {path:?}"
             );
         }
 
@@ -345,7 +344,7 @@
     F: FnMut(ItemId, EdgeKind),
 {
     fn visit_kind(&mut self, item: ItemId, kind: EdgeKind) {
-        (*self)(item, kind)
+        (*self)(item, kind);
     }
 }
 
@@ -438,7 +437,7 @@
         let is_newly_discovered =
             self.seen.add(self.currently_traversing, item);
         if is_newly_discovered {
-            self.queue.push(item)
+            self.queue.push(item);
         }
     }
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/ty.rs firefox-140.10.2/third_party/rust/bindgen/ir/ty.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/ty.rs	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/ty.rs	Mon May 11 04:49:32 2026
@@ -6,7 +6,7 @@
 use super::enum_ty::Enum;
 use super::function::FunctionSig;
 use super::item::{IsOpaque, Item};
-use super::layout::{Layout, Opaque};
+use super::layout::Layout;
 use super::objc::ObjCInterface;
 use super::template::{
     AsTemplateParam, TemplateInstantiation, TemplateParameters,
@@ -67,6 +67,17 @@
         }
     }
 
+    /// Construct an opaque item from a clang type.
+    pub(crate) fn new_opaque_from_clang_ty(
+        ty: &clang::Type,
+        ctx: &BindgenContext,
+    ) -> Self {
+        let layout = Layout::new(ty.size(ctx), ty.align(ctx));
+        let ty_kind = TypeKind::Opaque;
+        let is_const = ty.is_const();
+        Type::new(None, Some(layout), ty_kind, is_const)
+    }
+
     /// Which kind of type is this?
     pub(crate) fn kind(&self) -> &TypeKind {
         &self.kind
@@ -243,16 +254,16 @@
     }
 
     /// Takes `name`, and returns a suitable identifier representation for it.
-    fn sanitize_name(name: &str) -> Cow<str> {
+    fn sanitize_name(name: &str) -> Cow<'_, str> {
         if clang::is_valid_identifier(name) {
             return Cow::Borrowed(name);
         }
 
-        let name = name.replace(|c| c == ' ' || c == ':' || c == '.', "_");
+        let name = name.replace([' ', ':', '.'], "_");
         Cow::Owned(name)
     }
 
-    /// Get this type's santizied name.
+    /// Get this type's sanitized name.
     pub(crate) fn sanitized_name<'a>(
         &'a self,
         ctx: &BindgenContext,
@@ -261,7 +272,7 @@
             TypeKind::Pointer(inner) => Some((inner, Cow::Borrowed("ptr"))),
             TypeKind::Reference(inner) => Some((inner, Cow::Borrowed("ref"))),
             TypeKind::Array(inner, length) => {
-                Some((inner, format!("array{}", length).into()))
+                Some((inner, format!("array{length}").into()))
             }
             _ => None,
         };
@@ -269,13 +280,13 @@
             ctx.resolve_item(inner)
                 .expect_type()
                 .sanitized_name(ctx)
-                .map(|name| format!("{}_{}", prefix, name).into())
+                .map(|name| format!("{prefix}_{name}").into())
         } else {
             self.name().map(Self::sanitize_name)
         }
     }
 
-    /// See safe_canonical_type.
+    /// See [`Self::safe_canonical_type`].
     pub(crate) fn canonical_type<'tr>(
         &'tr self,
         ctx: &'tr BindgenContext,
@@ -471,7 +482,7 @@
 #[test]
 fn is_invalid_type_param_valid() {
     let ty = Type::new(Some("foo".into()), None, TypeKind::TypeParam, false);
-    assert!(!ty.is_invalid_type_param())
+    assert!(!ty.is_invalid_type_param());
 }
 
 #[test]
@@ -482,38 +493,38 @@
         TypeKind::TypeParam,
         false,
     );
-    assert!(!ty.is_invalid_type_param())
+    assert!(!ty.is_invalid_type_param());
 }
 
 #[test]
 fn is_invalid_type_param_valid_unnamed_kind() {
     let ty = Type::new(Some("foo".into()), None, TypeKind::Void, false);
-    assert!(!ty.is_invalid_type_param())
+    assert!(!ty.is_invalid_type_param());
 }
 
 #[test]
 fn is_invalid_type_param_invalid_start() {
     let ty = Type::new(Some("1foo".into()), None, TypeKind::TypeParam, false);
-    assert!(ty.is_invalid_type_param())
+    assert!(ty.is_invalid_type_param());
 }
 
 #[test]
-fn is_invalid_type_param_invalid_remaing() {
+fn is_invalid_type_param_invalid_remaining() {
     let ty = Type::new(Some("foo-".into()), None, TypeKind::TypeParam, false);
-    assert!(ty.is_invalid_type_param())
+    assert!(ty.is_invalid_type_param());
 }
 
 #[test]
-#[should_panic]
+#[should_panic(expected = "Unnamed named type")]
 fn is_invalid_type_param_unnamed() {
     let ty = Type::new(None, None, TypeKind::TypeParam, false);
-    assert!(ty.is_invalid_type_param())
+    assert!(ty.is_invalid_type_param());
 }
 
 #[test]
 fn is_invalid_type_param_empty_name() {
-    let ty = Type::new(Some("".into()), None, TypeKind::TypeParam, false);
-    assert!(ty.is_invalid_type_param())
+    let ty = Type::new(Some(String::new()), None, TypeKind::TypeParam, false);
+    assert!(ty.is_invalid_type_param());
 }
 
 impl TemplateParameters for Type {
@@ -582,7 +593,7 @@
     /// A compound type, that is, a class, struct, or union.
     Comp(CompInfo),
 
-    /// An opaque type that we just don't understand. All usage of this shoulf
+    /// An opaque type that we just don't understand. All usage of this should
     /// result in an opaque blob of bytes generated from the containing type's
     /// layout.
     Opaque,
@@ -623,7 +634,7 @@
     /// A pointer to an Apple block.
     BlockPointer(TypeId),
 
-    /// A reference to a type, as in: int& foo().
+    /// A reference to a type, as in: int& `foo()`.
     Reference(TypeId),
 
     /// An instantiation of an abstract template definition with a set of
@@ -634,15 +645,10 @@
     /// itself, and postpones its resolution.
     ///
     /// These are gone in a phase after parsing where these are mapped to
-    /// already known types, and are converted to ResolvedTypeRef.
+    /// already known types, and are converted to `ResolvedTypeRef`.
     ///
     /// see tests/headers/typeref.hpp to see somewhere where this is a problem.
-    UnresolvedTypeRef(
-        clang::Type,
-        clang::Cursor,
-        /* parent_id */
-        Option<ItemId>,
-    ),
+    UnresolvedTypeRef(clang::Type, Cursor, /* parent_id */ Option<ItemId>),
 
     /// An indirection to another type.
     ///
@@ -685,7 +691,7 @@
                 Some(location),
             );
             if let Some(ty) = already_resolved {
-                debug!("{:?} already resolved: {:?}", ty, location);
+                debug!("{ty:?} already resolved: {location:?}");
                 return Ok(ParseResult::AlreadyResolved(ty.into()));
             }
         }
@@ -700,8 +706,7 @@
         };
 
         debug!(
-            "from_clang_ty: {:?}, ty: {:?}, loc: {:?}",
-            potential_id, ty, location
+            "from_clang_ty: {potential_id:?}, ty: {ty:?}, loc: {location:?}"
         );
         debug!("currently_parsed_types: {:?}", ctx.currently_parsed_types());
 
@@ -711,7 +716,7 @@
         let mut ty_kind = ty.kind();
         match location.kind() {
             CXCursor_ObjCProtocolDecl | CXCursor_ObjCCategoryDecl => {
-                ty_kind = CXType_ObjCInterface
+                ty_kind = CXType_ObjCInterface;
             }
             _ => {}
         }
@@ -743,7 +748,7 @@
                  opaque type instead."
             );
             return Ok(ParseResult::New(
-                Opaque::from_clang_ty(&canonical_ty, ctx),
+                Self::new_opaque_from_clang_ty(&canonical_ty, ctx),
                 None,
             ));
         }
@@ -776,7 +781,7 @@
                                     // etc.
                                     !canonical_ty.spelling().contains("type-parameter") =>
                 {
-                    debug!("Looking for canonical type: {:?}", canonical_ty);
+                    debug!("Looking for canonical type: {canonical_ty:?}");
                     return Self::from_clang_ty(
                         potential_id,
                         &canonical_ty,
@@ -797,10 +802,7 @@
                     // Same here, with template specialisations we can safely
                     // assume this is a Comp(..)
                     } else if ty.is_fully_instantiated_template() {
-                        debug!(
-                            "Template specialization: {:?}, {:?} {:?}",
-                            ty, location, canonical_ty
-                        );
+                        debug!("Template specialization: {ty:?}, {location:?} {canonical_ty:?}");
                         let complex = CompInfo::from_ty(
                             potential_id,
                             ty,
@@ -869,20 +871,17 @@
                                     Some(location),
                                     ctx,
                                 );
-                                match complex {
-                                    Ok(complex) => TypeKind::Comp(complex),
-                                    Err(_) => {
-                                        warn!(
-                                            "Could not create complex type \
-                                             from class template or base \
-                                             specifier, using opaque blob"
-                                        );
-                                        let opaque =
-                                            Opaque::from_clang_ty(ty, ctx);
-                                        return Ok(ParseResult::New(
-                                            opaque, None,
-                                        ));
-                                    }
+                                if let Ok(complex) = complex {
+                                    TypeKind::Comp(complex)
+                                } else {
+                                    warn!(
+                                        "Could not create complex type \
+                                         from class template or base \
+                                         specifier, using opaque blob"
+                                    );
+                                    let opaque =
+                                        Self::new_opaque_from_clang_ty(ty, ctx);
+                                    return Ok(ParseResult::New(opaque, None));
                                 }
                             }
                             CXCursor_TypeAliasTemplateDecl => {
@@ -930,16 +929,12 @@
                                     CXChildVisit_Continue
                                 });
 
-                                let inner_type = match inner {
-                                    Ok(inner) => inner,
-                                    Err(..) => {
-                                        warn!(
-                                            "Failed to parse template alias \
-                                             {:?}",
-                                            location
-                                        );
-                                        return Err(ParseError::Continue);
-                                    }
+                                let Ok(inner_type) = inner else {
+                                    warn!(
+                                        "Failed to parse template alias \
+                                             {location:?}"
+                                    );
+                                    return Err(ParseError::Continue);
                                 };
 
                                 TypeKind::TemplateAlias(inner_type, args)
@@ -948,13 +943,7 @@
                                 let referenced = location.referenced().unwrap();
                                 let referenced_ty = referenced.cur_type();
 
-                                debug!(
-                                    "TemplateRef: location = {:?}; referenced = \
-                                        {:?}; referenced_ty = {:?}",
-                                    location,
-                                    referenced,
-                                    referenced_ty
-                                );
+                                debug!("TemplateRef: location = {location:?}; referenced = {referenced:?}; referenced_ty = {referenced_ty:?}");
 
                                 return Self::from_clang_ty(
                                     potential_id,
@@ -969,11 +958,7 @@
                                 let referenced_ty = referenced.cur_type();
                                 let declaration = referenced_ty.declaration();
 
-                                debug!(
-                                    "TypeRef: location = {:?}; referenced = \
-                                     {:?}; referenced_ty = {:?}",
-                                    location, referenced, referenced_ty
-                                );
+                                debug!("TypeRef: location = {location:?}; referenced = {referenced:?}; referenced_ty = {referenced_ty:?}");
 
                                 let id = Item::from_ty_or_ref_with_id(
                                     potential_id,
@@ -991,16 +976,11 @@
                             }
                             _ => {
                                 if ty.kind() == CXType_Unexposed {
-                                    warn!(
-                                        "Unexposed type {:?}, recursing inside, \
-                                          loc: {:?}",
-                                        ty,
-                                        location
-                                    );
+                                    warn!("Unexposed type {ty:?}, recursing inside, loc: {location:?}");
                                     return Err(ParseError::Recurse);
                                 }
 
-                                warn!("invalid type {:?}", ty);
+                                warn!("invalid type {ty:?}");
                                 return Err(ParseError::Continue);
                             }
                         }
@@ -1008,7 +988,7 @@
                 }
                 CXType_Auto => {
                     if canonical_ty == *ty {
-                        debug!("Couldn't find deduced type: {:?}", ty);
+                        debug!("Couldn't find deduced type: {ty:?}");
                         return Err(ParseError::Continue);
                     }
 
@@ -1092,7 +1072,7 @@
                         Item::from_ty_or_ref(inner, location, None, ctx);
                     if inner_id == potential_id {
                         warn!(
-                            "Generating oqaque type instead of self-referential \
+                            "Generating opaque type instead of self-referential \
                             typedef");
                         // This can happen if we bail out of recursive situations
                         // within the clang parsing.
@@ -1148,7 +1128,7 @@
 
                     TypeKind::Comp(complex)
                 }
-                CXType_Vector => {
+                CXType_Vector | CXType_ExtVector => {
                     let inner = Item::from_ty(
                         ty.elem_type().as_ref().unwrap(),
                         location,
@@ -1167,6 +1147,18 @@
                     .expect("Not able to resolve array element?");
                     TypeKind::Array(inner, ty.num_elements().unwrap())
                 }
+                CXType_Atomic => {
+                    // TODO(emilio): Maybe we can preserve the "is atomic" bit somehow and generate
+                    // something more useful... But for now this is better than panicking or
+                    // generating nothing.
+                    return Self::from_clang_ty(
+                        potential_id,
+                        &ty.atomic_value_type(),
+                        location,
+                        parent_id,
+                        ctx,
+                    );
+                }
                 CXType_Elaborated => {
                     return Self::from_clang_ty(
                         potential_id,
@@ -1191,10 +1183,8 @@
                 }
                 _ => {
                     warn!(
-                        "unsupported type: kind = {:?}; ty = {:?}; at {:?}",
+                        "unsupported type: kind = {:?}; ty = {ty:?}; at {location:?}",
                         ty.kind(),
-                        ty,
-                        location
                     );
                     return Err(ParseError::Continue);
                 }
@@ -1205,8 +1195,7 @@
 
         let is_const = ty.is_const() ||
             (ty.kind() == CXType_ConstantArray &&
-                ty.elem_type()
-                    .map_or(false, |element| element.is_const()));
+                ty.elem_type().is_some_and(|element| element.is_const()));
 
         let ty = Type::new(name, layout, kind, is_const);
         // TODO: maybe declaration.canonical()?
@@ -1221,10 +1210,7 @@
     where
         T: Tracer,
     {
-        if self
-            .name()
-            .map_or(false, |name| context.is_stdint_type(name))
-        {
+        if self.name().is_some_and(|name| context.is_stdint_type(name)) {
             // These types are special-cased in codegen and don't need to be traversed.
             return;
         }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/ir/var.rs firefox-140.10.2/third_party/rust/bindgen/ir/var.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/ir/var.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/ir/var.rs	Mon May 11 04:49:32 2026
@@ -113,11 +113,7 @@
         }
 
         if let Some(ref mangled) = self.mangled_name {
-            writeln!(
-                out,
-                "<tr><td>mangled name</td><td>{}</td></tr>",
-                mangled
-            )?;
+            writeln!(out, "<tr><td>mangled name</td><td>{mangled}</td></tr>")?;
         }
 
         Ok(())
@@ -129,35 +125,32 @@
         ctx.options().default_macro_constant_type ==
             MacroTypeVariation::Signed
     {
-        if value < i32::min_value() as i64 || value > i32::max_value() as i64 {
+        if value < i64::from(i32::MIN) || value > i64::from(i32::MAX) {
             IntKind::I64
         } else if !ctx.options().fit_macro_constants ||
-            value < i16::min_value() as i64 ||
-            value > i16::max_value() as i64
+            value < i64::from(i16::MIN) ||
+            value > i64::from(i16::MAX)
         {
             IntKind::I32
-        } else if value < i8::min_value() as i64 ||
-            value > i8::max_value() as i64
-        {
+        } else if value < i64::from(i8::MIN) || value > i64::from(i8::MAX) {
             IntKind::I16
         } else {
             IntKind::I8
         }
-    } else if value > u32::max_value() as i64 {
+    } else if value > i64::from(u32::MAX) {
         IntKind::U64
-    } else if !ctx.options().fit_macro_constants ||
-        value > u16::max_value() as i64
+    } else if !ctx.options().fit_macro_constants || value > i64::from(u16::MAX)
     {
         IntKind::U32
-    } else if value > u8::max_value() as i64 {
+    } else if value > i64::from(u8::MAX) {
         IntKind::U16
     } else {
         IntKind::U8
     }
 }
 
-/// Parses tokens from a CXCursor_MacroDefinition pointing into a function-like
-/// macro, and calls the func_macro callback.
+/// Parses tokens from a `CXCursor_MacroDefinition` pointing into a function-like
+/// macro, and calls the `func_macro` callback.
 fn handle_function_macro(
     cursor: &clang::Cursor,
     callbacks: &dyn crate::callbacks::ParseCallbacks,
@@ -206,9 +199,8 @@
 
                 let value = parse_macro(ctx, &cursor);
 
-                let (id, value) = match value {
-                    Some(v) => v,
-                    None => return Err(ParseError::Continue),
+                let Some((id, value)) = value else {
+                    return Err(ParseError::Continue);
                 };
 
                 assert!(!id.is_empty(), "Empty macro name?");
@@ -242,10 +234,7 @@
                                 assert_eq!(c.len_utf8(), 1);
                                 c as u8
                             }
-                            CChar::Raw(c) => {
-                                assert!(c <= ::std::u8::MAX as u64);
-                                c as u8
-                            }
+                            CChar::Raw(c) => u8::try_from(c).unwrap(),
                         };
 
                         (TypeKind::Int(IntKind::U8), VarType::Char(c))
@@ -315,7 +304,7 @@
                     ([CXType_ConstantArray, CXType_IncompleteArray]
                         .contains(&ty.kind()) &&
                         ty.elem_type()
-                            .map_or(false, |element| element.is_const()));
+                            .is_some_and(|element| element.is_const()));
 
                 let ty = match Item::from_ty(&ty, cursor, None, ctx) {
                     Ok(ty) => ty,
@@ -324,7 +313,7 @@
                             matches!(ty.kind(), CXType_Auto | CXType_Unexposed),
                             "Couldn't resolve constant type, and it \
                              wasn't an nondeductible auto type or unexposed \
-                             type!"
+                             type: {ty:?}"
                         );
                         return Err(e);
                     }
@@ -338,17 +327,17 @@
                     .safe_resolve_type(ty)
                     .and_then(|t| t.safe_canonical_type(ctx));
 
-                let is_integer = canonical_ty.map_or(false, |t| t.is_integer());
-                let is_float = canonical_ty.map_or(false, |t| t.is_float());
+                let is_integer = canonical_ty.is_some_and(|t| t.is_integer());
+                let is_float = canonical_ty.is_some_and(|t| t.is_float());
 
                 // TODO: We could handle `char` more gracefully.
                 // TODO: Strings, though the lookup is a bit more hard (we need
                 // to look at the canonical type of the pointee too, and check
                 // is char, u8, or i8 I guess).
                 let value = if is_integer {
-                    let kind = match *canonical_ty.unwrap().kind() {
-                        TypeKind::Int(kind) => kind,
-                        _ => unreachable!(),
+                    let TypeKind::Int(kind) = *canonical_ty.unwrap().kind()
+                    else {
+                        unreachable!()
                     };
 
                     let mut val = cursor.evaluate().and_then(|v| v.as_int());
@@ -389,20 +378,66 @@
     }
 }
 
+/// This function uses a [`FallbackTranslationUnit`][clang::FallbackTranslationUnit] to parse each
+/// macro that cannot be parsed by the normal bindgen process for `#define`s.
+///
+/// To construct the [`FallbackTranslationUnit`][clang::FallbackTranslationUnit], first precompiled
+/// headers are generated for all input headers. An empty temporary `.c` file is generated to pass
+/// to the translation unit. On the evaluation of each macro, a [`String`] is generated with the
+/// new contents of the empty file and passed in for reparsing. The precompiled headers and
+/// preservation of the [`FallbackTranslationUnit`][clang::FallbackTranslationUnit] across macro
+/// evaluations are both optimizations that have significantly improved the performance.
+fn parse_macro_clang_fallback(
+    ctx: &mut BindgenContext,
+    cursor: &clang::Cursor,
+) -> Option<(Vec<u8>, cexpr::expr::EvalResult)> {
+    if !ctx.options().clang_macro_fallback {
+        return None;
+    }
+
+    let ftu = ctx.try_ensure_fallback_translation_unit()?;
+    let contents = format!("int main() {{ {}; }}", cursor.spelling());
+    ftu.reparse(&contents).ok()?;
+    // Children of root node of AST
+    let root_children = ftu.translation_unit().cursor().collect_children();
+    // Last child in root is function declaration
+    // Should be FunctionDecl
+    let main_func = root_children.last()?;
+    // Children should all be statements in function declaration
+    let all_stmts = main_func.collect_children();
+    // First child in all_stmts should be the statement containing the macro to evaluate
+    // Should be CompoundStmt
+    let macro_stmt = all_stmts.first()?;
+    // Children should all be expressions from the compound statement
+    let paren_exprs = macro_stmt.collect_children();
+    // First child in all_exprs is the expression utilizing the given macro to be evaluated
+    // Should  be ParenExpr
+    let paren = paren_exprs.first()?;
+
+    Some((
+        cursor.spelling().into_bytes(),
+        cexpr::expr::EvalResult::Int(Wrapping(paren.evaluate()?.as_int()?)),
+    ))
+}
+
 /// Try and parse a macro using all the macros parsed until now.
 fn parse_macro(
-    ctx: &BindgenContext,
+    ctx: &mut BindgenContext,
     cursor: &clang::Cursor,
 ) -> Option<(Vec<u8>, cexpr::expr::EvalResult)> {
     use cexpr::expr;
 
-    let cexpr_tokens = cursor.cexpr_tokens();
+    let mut cexpr_tokens = cursor.cexpr_tokens();
 
+    for callbacks in &ctx.options().parse_callbacks {
+        callbacks.modify_macro(&cursor.spelling(), &mut cexpr_tokens);
+    }
+
     let parser = expr::IdentifierParser::new(ctx.parsed_macros());
 
     match parser.macro_definition(&cexpr_tokens) {
         Ok((_, (id, val))) => Some((id.into(), val)),
-        _ => None,
+        _ => parse_macro_clang_fallback(ctx, cursor),
     }
 }
 
@@ -443,15 +478,15 @@
 
 fn duplicated_macro_diagnostic(
     macro_name: &str,
-    _location: crate::clang::SourceLocation,
+    _location: clang::SourceLocation,
     _ctx: &BindgenContext,
 ) {
-    warn!("Duplicated macro definition: {}", macro_name);
+    warn!("Duplicated macro definition: {macro_name}");
 
     #[cfg(feature = "experimental")]
     // FIXME (pvdrz & amanjeev): This diagnostic message shows way too often to be actually
     // useful. We have to change the logic where this function is called to be able to emit this
-    // message only when the duplication is an actuall issue.
+    // message only when the duplication is an actual issue.
     //
     // If I understood correctly, `bindgen` ignores all `#undef` directives. Meaning that this:
     // ```c
@@ -480,7 +515,7 @@
         slice.with_source(source);
 
         Diagnostic::default()
-            .with_title("Duplicated macro definition.", Level::Warn)
+            .with_title("Duplicated macro definition.", Level::Warning)
             .add_slice(slice)
             .add_annotation("This macro had a duplicate.", Level::Note)
             .display();
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/lib.rs firefox-140.10.2/third_party/rust/bindgen/lib.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/lib.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/lib.rs	Mon May 11 04:49:32 2026
@@ -19,8 +19,6 @@
 #[macro_use]
 extern crate bitflags;
 #[macro_use]
-extern crate lazy_static;
-#[macro_use]
 extern crate quote;
 
 #[cfg(feature = "logging")]
@@ -52,12 +50,11 @@
 pub use codegen::{
     AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle,
 };
-#[cfg(feature = "__cli")]
-pub use features::RUST_TARGET_STRINGS;
-pub use features::{RustTarget, LATEST_STABLE_RUST};
+pub use features::{RustEdition, RustTarget, LATEST_STABLE_RUST};
 pub use ir::annotations::FieldVisibilityKind;
 pub use ir::function::Abi;
-pub use regex_set::RegexSet;
+#[cfg(feature = "__cli")]
+pub use options::cli::builder_from_flags;
 
 use codegen::CodegenError;
 use features::RustFeatures;
@@ -73,6 +70,7 @@
 use std::ffi::OsStr;
 use std::fs::{File, OpenOptions};
 use std::io::{self, Write};
+use std::mem::size_of;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::rc::Rc;
@@ -88,10 +86,12 @@
 const DEFAULT_NON_EXTERN_FNS_SUFFIX: &str = "__extern";
 
 fn file_is_cpp(name_file: &str) -> bool {
-    name_file.ends_with(".hpp") ||
-        name_file.ends_with(".hxx") ||
-        name_file.ends_with(".hh") ||
-        name_file.ends_with(".h++")
+    Path::new(name_file).extension().is_some_and(|ext| {
+        ext.eq_ignore_ascii_case("hpp") ||
+            ext.eq_ignore_ascii_case("hxx") ||
+            ext.eq_ignore_ascii_case("hh") ||
+            ext.eq_ignore_ascii_case("h++")
+    })
 }
 
 fn args_are_cpp(clang_args: &[Box<str>]) -> bool {
@@ -144,7 +144,7 @@
         self.contains(CodegenConfig::VARS)
     }
 
-    /// Returns true if methds should be generated.
+    /// Returns true if methods should be generated.
     pub fn methods(self) -> bool {
         self.contains(CodegenConfig::METHODS)
     }
@@ -194,7 +194,7 @@
             "rustfmt" => Ok(Self::Rustfmt),
             #[cfg(feature = "prettyplease")]
             "prettyplease" => Ok(Self::Prettyplease),
-            _ => Err(format!("`{}` is not a valid formatter", s)),
+            _ => Err(format!("`{s}` is not a valid formatter")),
         }
     }
 }
@@ -208,7 +208,7 @@
             Self::Prettyplease => "prettyplease",
         };
 
-        s.fmt(f)
+        std::fmt::Display::fmt(&s, f)
     }
 }
 
@@ -238,6 +238,7 @@
 /// 2. [`bitfield_enum()`](#method.bitfield_enum)
 /// 3. [`newtype_enum()`](#method.newtype_enum)
 /// 4. [`rustified_enum()`](#method.rustified_enum)
+/// 5. [`rustified_non_exhaustive_enum()`](#method.rustified_non_exhaustive_enum)
 ///
 /// For each C enum, bindgen tries to match the pattern in the following order:
 ///
@@ -300,12 +301,11 @@
     parse_callbacks: &[Rc<dyn callbacks::ParseCallbacks>],
 ) -> Vec<String> {
     // Add any extra arguments from the environment to the clang command line.
-    let extra_clang_args = match get_target_dependent_env_var(
+    let Some(extra_clang_args) = get_target_dependent_env_var(
         parse_callbacks,
         "BINDGEN_EXTRA_CLANG_ARGS",
-    ) {
-        None => return vec![],
-        Some(s) => s,
+    ) else {
+        return vec![];
     };
 
     // Try to parse it with shell quoting. If we fail, make it one single big argument.
@@ -318,6 +318,22 @@
 impl Builder {
     /// Generate the Rust bindings using the options built up thus far.
     pub fn generate(mut self) -> Result<Bindings, BindgenError> {
+        // Keep rust_features synced with rust_target
+        self.options.rust_features = match self.options.rust_edition {
+            Some(edition) => {
+                if !edition.is_available(self.options.rust_target) {
+                    return Err(BindgenError::UnsupportedEdition(
+                        edition,
+                        self.options.rust_target,
+                    ));
+                }
+                RustFeatures::new(self.options.rust_target, edition)
+            }
+            None => {
+                RustFeatures::new_with_latest_edition(self.options.rust_target)
+            }
+        };
+
         // Add any extra arguments from the environment to the clang command line.
         self.options.clang_args.extend(
             get_extra_clang_args(&self.options.parse_callbacks)
@@ -331,6 +347,18 @@
         }
 
         // Transform input headers to arguments on the clang command line.
+        self.options.fallback_clang_args = self
+            .options
+            .clang_args
+            .iter()
+            .filter(|arg| {
+                !arg.starts_with("-MMD") &&
+                    !arg.starts_with("-MD") &&
+                    !arg.starts_with("--write-user-dependencies") &&
+                    !arg.starts_with("--user-dependencies")
+            })
+            .cloned()
+            .collect::<Vec<_>>();
         self.options.clang_args.extend(
             self.options.input_headers
                 [..self.options.input_headers.len().saturating_sub(1)]
@@ -346,7 +374,7 @@
                 })
                 .collect::<Vec<_>>();
 
-        Bindings::generate(self.options, input_unsaved_files)
+        Bindings::generate(self.options, &input_unsaved_files)
     }
 
     /// Preprocess and dump the input header files to disk.
@@ -527,25 +555,11 @@
         for regex_set in self.abi_overrides.values_mut().chain(regex_sets) {
             regex_set.build(record_matches);
         }
-
-        let rust_target = self.rust_target;
-        #[allow(deprecated)]
-        if rust_target <= RustTarget::Stable_1_30 {
-            deprecated_target_diagnostic(rust_target, self);
-        }
-
-        // Disable `untagged_union` if the target does not support it.
-        if !self.rust_features.untagged_union {
-            self.untagged_union = false;
-        }
     }
 
     /// Update rust target version
     pub fn set_rust_target(&mut self, rust_target: RustTarget) {
         self.rust_target = rust_target;
-
-        // Keep rust_features synced with rust_target
-        self.rust_features = rust_target.into();
     }
 
     /// Get features supported by target Rust version
@@ -560,7 +574,7 @@
         self.parse_callbacks
             .iter()
             .filter_map(|cb| f(cb.as_ref()))
-            .last()
+            .next_back()
     }
 
     fn all_callbacks<T>(
@@ -579,36 +593,15 @@
 
     fn process_comment(&self, comment: &str) -> String {
         let comment = comment::preprocess(comment);
-        self.parse_callbacks
-            .last()
-            .and_then(|cb| cb.process_comment(&comment))
+        self.last_callback(|cb| cb.process_comment(&comment))
             .unwrap_or(comment)
     }
 }
 
-fn deprecated_target_diagnostic(target: RustTarget, _options: &BindgenOptions) {
-    warn!("The {} Rust target is deprecated. If you have a need to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues", target);
-
-    #[cfg(feature = "experimental")]
-    if _options.emit_diagnostics {
-        use crate::diagnostics::{Diagnostic, Level};
-
-        let mut diagnostic = Diagnostic::default();
-        diagnostic.with_title(
-            format!("The {} Rust target is deprecated.", target),
-            Level::Warn,
-        );
-        diagnostic.add_annotation(
-            "This Rust target was passed to `--rust-target`",
-            Level::Info,
-        );
-        diagnostic.add_annotation("If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues", Level::Help);
-        diagnostic.display();
-    }
-}
-
 #[cfg(feature = "runtime")]
 fn ensure_libclang_is_loaded() {
+    use std::sync::{Arc, OnceLock};
+
     if clang_sys::is_loaded() {
         return;
     }
@@ -617,17 +610,14 @@
     // doesn't get dropped prematurely, nor is loaded multiple times
     // across different threads.
 
-    lazy_static! {
-        static ref LIBCLANG: std::sync::Arc<clang_sys::SharedLibrary> = {
-            clang_sys::load().expect("Unable to find libclang");
-            clang_sys::get_library().expect(
-                "We just loaded libclang and it had better still be \
-                 here!",
-            )
-        };
-    }
+    static LIBCLANG: OnceLock<Arc<clang_sys::SharedLibrary>> = OnceLock::new();
+    let libclang = LIBCLANG.get_or_init(|| {
+        clang_sys::load().expect("Unable to find libclang");
+        clang_sys::get_library()
+            .expect("We just loaded libclang and it had better still be here!")
+    });
 
-    clang_sys::set_library(Some(LIBCLANG.clone()));
+    clang_sys::set_library(Some(libclang.clone()));
 }
 
 #[cfg(not(feature = "runtime"))]
@@ -647,6 +637,8 @@
     ClangDiagnostic(String),
     /// Code generation reported an error.
     Codegen(CodegenError),
+    /// The passed edition is not available on that Rust target.
+    UnsupportedEdition(RustEdition, RustTarget),
 }
 
 impl std::fmt::Display for BindgenError {
@@ -662,11 +654,14 @@
                 write!(f, "header '{}' does not exist.", h.display())
             }
             BindgenError::ClangDiagnostic(message) => {
-                write!(f, "clang diagnosed error: {}", message)
+                write!(f, "clang diagnosed error: {message}")
             }
             BindgenError::Codegen(err) => {
-                write!(f, "codegen error: {}", err)
+                write!(f, "codegen error: {err}")
             }
+            BindgenError::UnsupportedEdition(edition, target) => {
+                write!(f, "edition {edition} is not available on Rust {target}")
+            }
         }
     }
 }
@@ -686,35 +681,46 @@
 // Some architecture triplets are different between rust and libclang, see #1211
 // and duplicates.
 fn rust_to_clang_target(rust_target: &str) -> Box<str> {
-    if rust_target.starts_with("aarch64-apple-") {
-        let mut clang_target = "arm64-apple-".to_owned();
-        clang_target
-            .push_str(rust_target.strip_prefix("aarch64-apple-").unwrap());
-        return clang_target.into();
-    } else if rust_target.starts_with("riscv64gc-") {
-        let mut clang_target = "riscv64-".to_owned();
-        clang_target.push_str(rust_target.strip_prefix("riscv64gc-").unwrap());
-        return clang_target.into();
-    } else if rust_target.ends_with("-espidf") {
-        let mut clang_target =
-            rust_target.strip_suffix("-espidf").unwrap().to_owned();
-        clang_target.push_str("-elf");
-        if clang_target.starts_with("riscv32imc-") {
-            clang_target = "riscv32-".to_owned() +
-                clang_target.strip_prefix("riscv32imc-").unwrap();
+    const TRIPLE_HYPHENS_MESSAGE: &str = "Target triple should contain hyphens";
+
+    let mut triple: Vec<&str> = rust_target.split_terminator('-').collect();
+
+    assert!(!triple.is_empty(), "{}", TRIPLE_HYPHENS_MESSAGE);
+    triple.resize(4, "");
+
+    // RISC-V
+    if triple[0].starts_with("riscv32") {
+        triple[0] = "riscv32";
+    } else if triple[0].starts_with("riscv64") {
+        triple[0] = "riscv64";
+    }
+
+    // Apple
+    if triple[1] == "apple" {
+        if triple[0] == "aarch64" {
+            triple[0] = "arm64";
         }
-        return clang_target.into();
-    } else if rust_target.starts_with("riscv32imc-") {
-        let mut clang_target = "riscv32-".to_owned();
-        clang_target.push_str(rust_target.strip_prefix("riscv32imc-").unwrap());
-        return clang_target.into();
-    } else if rust_target.starts_with("riscv32imac-") {
-        let mut clang_target = "riscv32-".to_owned();
-        clang_target
-            .push_str(rust_target.strip_prefix("riscv32imac-").unwrap());
-        return clang_target.into();
+        if triple[3] == "sim" {
+            triple[3] = "simulator";
+        }
     }
-    rust_target.into()
+
+    // ESP-IDF
+    if triple[2] == "espidf" {
+        triple[2] = "elf";
+    }
+
+    triple
+        .iter()
+        .skip(1)
+        .fold(triple[0].to_string(), |triple, part| {
+            if part.is_empty() {
+                triple
+            } else {
+                triple + "-" + part
+            }
+        })
+        .into()
 }
 
 /// Returns the effective target, and whether it was explicitly specified on the
@@ -747,11 +753,23 @@
     /// Generate bindings for the given options.
     pub(crate) fn generate(
         mut options: BindgenOptions,
-        input_unsaved_files: Vec<clang::UnsavedFile>,
+        input_unsaved_files: &[clang::UnsavedFile],
     ) -> Result<Bindings, BindgenError> {
         ensure_libclang_is_loaded();
 
         #[cfg(feature = "runtime")]
+        match clang_sys::get_library().unwrap().version() {
+            None => {
+                warn!("Could not detect a Clang version, make sure you are using libclang 9 or newer");
+            }
+            Some(version) => {
+                if version < clang_sys::Version::V9_0 {
+                    warn!("Detected Clang version {version:?} which is unsupported and can cause invalid code generation, use libclang 9 or newer");
+                }
+            }
+        }
+
+        #[cfg(feature = "runtime")]
         debug!(
             "Generating bindings, libclang at {}",
             clang_sys::get_library().unwrap().path().display()
@@ -775,9 +793,9 @@
         if !explicit_target && !is_host_build {
             options.clang_args.insert(
                 0,
-                format!("--target={}", effective_target).into_boxed_str(),
+                format!("--target={effective_target}").into_boxed_str(),
             );
-        };
+        }
 
         fn detect_include_paths(options: &mut BindgenOptions) {
             if !options.detect_include_paths {
@@ -819,19 +837,17 @@
             };
 
             debug!(
-                "Trying to find clang with flags: {:?}",
-                clang_args_for_clang_sys
+                "Trying to find clang with flags: {clang_args_for_clang_sys:?}"
             );
 
-            let clang = match clang_sys::support::Clang::find(
+            let Some(clang) = clang_sys::support::Clang::find(
                 None,
                 &clang_args_for_clang_sys,
-            ) {
-                None => return,
-                Some(clang) => clang,
+            ) else {
+                return;
             };
 
-            debug!("Found clang: {:?}", clang);
+            debug!("Found clang: {clang:?}");
 
             // Whether we are working with C or C++ inputs.
             let is_cpp = args_are_cpp(&options.clang_args) ||
@@ -844,7 +860,7 @@
             };
 
             if let Some(search_paths) = search_paths {
-                for path in search_paths.into_iter() {
+                for path in search_paths {
                     if let Ok(path) = path.into_os_string().into_string() {
                         options.clang_args.push("-isystem".into());
                         options.clang_args.push(path.into_boxed_str());
@@ -887,21 +903,19 @@
             if idx != 0 || !options.input_headers.is_empty() {
                 options.clang_args.push("-include".into());
             }
-            options.clang_args.push(f.name.to_str().unwrap().into())
+            options.clang_args.push(f.name.to_str().unwrap().into());
         }
 
-        debug!("Fixed-up options: {:?}", options);
+        debug!("Fixed-up options: {options:?}");
 
         let time_phases = options.time_phases;
-        let mut context = BindgenContext::new(options, &input_unsaved_files);
+        let mut context = BindgenContext::new(options, input_unsaved_files);
 
         if is_host_build {
             debug_assert_eq!(
                 context.target_pointer_size(),
-                std::mem::size_of::<*mut ()>(),
-                "{:?} {:?}",
-                effective_target,
-                HOST_TARGET
+                size_of::<*mut ()>(),
+                "{effective_target:?} {HOST_TARGET:?}"
             );
         }
 
@@ -934,13 +948,13 @@
         if !self.options.disable_header_comment {
             let version =
                 option_env!("CARGO_PKG_VERSION").unwrap_or("(unknown version)");
-            writeln!(
+            write!(
                 writer,
-                "/* automatically generated by rust-bindgen {version} */{NL}",
+                "/* automatically generated by rust-bindgen {version} */{NL}{NL}",
             )?;
         }
 
-        for line in self.options.raw_lines.iter() {
+        for line in &self.options.raw_lines {
             writer.write_all(line.as_bytes())?;
             writer.write_all(NL.as_bytes())?;
         }
@@ -955,8 +969,7 @@
             }
             Err(err) => {
                 eprintln!(
-                    "Failed to run rustfmt: {} (non-fatal, continuing)",
-                    err
+                    "Failed to run rustfmt: {err} (non-fatal, continuing)"
                 );
                 writer.write_all(self.module.to_string().as_bytes())?;
             }
@@ -965,25 +978,17 @@
     }
 
     /// Gets the rustfmt path to rustfmt the generated bindings.
-    fn rustfmt_path(&self) -> io::Result<Cow<PathBuf>> {
+    fn rustfmt_path(&self) -> Cow<'_, Path> {
         debug_assert!(matches!(self.options.formatter, Formatter::Rustfmt));
         if let Some(ref p) = self.options.rustfmt_path {
-            return Ok(Cow::Borrowed(p));
+            Cow::Borrowed(p)
+        } else if let Ok(rustfmt) = env::var("RUSTFMT") {
+            Cow::Owned(rustfmt.into())
+        } else {
+            // No rustfmt binary was specified, so assume that the binary is called
+            // "rustfmt" and that it is in the user's PATH.
+            Cow::Borrowed(Path::new("rustfmt"))
         }
-        if let Ok(rustfmt) = env::var("RUSTFMT") {
-            return Ok(Cow::Owned(rustfmt.into()));
-        }
-        #[cfg(feature = "which-rustfmt")]
-        match which::which("rustfmt") {
-            Ok(p) => Ok(Cow::Owned(p)),
-            Err(e) => {
-                Err(io::Error::new(io::ErrorKind::Other, format!("{}", e)))
-            }
-        }
-        #[cfg(not(feature = "which-rustfmt"))]
-        // No rustfmt binary was specified, so assume that the binary is called
-        // "rustfmt" and that it is in the user's PATH.
-        Ok(Cow::Owned("rustfmt".into()))
     }
 
     /// Formats a token stream with the formatter set up in `BindgenOptions`.
@@ -1003,7 +1008,7 @@
             Formatter::Rustfmt => (),
         }
 
-        let rustfmt = self.rustfmt_path()?;
+        let rustfmt = self.rustfmt_path();
         let mut cmd = Command::new(&*rustfmt);
 
         cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
@@ -1017,6 +1022,12 @@
             cmd.args(["--config-path", path]);
         }
 
+        let edition = self
+            .options
+            .rust_edition
+            .unwrap_or_else(|| self.options.rust_target.latest_edition());
+        cmd.args(["--edition", &format!("{edition}")]);
+
         let mut child = cmd.spawn()?;
         let mut child_stdin = child.stdin.take().unwrap();
         let mut child_stdout = child.stdout.take().unwrap();
@@ -1065,14 +1076,14 @@
 }
 
 fn rustfmt_non_fatal_error_diagnostic(msg: &str, _options: &BindgenOptions) {
-    warn!("{}", msg);
+    warn!("{msg}");
 
     #[cfg(feature = "experimental")]
     if _options.emit_diagnostics {
         use crate::diagnostics::{Diagnostic, Level};
 
         Diagnostic::default()
-            .with_title(msg, Level::Warn)
+            .with_title(msg, Level::Warning)
             .add_annotation(
                 "The bindings will be generated but not formatted.",
                 Level::Note,
@@ -1124,7 +1135,7 @@
     use clang_sys::*;
 
     let mut error = None;
-    for d in context.translation_unit().diags().iter() {
+    for d in &context.translation_unit().diags() {
         let msg = d.format();
         let is_err = d.severity() >= CXDiagnostic_Error;
         if is_err {
@@ -1132,7 +1143,7 @@
             error.push_str(&msg);
             error.push('\n');
         } else {
-            eprintln!("clang diag: {}", msg);
+            eprintln!("clang diag: {msg}");
         }
     }
 
@@ -1144,10 +1155,10 @@
 
     if context.options().emit_ast {
         fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
-            if !cur.is_builtin() {
-                clang::ast_dump(cur, 0)
-            } else {
+            if cur.is_builtin() {
                 CXChildVisit_Continue
+            } else {
+                clang::ast_dump(cur, 0)
             }
         }
         cursor.visit(|cur| dump_if_not_builtin(&cur));
@@ -1155,11 +1166,12 @@
 
     let root = context.root_module();
     context.with_module(root, |ctx| {
-        cursor.visit_sorted(ctx, |ctx, child| parse_one(ctx, child, None))
+        cursor.visit_sorted(ctx, |ctx, child| parse_one(ctx, child, None));
     });
 
-    assert!(
-        context.current_module() == context.root_module(),
+    assert_eq!(
+        context.current_module(),
+        context.root_module(),
         "How did this happen?"
     );
     Ok(())
@@ -1182,7 +1194,7 @@
     let raw_v: String = clang::extract_clang_version();
     let split_v: Option<Vec<&str>> = raw_v
         .split_whitespace()
-        .find(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
+        .find(|t| t.chars().next().is_some_and(|v| v.is_ascii_digit()))
         .map(|v| v.split('.').collect());
     if let Some(v) = split_v {
         if v.len() >= 2 {
@@ -1195,7 +1207,7 @@
                 };
             }
         }
-    };
+    }
     ClangVersion {
         parsed: None,
         full: raw_v.clone(),
@@ -1205,11 +1217,11 @@
 fn env_var<K: AsRef<str> + AsRef<OsStr>>(
     parse_callbacks: &[Rc<dyn callbacks::ParseCallbacks>],
     key: K,
-) -> Result<String, std::env::VarError> {
+) -> Result<String, env::VarError> {
     for callback in parse_callbacks {
         callback.read_env_var(key.as_ref());
     }
-    std::env::var(key)
+    env::var(key)
 }
 
 /// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found.
@@ -1218,12 +1230,12 @@
     var: &str,
 ) -> Option<String> {
     if let Ok(target) = env_var(parse_callbacks, "TARGET") {
-        if let Ok(v) = env_var(parse_callbacks, format!("{}_{}", var, target)) {
+        if let Ok(v) = env_var(parse_callbacks, format!("{var}_{target}")) {
             return Some(v);
         }
         if let Ok(v) = env_var(
             parse_callbacks,
-            format!("{}_{}", var, target.replace('-', "_")),
+            format!("{var}_{}", target.replace('-', "_")),
         ) {
             return Some(v);
         }
@@ -1232,7 +1244,7 @@
     env_var(parse_callbacks, var).ok()
 }
 
-/// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed
+/// A `ParseCallbacks` implementation that will act on file includes by echoing a rerun-if-changed
 /// line and on env variable usage by echoing a rerun-if-env-changed line
 ///
 /// When running inside a `build.rs` script, this can be used to make cargo invalidate the
@@ -1285,24 +1297,24 @@
 impl callbacks::ParseCallbacks for CargoCallbacks {
     fn header_file(&self, filename: &str) {
         if self.rerun_on_header_files {
-            println!("cargo:rerun-if-changed={}", filename);
+            println!("cargo:rerun-if-changed={filename}");
         }
     }
 
     fn include_file(&self, filename: &str) {
-        println!("cargo:rerun-if-changed={}", filename);
+        println!("cargo:rerun-if-changed={filename}");
     }
 
     fn read_env_var(&self, key: &str) {
-        println!("cargo:rerun-if-env-changed={}", key);
+        println!("cargo:rerun-if-env-changed={key}");
     }
 }
 
-/// Test command_line_flag function.
+/// Test `command_line_flag` function.
 #[test]
 fn commandline_flag_unit_test_function() {
     //Test 1
-    let bindings = crate::builder();
+    let bindings = builder();
     let command_line_flags = bindings.command_line_flags();
 
     let test_cases = [
@@ -1318,7 +1330,7 @@
     assert!(test_cases.iter().all(|x| command_line_flags.contains(x)));
 
     //Test 2
-    let bindings = crate::builder()
+    let bindings = builder()
         .header("input_header")
         .allowlist_type("Distinct_Type")
         .allowlist_function("safe_function");
@@ -1338,7 +1350,7 @@
     .iter()
     .map(|&x| x.into())
     .collect::<Vec<String>>();
-    println!("{:?}", command_line_flags);
+    println!("{command_line_flags:?}");
 
     assert!(test_cases.iter().all(|x| command_line_flags.contains(x)));
 }
@@ -1358,6 +1370,10 @@
         "riscv64-unknown-linux-gnu"
     );
     assert_eq!(
+        rust_to_clang_target("riscv64imac-unknown-none-elf").as_ref(),
+        "riscv64-unknown-none-elf"
+    );
+    assert_eq!(
         rust_to_clang_target("riscv32imc-unknown-none-elf").as_ref(),
         "riscv32-unknown-none-elf"
     );
@@ -1365,6 +1381,14 @@
         rust_to_clang_target("riscv32imac-unknown-none-elf").as_ref(),
         "riscv32-unknown-none-elf"
     );
+    assert_eq!(
+        rust_to_clang_target("riscv32imafc-unknown-none-elf").as_ref(),
+        "riscv32-unknown-none-elf"
+    );
+    assert_eq!(
+        rust_to_clang_target("riscv32i-unknown-none-elf").as_ref(),
+        "riscv32-unknown-none-elf"
+    );
 }
 
 #[test]
@@ -1376,5 +1400,21 @@
     assert_eq!(
         rust_to_clang_target("xtensa-esp32-espidf").as_ref(),
         "xtensa-esp32-elf"
+    );
+}
+
+#[test]
+fn test_rust_to_clang_target_simulator() {
+    assert_eq!(
+        rust_to_clang_target("aarch64-apple-ios-sim").as_ref(),
+        "arm64-apple-ios-simulator"
+    );
+    assert_eq!(
+        rust_to_clang_target("aarch64-apple-tvos-sim").as_ref(),
+        "arm64-apple-tvos-simulator"
+    );
+    assert_eq!(
+        rust_to_clang_target("aarch64-apple-watchos-sim").as_ref(),
+        "arm64-apple-watchos-simulator"
     );
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/log_stubs.rs firefox-140.10.2/third_party/rust/bindgen/log_stubs.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/log_stubs.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/log_stubs.rs	Mon May 11 04:49:32 2026
@@ -1,5 +1,6 @@
 #![allow(unused)]
 
+#[clippy::format_args]
 macro_rules! log {
     (target: $target:expr, $lvl:expr, $($arg:tt)+) => {{
         let _ = $target;
@@ -10,22 +11,27 @@
         let _ = format_args!($($arg)+);
     }};
 }
+#[clippy::format_args]
 macro_rules! error {
     (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
     ($($arg:tt)+) => { log!("", $($arg)+) };
 }
+#[clippy::format_args]
 macro_rules! warn {
     (target: $target:expr, $($arg:tt)*) => { log!(target: $target, "", $($arg)*) };
     ($($arg:tt)*) => { log!("", $($arg)*) };
 }
+#[clippy::format_args]
 macro_rules! info {
     (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
     ($($arg:tt)+) => { log!("", $($arg)+) };
 }
+#[clippy::format_args]
 macro_rules! debug {
     (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
     ($($arg:tt)+) => { log!("", $($arg)+) };
 }
+#[clippy::format_args]
 macro_rules! trace {
     (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
     ($($arg:tt)+) => { log!("", $($arg)+) };
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/options/as_args.rs firefox-140.10.2/third_party/rust/bindgen/options/as_args.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/options/as_args.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/bindgen/options/as_args.rs	Mon May 11 04:49:32 2026
@@ -1,6 +1,6 @@
 use std::path::PathBuf;
 
-use crate::RegexSet;
+use crate::regex_set::RegexSet;
 
 /// Trait used to turn [`crate::BindgenOptions`] fields into CLI args.
 pub(super) trait AsArgs {
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/options/cli.rs firefox-140.10.2/third_party/rust/bindgen/options/cli.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/options/cli.rs	Thu Jan  1 01:00:00 1970
+++ firefox-140.10.2/third_party/rust/bindgen/options/cli.rs	Mon May 11 04:49:32 2026
@@ -0,0 +1,1151 @@
+#![allow(unused_qualifications)] // Clap somehow generates a lot of these
+
+use crate::{
+    builder,
+    callbacks::{
+        AttributeInfo, DeriveInfo, ItemInfo, ParseCallbacks, TypeKind,
+    },
+    features::{RustEdition, EARLIEST_STABLE_RUST},
+    regex_set::RegexSet,
+    Abi, AliasVariation, Builder, CodegenConfig, EnumVariation,
+    FieldVisibilityKind, Formatter, MacroTypeVariation, NonCopyUnionStyle,
+    RustTarget,
+};
+use clap::{
+    error::{Error, ErrorKind},
+    CommandFactory, Parser,
+};
+use proc_macro2::TokenStream;
+use std::io;
+use std::path::{Path, PathBuf};
+use std::str::FromStr;
+use std::{fs::File, process::exit};
+
+fn rust_target_help() -> String {
+    format!(
+        "Version of the Rust compiler to target. Any Rust version after {EARLIEST_STABLE_RUST} is supported. Defaults to {}.",
+        RustTarget::default()
+    )
+}
+
+fn rust_edition_help() -> String {
+    format!("Rust edition to target. Defaults to the latest edition supported by the chosen Rust target. Possible values: ({}). ", RustEdition::ALL.map(|e| e.to_string()).join("|"))
+}
+
+fn parse_codegen_config(
+    what_to_generate: &str,
+) -> Result<CodegenConfig, Error> {
+    let mut config = CodegenConfig::empty();
+    for what in what_to_generate.split(',') {
+        match what {
+            "functions" => config.insert(CodegenConfig::FUNCTIONS),
+            "types" => config.insert(CodegenConfig::TYPES),
+            "vars" => config.insert(CodegenConfig::VARS),
+            "methods" => config.insert(CodegenConfig::METHODS),
+            "constructors" => config.insert(CodegenConfig::CONSTRUCTORS),
+            "destructors" => config.insert(CodegenConfig::DESTRUCTORS),
+            otherwise => {
+                return Err(Error::raw(
+                    ErrorKind::InvalidValue,
+                    format!("Unknown codegen item kind: {otherwise}"),
+                ));
+            }
+        }
+    }
+
+    Ok(config)
+}
+
+fn parse_rustfmt_config_path(path_str: &str) -> Result<PathBuf, Error> {
+    let path = Path::new(path_str);
+
+    if !path.is_absolute() {
+        return Err(Error::raw(
+            ErrorKind::InvalidValue,
+            "--rustfmt-configuration-file needs to be an absolute path!",
+        ));
+    }
+
+    if path.to_str().is_none() {
+        return Err(Error::raw(
+            ErrorKind::InvalidUtf8,
+            "--rustfmt-configuration-file contains non-valid UTF8 characters.",
+        ));
+    }
+
+    Ok(path.to_path_buf())
+}
+
+fn parse_abi_override(abi_override: &str) -> Result<(Abi, String), Error> {
+    let (regex, abi_str) = abi_override
+        .rsplit_once('=')
+        .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?;
+
+    let abi = abi_str
+        .parse()
+        .map_err(|err| Error::raw(ErrorKind::InvalidValue, err))?;
+
+    Ok((abi, regex.to_owned()))
+}
+
+fn parse_custom_derive(
+    custom_derive: &str,
+) -> Result<(Vec<String>, String), Error> {
+    let (regex, derives) = custom_derive
+        .rsplit_once('=')
+        .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?;
+
+    let derives = derives.split(',').map(|s| s.to_owned()).collect();
+
+    Ok((derives, regex.to_owned()))
+}
+
+fn parse_custom_attribute(
+    custom_attribute: &str,
+) -> Result<(Vec<String>, String), Error> {
+    let mut brace_level = 0;
+    let (regex, attributes) = custom_attribute
+        .rsplit_once(|c| {
+            match c {
+                ']' => brace_level += 1,
+                '[' => brace_level -= 1,
+                _ => {}
+            }
+            c == '=' && brace_level == 0
+        })
+        .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?;
+
+    let mut brace_level = 0;
+    let attributes = attributes
+        .split(|c| {
+            match c {
+                ']' => brace_level += 1,
+                '[' => brace_level -= 1,
+                _ => {}
+            }
+            c == ',' && brace_level == 0
+        })
+        .map(|s| s.to_owned())
+        .collect::<Vec<_>>();
+
+    for attribute in &attributes {
+        if let Err(err) = TokenStream::from_str(attribute) {
+            return Err(Error::raw(ErrorKind::InvalidValue, err));
+        }
+    }
+
+    Ok((attributes, regex.to_owned()))
+}
+
+#[derive(Parser, Debug)]
+#[clap(
+    about = "Generates Rust bindings from C/C++ headers.",
+    override_usage = "bindgen <FLAGS> <OPTIONS> <HEADER> -- <CLANG_ARGS>...",
+    trailing_var_arg = true
+)]
+#[allow(clippy::doc_markdown)]
+struct BindgenCommand {
+    /// C or C++ header file.
+    header: Option<String>,
+    /// Path to write depfile to.
+    #[arg(long)]
+    depfile: Option<String>,
+    /// The default STYLE of code used to generate enums.
+    #[arg(long, value_name = "STYLE")]
+    default_enum_style: Option<EnumVariation>,
+    /// Mark any enum whose name matches REGEX as a set of bitfield flags.
+    #[arg(long, value_name = "REGEX")]
+    bitfield_enum: Vec<String>,
+    /// Mark any enum whose name matches REGEX as a newtype.
+    #[arg(long, value_name = "REGEX")]
+    newtype_enum: Vec<String>,
+    /// Mark any enum whose name matches REGEX as a global newtype.
+    #[arg(long, value_name = "REGEX")]
+    newtype_global_enum: Vec<String>,
+    /// Mark any enum whose name matches REGEX as a Rust enum.
+    #[arg(long, value_name = "REGEX")]
+    rustified_enum: Vec<String>,
+    /// Mark any enum whose name matches REGEX as a non-exhaustive Rust enum.
+    #[arg(long, value_name = "REGEX")]
+    rustified_non_exhaustive_enum: Vec<String>,
+    /// Mark any enum whose name matches REGEX as a series of constants.
+    #[arg(long, value_name = "REGEX")]
+    constified_enum: Vec<String>,
+    /// Mark any enum whose name matches REGEX as a module of constants.
+    #[arg(long, value_name = "REGEX")]
+    constified_enum_module: Vec<String>,
+    /// The default signed/unsigned TYPE for C macro constants.
+    #[arg(long, value_name = "TYPE")]
+    default_macro_constant_type: Option<MacroTypeVariation>,
+    /// The default STYLE of code used to generate typedefs.
+    #[arg(long, value_name = "STYLE")]
+    default_alias_style: Option<AliasVariation>,
+    /// Mark any typedef alias whose name matches REGEX to use normal type aliasing.
+    #[arg(long, value_name = "REGEX")]
+    normal_alias: Vec<String>,
+    /// Mark any typedef alias whose name matches REGEX to have a new type generated for it.
+    #[arg(long, value_name = "REGEX")]
+    new_type_alias: Vec<String>,
+    /// Mark any typedef alias whose name matches REGEX to have a new type with Deref and DerefMut to the inner type.
+    #[arg(long, value_name = "REGEX")]
+    new_type_alias_deref: Vec<String>,
+    /// The default STYLE of code used to generate unions with non-Copy members. Note that ManuallyDrop was first stabilized in Rust 1.20.0.
+    #[arg(long, value_name = "STYLE")]
+    default_non_copy_union_style: Option<NonCopyUnionStyle>,
+    /// Mark any union whose name matches REGEX and who has a non-Copy member to use a bindgen-generated wrapper for fields.
+    #[arg(long, value_name = "REGEX")]
+    bindgen_wrapper_union: Vec<String>,
+    /// Mark any union whose name matches REGEX and who has a non-Copy member to use ManuallyDrop (stabilized in Rust 1.20.0) for fields.
+    #[arg(long, value_name = "REGEX")]
+    manually_drop_union: Vec<String>,
+    /// Mark TYPE as hidden.
+    #[arg(long, value_name = "TYPE")]
+    blocklist_type: Vec<String>,
+    /// Mark FUNCTION as hidden.
+    #[arg(long, value_name = "FUNCTION")]
+    blocklist_function: Vec<String>,
+    /// Mark ITEM as hidden.
+    #[arg(long, value_name = "ITEM")]
+    blocklist_item: Vec<String>,
+    /// Mark FILE as hidden.
+    #[arg(long, value_name = "FILE")]
+    blocklist_file: Vec<String>,
+    /// Mark VAR as hidden.
+    #[arg(long, value_name = "VAR")]
+    blocklist_var: Vec<String>,
+    /// Avoid generating layout tests for any type.
+    #[arg(long)]
+    no_layout_tests: bool,
+    /// Avoid deriving Copy on any type.
+    #[arg(long)]
+    no_derive_copy: bool,
+    /// Avoid deriving Debug on any type.
+    #[arg(long)]
+    no_derive_debug: bool,
+    /// Avoid deriving Default on any type.
+    #[arg(long, hide = true)]
+    no_derive_default: bool,
+    /// Create a Debug implementation if it cannot be derived automatically.
+    #[arg(long)]
+    impl_debug: bool,
+    /// Create a PartialEq implementation if it cannot be derived automatically.
+    #[arg(long)]
+    impl_partialeq: bool,
+    /// Derive Default on any type.
+    #[arg(long)]
+    with_derive_default: bool,
+    /// Derive Hash on any type.
+    #[arg(long)]
+    with_derive_hash: bool,
+    /// Derive PartialEq on any type.
+    #[arg(long)]
+    with_derive_partialeq: bool,
+    /// Derive PartialOrd on any type.
+    #[arg(long)]
+    with_derive_partialord: bool,
+    /// Derive Eq on any type.
+    #[arg(long)]
+    with_derive_eq: bool,
+    /// Derive Ord on any type.
+    #[arg(long)]
+    with_derive_ord: bool,
+    /// Avoid including doc comments in the output, see: <https://github.com/rust-lang/rust-bindgen/issues/426>
+    #[arg(long)]
+    no_doc_comments: bool,
+    /// Disable allowlisting types recursively. This will cause bindgen to emit Rust code that won't compile! See the `bindgen::Builder::allowlist_recursively` method's documentation for details.
+    #[arg(long)]
+    no_recursive_allowlist: bool,
+    /// Use extern crate instead of use for objc.
+    #[arg(long)]
+    objc_extern_crate: bool,
+    /// Generate block signatures instead of void pointers.
+    #[arg(long)]
+    generate_block: bool,
+    /// Generate string constants as `&CStr` instead of `&[u8]`.
+    #[arg(long)]
+    generate_cstr: bool,
+    /// Use extern crate instead of use for block.
+    #[arg(long)]
+    block_extern_crate: bool,
+    /// Do not trust the libclang-provided mangling
+    #[arg(long)]
+    distrust_clang_mangling: bool,
+    /// Output bindings for builtin definitions, e.g. __builtin_va_list.
+    #[arg(long)]
+    builtins: bool,
+    /// Use the given PREFIX before raw types instead of ::std::os::raw.
+    #[arg(long, value_name = "PREFIX")]
+    ctypes_prefix: Option<String>,
+    /// Use the given PREFIX for anonymous fields.
+    #[arg(long, value_name = "PREFIX")]
+    anon_fields_prefix: Option<String>,
+    /// Time the different bindgen phases and print to stderr
+    #[arg(long)]
+    time_phases: bool,
+    /// Output the Clang AST for debugging purposes.
+    #[arg(long)]
+    emit_clang_ast: bool,
+    /// Output our internal IR for debugging purposes.
+    #[arg(long)]
+    emit_ir: bool,
+    /// Dump a graphviz dot file to PATH.
+    #[arg(long, value_name = "PATH")]
+    emit_ir_graphviz: Option<String>,
+    /// Enable support for C++ namespaces.
+    #[arg(long)]
+    enable_cxx_namespaces: bool,
+    /// Disable namespacing via mangling, causing bindgen to generate names like `Baz` instead of `foo_bar_Baz` for an input name `foo::bar::Baz`.
+    #[arg(long)]
+    disable_name_namespacing: bool,
+    /// Disable nested struct naming, causing bindgen to generate names like `bar` instead of `foo_bar` for a nested definition `struct foo { struct bar { } b; };`.
+    #[arg(long)]
+    disable_nested_struct_naming: bool,
+    /// Disable support for native Rust unions.
+    #[arg(long)]
+    disable_untagged_union: bool,
+    /// Suppress insertion of bindgen's version identifier into generated bindings.
+    #[arg(long)]
+    disable_header_comment: bool,
+    /// Do not generate bindings for functions or methods. This is useful when you only care about struct layouts.
+    #[arg(long)]
+    ignore_functions: bool,
+    /// Generate only given items, split by commas. Valid values are `functions`,`types`, `vars`, `methods`, `constructors` and `destructors`.
+    #[arg(long, value_parser = parse_codegen_config)]
+    generate: Option<CodegenConfig>,
+    /// Do not generate bindings for methods.
+    #[arg(long)]
+    ignore_methods: bool,
+    /// Do not automatically convert floats to f32/f64.
+    #[arg(long)]
+    no_convert_floats: bool,
+    /// Do not prepend the enum name to constant or newtype variants.
+    #[arg(long)]
+    no_prepend_enum_name: bool,
+    /// Do not try to detect default include paths
+    #[arg(long)]
+    no_include_path_detection: bool,
+    /// Try to fit macro constants into types smaller than u32/i32
+    #[arg(long)]
+    fit_macro_constant_types: bool,
+    /// Mark TYPE as opaque.
+    #[arg(long, value_name = "TYPE")]
+    opaque_type: Vec<String>,
+    ///  Write Rust bindings to OUTPUT.
+    #[arg(long, short, value_name = "OUTPUT")]
+    output: Option<String>,
+    /// Add a raw line of Rust code at the beginning of output.
+    #[arg(long)]
+    raw_line: Vec<String>,
+    /// Add a RAW_LINE of Rust code to a given module with name MODULE_NAME.
+    #[arg(long, number_of_values = 2, value_names = ["MODULE_NAME", "RAW_LINE"])]
+    module_raw_line: Vec<String>,
+    #[arg(long, help = rust_target_help())]
+    rust_target: Option<RustTarget>,
+    #[arg(long, value_name = "EDITION", help = rust_edition_help())]
+    rust_edition: Option<RustEdition>,
+    /// Use types from Rust core instead of std.
+    #[arg(long)]
+    use_core: bool,
+    /// Conservatively generate inline namespaces to avoid name conflicts.
+    #[arg(long)]
+    conservative_inline_namespaces: bool,
+    /// Allowlist all the free-standing functions matching REGEX. Other non-allowlisted functions will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_function: Vec<String>,
+    /// Generate inline functions.
+    #[arg(long)]
+    generate_inline_functions: bool,
+    /// Only generate types matching REGEX. Other non-allowlisted types will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_type: Vec<String>,
+    /// Allowlist all the free-standing variables matching REGEX. Other non-allowlisted variables will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_var: Vec<String>,
+    /// Allowlist all contents of PATH.
+    #[arg(long, value_name = "PATH")]
+    allowlist_file: Vec<String>,
+    /// Allowlist all items matching REGEX. Other non-allowlisted items will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_item: Vec<String>,
+    /// Print verbose error messages.
+    #[arg(long)]
+    verbose: bool,
+    /// Preprocess and dump the input header files to disk. Useful when debugging bindgen, using C-Reduce, or when filing issues. The resulting file will be named something like `__bindgen.i` or `__bindgen.ii`.
+    #[arg(long)]
+    dump_preprocessed_input: bool,
+    /// Do not record matching items in the regex sets. This disables reporting of unused items.
+    #[arg(long)]
+    no_record_matches: bool,
+    /// Do not bind size_t as usize (useful on platforms where those types are incompatible).
+    #[arg(long = "no-size_t-is-usize")]
+    no_size_t_is_usize: bool,
+    /// Do not format the generated bindings with rustfmt. This option is deprecated, please use
+    /// `--formatter=none` instead.
+    #[arg(long)]
+    no_rustfmt_bindings: bool,
+    /// Which FORMATTER should be used for the bindings
+    #[arg(
+        long,
+        value_name = "FORMATTER",
+        conflicts_with = "no_rustfmt_bindings"
+    )]
+    formatter: Option<Formatter>,
+    /// The absolute PATH to the rustfmt configuration file. The configuration file will be used for formatting the bindings. This parameter sets `formatter` to `rustfmt`.
+    #[arg(long, value_name = "PATH", conflicts_with = "no_rustfmt_bindings", value_parser=parse_rustfmt_config_path)]
+    rustfmt_configuration_file: Option<PathBuf>,
+    /// Avoid deriving PartialEq for types matching REGEX.
+    #[arg(long, value_name = "REGEX")]
+    no_partialeq: Vec<String>,
+    /// Avoid deriving Copy and Clone for types matching REGEX.
+    #[arg(long, value_name = "REGEX")]
+    no_copy: Vec<String>,
+    /// Avoid deriving Debug for types matching REGEX.
+    #[arg(long, value_name = "REGEX")]
+    no_debug: Vec<String>,
+    /// Avoid deriving/implementing Default for types matching REGEX.
+    #[arg(long, value_name = "REGEX")]
+    no_default: Vec<String>,
+    /// Avoid deriving Hash for types matching REGEX.
+    #[arg(long, value_name = "REGEX")]
+    no_hash: Vec<String>,
+    /// Add `#[must_use]` annotation to types matching REGEX.
+    #[arg(long, value_name = "REGEX")]
+    must_use_type: Vec<String>,
+    /// Enables detecting unexposed attributes in functions (slow). Used to generate `#[must_use]` annotations.
+    #[arg(long)]
+    enable_function_attribute_detection: bool,
+    /// Use `*const [T; size]` instead of `*const T` for C arrays
+    #[arg(long)]
+    use_array_pointers_in_arguments: bool,
+    /// The NAME to be used in a #[link(wasm_import_module = ...)] statement
+    #[arg(long, value_name = "NAME")]
+    wasm_import_module_name: Option<String>,
+    /// Use dynamic loading mode with the given library NAME.
+    #[arg(long, value_name = "NAME")]
+    dynamic_loading: Option<String>,
+    /// Require successful linkage to all functions in the library.
+    #[arg(long)]
+    dynamic_link_require_all: bool,
+    /// Prefix the name of exported symbols.
+    #[arg(long)]
+    prefix_link_name: Option<String>,
+    /// Makes generated bindings `pub` only for items if the items are publicly accessible in C++.
+    #[arg(long)]
+    respect_cxx_access_specs: bool,
+    /// Always translate enum integer types to native Rust integer types.
+    #[arg(long)]
+    translate_enum_integer_types: bool,
+    /// Generate types with C style naming.
+    #[arg(long)]
+    c_naming: bool,
+    /// Always output explicit padding fields.
+    #[arg(long)]
+    explicit_padding: bool,
+    /// Always be specific about the 'receiver' of a virtual function.
+    #[arg(long)]
+    use_specific_virtual_function_receiver: bool,
+    /// Use distinct char16_t
+    #[arg(long)]
+    use_distinct_char16_t: bool,
+    /// Output C++ overloaded operators
+    #[arg(long)]
+    represent_cxx_operators: bool,
+    /// Enables generation of vtable functions.
+    #[arg(long)]
+    vtable_generation: bool,
+    /// Enables sorting of code generation in a predefined manner.
+    #[arg(long)]
+    sort_semantically: bool,
+    /// Deduplicates extern blocks.
+    #[arg(long)]
+    merge_extern_blocks: bool,
+    /// Overrides the ABI of functions matching REGEX. The OVERRIDE value must be of the shape REGEX=ABI where ABI can be one of C, stdcall, efiapi, fastcall, thiscall, aapcs, win64 or C-unwind<.>
+    #[arg(long, value_name = "OVERRIDE", value_parser = parse_abi_override)]
+    override_abi: Vec<(Abi, String)>,
+    /// Wrap unsafe operations in unsafe blocks.
+    #[arg(long)]
+    wrap_unsafe_ops: bool,
+    /// Enable fallback for clang macro parsing.
+    #[arg(long)]
+    clang_macro_fallback: bool,
+    /// Set path for temporary files generated by fallback for clang macro parsing.
+    #[arg(long)]
+    clang_macro_fallback_build_dir: Option<PathBuf>,
+    /// Use DSTs to represent structures with flexible array members.
+    #[arg(long)]
+    flexarray_dst: bool,
+    /// Derive custom traits on any kind of type. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom: Vec<(Vec<String>, String)>,
+    /// Derive custom traits on a `struct`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom_struct: Vec<(Vec<String>, String)>,
+    /// Derive custom traits on an `enum`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom_enum: Vec<(Vec<String>, String)>,
+    /// Derive custom traits on a `union`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a comma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom_union: Vec<(Vec<String>, String)>,
+    /// Add custom attributes on any kind of type. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)]
+    with_attribute_custom: Vec<(Vec<String>, String)>,
+    /// Add custom attributes on a `struct`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)]
+    with_attribute_custom_struct: Vec<(Vec<String>, String)>,
+    /// Add custom attributes on an `enum`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)]
+    with_attribute_custom_enum: Vec<(Vec<String>, String)>,
+    /// Add custom attributes on a `union`. The CUSTOM value must be of the shape REGEX=ATTRIBUTE where ATTRIBUTE is a comma-separated list of attributes.
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_attribute)]
+    with_attribute_custom_union: Vec<(Vec<String>, String)>,
+    /// Generate wrappers for `static` and `static inline` functions.
+    #[arg(long)]
+    wrap_static_fns: bool,
+    /// Sets the PATH for the source file that must be created due to the presence of `static` and
+    /// `static inline` functions.
+    #[arg(long, value_name = "PATH")]
+    wrap_static_fns_path: Option<PathBuf>,
+    /// Sets the SUFFIX added to the extern wrapper functions generated for `static` and `static
+    /// inline` functions.
+    #[arg(long, value_name = "SUFFIX")]
+    wrap_static_fns_suffix: Option<String>,
+    /// Set the default VISIBILITY of fields, including bitfields and accessor methods for
+    /// bitfields. This flag is ignored if the `--respect-cxx-access-specs` flag is used.
+    #[arg(long, value_name = "VISIBILITY")]
+    default_visibility: Option<FieldVisibilityKind>,
+    /// Whether to generate C++ functions marked with "=delete" even though they
+    /// can't be called.
+    #[arg(long)]
+    generate_deleted_functions: bool,
+    /// Whether to generate C++ "pure virtual" functions even though they can't
+    /// be called.
+    #[arg(long)]
+    generate_pure_virtual_functions: bool,
+    /// Whether to generate C++ private functions even though they can't
+    /// be called.
+    #[arg(long)]
+    generate_private_functions: bool,
+    /// Whether to emit diagnostics or not.
+    #[cfg(feature = "experimental")]
+    #[arg(long, requires = "experimental")]
+    emit_diagnostics: bool,
+    /// Generates completions for the specified SHELL, sends them to `stdout` and exits.
+    #[arg(long, value_name = "SHELL")]
+    generate_shell_completions: Option<clap_complete::Shell>,
+    /// Enables experimental features.
+    #[arg(long)]
+    experimental: bool,
+    /// Prints the version, and exits
+    #[arg(short = 'V', long)]
+    version: bool,
+    /// Arguments to be passed straight through to clang.
+    clang_args: Vec<String>,
+}
+
+/// Construct a new [`Builder`](./struct.Builder.html) from command line flags.
+pub fn builder_from_flags<I>(
+    args: I,
+) -> Result<(Builder, Box<dyn io::Write>, bool), io::Error>
+where
+    I: Iterator<Item = String>,
+{
+    let command = BindgenCommand::parse_from(args);
+
+    let BindgenCommand {
+        header,
+        depfile,
+        default_enum_style,
+        bitfield_enum,
+        newtype_enum,
+        newtype_global_enum,
+        rustified_enum,
+        rustified_non_exhaustive_enum,
+        constified_enum,
+        constified_enum_module,
+        default_macro_constant_type,
+        default_alias_style,
+        normal_alias,
+        new_type_alias,
+        new_type_alias_deref,
+        default_non_copy_union_style,
+        bindgen_wrapper_union,
+        manually_drop_union,
+        blocklist_type,
+        blocklist_function,
+        blocklist_item,
+        blocklist_file,
+        blocklist_var,
+        no_layout_tests,
+        no_derive_copy,
+        no_derive_debug,
+        no_derive_default,
+        impl_debug,
+        impl_partialeq,
+        with_derive_default,
+        with_derive_hash,
+        with_derive_partialeq,
+        with_derive_partialord,
+        with_derive_eq,
+        with_derive_ord,
+        no_doc_comments,
+        no_recursive_allowlist,
+        objc_extern_crate,
+        generate_block,
+        generate_cstr,
+        block_extern_crate,
+        distrust_clang_mangling,
+        builtins,
+        ctypes_prefix,
+        anon_fields_prefix,
+        time_phases,
+        emit_clang_ast,
+        emit_ir,
+        emit_ir_graphviz,
+        enable_cxx_namespaces,
+        disable_name_namespacing,
+        disable_nested_struct_naming,
+        disable_untagged_union,
+        disable_header_comment,
+        ignore_functions,
+        generate,
+        ignore_methods,
+        no_convert_floats,
+        no_prepend_enum_name,
+        no_include_path_detection,
+        fit_macro_constant_types,
+        opaque_type,
+        output,
+        raw_line,
+        module_raw_line,
+        rust_target,
+        rust_edition,
+        use_core,
+        conservative_inline_namespaces,
+        allowlist_function,
+        generate_inline_functions,
+        allowlist_type,
+        allowlist_var,
+        allowlist_file,
+        allowlist_item,
+        verbose,
+        dump_preprocessed_input,
+        no_record_matches,
+        no_size_t_is_usize,
+        no_rustfmt_bindings,
+        formatter,
+        rustfmt_configuration_file,
+        no_partialeq,
+        no_copy,
+        no_debug,
+        no_default,
+        no_hash,
+        must_use_type,
+        enable_function_attribute_detection,
+        use_array_pointers_in_arguments,
+        wasm_import_module_name,
+        dynamic_loading,
+        dynamic_link_require_all,
+        prefix_link_name,
+        respect_cxx_access_specs,
+        translate_enum_integer_types,
+        c_naming,
+        explicit_padding,
+        use_specific_virtual_function_receiver,
+        use_distinct_char16_t,
+        represent_cxx_operators,
+        vtable_generation,
+        sort_semantically,
+        merge_extern_blocks,
+        override_abi,
+        wrap_unsafe_ops,
+        clang_macro_fallback,
+        clang_macro_fallback_build_dir,
+        flexarray_dst,
+        with_derive_custom,
+        with_derive_custom_struct,
+        with_derive_custom_enum,
+        with_derive_custom_union,
+        with_attribute_custom,
+        with_attribute_custom_struct,
+        with_attribute_custom_enum,
+        with_attribute_custom_union,
+        wrap_static_fns,
+        wrap_static_fns_path,
+        wrap_static_fns_suffix,
+        default_visibility,
+        generate_deleted_functions,
+        generate_pure_virtual_functions,
+        generate_private_functions,
+        #[cfg(feature = "experimental")]
+        emit_diagnostics,
+        generate_shell_completions,
+        experimental: _,
+        version,
+        clang_args,
+    } = command;
+
+    if let Some(shell) = generate_shell_completions {
+        clap_complete::generate(
+            shell,
+            &mut BindgenCommand::command(),
+            "bindgen",
+            &mut io::stdout(),
+        );
+
+        exit(0)
+    }
+
+    if version {
+        println!(
+            "bindgen {}",
+            option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")
+        );
+        if verbose {
+            println!("Clang: {}", crate::clang_version().full);
+        }
+
+        exit(0)
+    }
+
+    if header.is_none() {
+        return Err(io::Error::new(io::ErrorKind::Other, "Header not found"));
+    }
+
+    let mut builder = builder();
+
+    #[derive(Debug)]
+    struct PrefixLinkNameCallback {
+        prefix: String,
+    }
+
+    impl ParseCallbacks for PrefixLinkNameCallback {
+        fn generated_link_name_override(
+            &self,
+            item_info: ItemInfo<'_>,
+        ) -> Option<String> {
+            let mut prefix = self.prefix.clone();
+            prefix.push_str(item_info.name);
+            Some(prefix)
+        }
+    }
+
+    #[derive(Debug)]
+    struct CustomDeriveCallback {
+        derives: Vec<String>,
+        kind: Option<TypeKind>,
+        regex_set: RegexSet,
+    }
+
+    impl ParseCallbacks for CustomDeriveCallback {
+        fn cli_args(&self) -> Vec<String> {
+            let mut args = vec![];
+
+            let flag = match &self.kind {
+                None => "--with-derive-custom",
+                Some(TypeKind::Struct) => "--with-derive-custom-struct",
+                Some(TypeKind::Enum) => "--with-derive-custom-enum",
+                Some(TypeKind::Union) => "--with-derive-custom-union",
+            };
+
+            let derives = self.derives.join(",");
+
+            for item in self.regex_set.get_items() {
+                args.extend_from_slice(&[
+                    flag.to_owned(),
+                    format!("{item}={derives}"),
+                ]);
+            }
+
+            args
+        }
+
+        fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec<String> {
+            if self.kind.map_or(true, |kind| kind == info.kind) &&
+                self.regex_set.matches(info.name)
+            {
+                return self.derives.clone();
+            }
+            vec![]
+        }
+    }
+
+    #[derive(Debug)]
+    struct CustomAttributeCallback {
+        attributes: Vec<String>,
+        kind: Option<TypeKind>,
+        regex_set: RegexSet,
+    }
+
+    impl ParseCallbacks for CustomAttributeCallback {
+        fn cli_args(&self) -> Vec<String> {
+            let mut args = vec![];
+
+            let flag = match &self.kind {
+                None => "--with-attribute-custom",
+                Some(TypeKind::Struct) => "--with-attribute-custom-struct",
+                Some(TypeKind::Enum) => "--with-attribute-custom-enum",
+                Some(TypeKind::Union) => "--with-attribute-custom-union",
+            };
+
+            let attributes = self.attributes.join(",");
+
+            for item in self.regex_set.get_items() {
+                args.extend_from_slice(&[
+                    flag.to_owned(),
+                    format!("{item}={attributes}"),
+                ]);
+            }
+
+            args
+        }
+
+        fn add_attributes(&self, info: &AttributeInfo<'_>) -> Vec<String> {
+            if self.kind.map_or(true, |kind| kind == info.kind) &&
+                self.regex_set.matches(info.name)
+            {
+                return self.attributes.clone();
+            }
+            vec![]
+        }
+    }
+
+    /// Macro used to apply CLI arguments to a builder.
+    ///
+    /// This is done by passing an identifier for each argument and a function to be applied over
+    /// the builder. For example:
+    /// ```rust,ignore
+    /// fn apply_arg(builder: Builder, arg_value: Value) -> Builder {
+    ///     todo!()
+    /// }
+    ///
+    /// apply_args!(
+    ///     builder {
+    ///         arg => apply_arg,
+    ///     }
+    /// );
+    /// ```
+    ///
+    /// If the identifier of the argument is the same as an already existing builder method then
+    /// you can omit the second part:
+    /// ```rust,ignore
+    /// apply_args!(
+    ///     builder {
+    ///         arg
+    ///     }
+    /// );
+    /// ```
+    /// Which expands to the same code as:
+    /// ```rust,ignore
+    /// apply_args!(
+    ///     builder {
+    ///         arg => Builder::arg,
+    ///     }
+    /// );
+    /// ```
+    macro_rules! apply_args {
+        ($builder:ident {}) => { $builder };
+        ($builder:ident {$arg:ident => $function:expr, $($token:tt)*}) => {
+            {
+                $builder = CliArg::apply($arg, $builder, $function);
+                apply_args!($builder {$($token)*})
+            }
+        };
+        ($builder:ident {$arg:ident, $($token:tt)*}) => {
+            {
+                $builder = CliArg::apply($arg, $builder, Builder::$arg);
+                apply_args!($builder {$($token)*})
+            }
+        }
+    }
+
+    builder = apply_args!(
+        builder {
+            header,
+            rust_target,
+            rust_edition,
+            default_enum_style,
+            bitfield_enum,
+            newtype_enum,
+            newtype_global_enum,
+            rustified_enum,
+            rustified_non_exhaustive_enum,
+            constified_enum,
+            constified_enum_module,
+            default_macro_constant_type,
+            default_alias_style,
+            normal_alias => Builder::type_alias,
+            new_type_alias,
+            new_type_alias_deref,
+            default_non_copy_union_style,
+            bindgen_wrapper_union,
+            manually_drop_union,
+            blocklist_type,
+            blocklist_function,
+            blocklist_item,
+            blocklist_file,
+            blocklist_var,
+            builtins => |b, _| b.emit_builtins(),
+            no_layout_tests => |b, _| b.layout_tests(false),
+            no_derive_copy => |b, _| b.derive_copy(false),
+            no_derive_debug => |b, _| b.derive_debug(false),
+            impl_debug,
+            impl_partialeq,
+            with_derive_default => Builder::derive_default,
+            with_derive_hash => Builder::derive_hash,
+            with_derive_partialeq => Builder::derive_partialeq,
+            with_derive_partialord => Builder::derive_partialord,
+            with_derive_eq => Builder::derive_eq,
+            with_derive_ord => Builder::derive_ord,
+            no_derive_default => |b, _| b.derive_default(false),
+            no_prepend_enum_name => |b, _| b.prepend_enum_name(false),
+            no_include_path_detection => |b, _| b.detect_include_paths(false),
+            fit_macro_constant_types => Builder::fit_macro_constants,
+            time_phases,
+            use_array_pointers_in_arguments => Builder::array_pointers_in_arguments,
+            wasm_import_module_name,
+            ctypes_prefix,
+            anon_fields_prefix,
+            generate => Builder::with_codegen_config,
+            emit_clang_ast => |b, _| b.emit_clang_ast(),
+            emit_ir => |b, _| b.emit_ir(),
+            emit_ir_graphviz,
+            enable_cxx_namespaces => |b, _| b.enable_cxx_namespaces(),
+            enable_function_attribute_detection => |b, _| b.enable_function_attribute_detection(),
+            disable_name_namespacing => |b, _| b.disable_name_namespacing(),
+            disable_nested_struct_naming => |b, _| b.disable_nested_struct_naming(),
+            disable_untagged_union => |b, _| b.disable_untagged_union(),
+            disable_header_comment => |b, _| b.disable_header_comment(),
+            ignore_functions => |b, _| b.ignore_functions(),
+            ignore_methods => |b, _| b.ignore_methods(),
+            no_convert_floats => |b, _| b.no_convert_floats(),
+            no_doc_comments => |b, _| b.generate_comments(false),
+            no_recursive_allowlist => |b, _| b.allowlist_recursively(false),
+            objc_extern_crate,
+            generate_block,
+            generate_cstr,
+            block_extern_crate,
+            opaque_type,
+            raw_line,
+            use_core => |b, _| b.use_core(),
+            distrust_clang_mangling => |b, _| b.trust_clang_mangling(false),
+            conservative_inline_namespaces => |b, _| b.conservative_inline_namespaces(),
+            generate_inline_functions,
+            allowlist_function,
+            allowlist_type,
+            allowlist_var,
+            allowlist_file,
+            allowlist_item,
+            clang_args => Builder::clang_arg,
+            no_record_matches => |b, _| b.record_matches(false),
+            no_size_t_is_usize => |b, _| b.size_t_is_usize(false),
+            no_rustfmt_bindings => |b, _| b.formatter(Formatter::None),
+            formatter,
+            no_partialeq,
+            no_copy,
+            no_debug,
+            no_default,
+            no_hash,
+            must_use_type,
+            dynamic_loading => Builder::dynamic_library_name,
+            dynamic_link_require_all,
+            prefix_link_name => |b, prefix| b.parse_callbacks(Box::new(PrefixLinkNameCallback { prefix })),
+            respect_cxx_access_specs,
+            translate_enum_integer_types,
+            c_naming,
+            explicit_padding,
+            use_specific_virtual_function_receiver,
+            use_distinct_char16_t,
+            represent_cxx_operators,
+            vtable_generation,
+            sort_semantically,
+            merge_extern_blocks,
+            override_abi => |b, (abi, regex)| b.override_abi(abi, regex),
+            wrap_unsafe_ops,
+            clang_macro_fallback => |b, _| b.clang_macro_fallback(),
+            clang_macro_fallback_build_dir,
+            flexarray_dst,
+            wrap_static_fns,
+            wrap_static_fns_path,
+            wrap_static_fns_suffix,
+            default_visibility,
+            generate_deleted_functions,
+            generate_pure_virtual_functions,
+            generate_private_functions,
+        }
+    );
+
+    let mut values = module_raw_line.into_iter();
+    while let Some(module) = values.next() {
+        let line = values.next().unwrap();
+        builder = builder.module_raw_line(module, line);
+    }
+
+    let output = if let Some(path) = &output {
+        let file = File::create(path)?;
+        if let Some(depfile) = depfile {
+            builder = builder.depfile(path, depfile);
+        }
+        Box::new(io::BufWriter::new(file)) as Box<dyn io::Write>
+    } else {
+        if let Some(depfile) = depfile {
+            builder = builder.depfile("-", depfile);
+        }
+        Box::new(io::BufWriter::new(io::stdout())) as Box<dyn io::Write>
+    };
+
+    if dump_preprocessed_input {
+        builder.dump_preprocessed_input()?;
+    }
+
+    if let Some(path) = rustfmt_configuration_file {
+        builder = builder.rustfmt_configuration_file(Some(path));
+    }
+
+    for (custom_derives, kind, _name) in [
+        (with_derive_custom, None, "--with-derive-custom"),
+        (
+            with_derive_custom_struct,
+            Some(TypeKind::Struct),
+            "--with-derive-custom-struct",
+        ),
+        (
+            with_derive_custom_enum,
+            Some(TypeKind::Enum),
+            "--with-derive-custom-enum",
+        ),
+        (
+            with_derive_custom_union,
+            Some(TypeKind::Union),
+            "--with-derive-custom-union",
+        ),
+    ] {
+        #[cfg(feature = "experimental")]
+        let name = emit_diagnostics.then_some(_name);
+
+        for (derives, regex) in custom_derives {
+            let mut regex_set = RegexSet::default();
+            regex_set.insert(regex);
+
+            #[cfg(feature = "experimental")]
+            regex_set.build_with_diagnostics(false, name);
+            #[cfg(not(feature = "experimental"))]
+            regex_set.build(false);
+
+            builder = builder.parse_callbacks(Box::new(CustomDeriveCallback {
+                derives,
+                kind,
+                regex_set,
+            }));
+        }
+    }
+
+    for (custom_attributes, kind, _name) in [
+        (with_attribute_custom, None, "--with-attribute-custom"),
+        (
+            with_attribute_custom_struct,
+            Some(TypeKind::Struct),
+            "--with-attribute-custom-struct",
+        ),
+        (
+            with_attribute_custom_enum,
+            Some(TypeKind::Enum),
+            "--with-attribute-custom-enum",
+        ),
+        (
+            with_attribute_custom_union,
+            Some(TypeKind::Union),
+            "--with-attribute-custom-union",
+        ),
+    ] {
+        #[cfg(feature = "experimental")]
+        let name = emit_diagnostics.then_some(_name);
+
+        for (attributes, regex) in custom_attributes {
+            let mut regex_set = RegexSet::default();
+            regex_set.insert(regex);
+
+            #[cfg(feature = "experimental")]
+            regex_set.build_with_diagnostics(false, name);
+            #[cfg(not(feature = "experimental"))]
+            regex_set.build(false);
+
+            builder =
+                builder.parse_callbacks(Box::new(CustomAttributeCallback {
+                    attributes,
+                    kind,
+                    regex_set,
+                }));
+        }
+    }
+
+    #[cfg(feature = "experimental")]
+    if emit_diagnostics {
+        builder = builder.emit_diagnostics();
+    }
+
+    Ok((builder, output, verbose))
+}
+
+/// Trait for CLI arguments that can be applied to a [`Builder`].
+trait CliArg {
+    /// The value of this argument.
+    type Value;
+
+    /// Apply the current argument to the passed [`Builder`].
+    fn apply(
+        self,
+        builder: Builder,
+        f: impl Fn(Builder, Self::Value) -> Builder,
+    ) -> Builder;
+}
+
+/// Boolean arguments are applied when they evaluate to `true`.
+impl CliArg for bool {
+    type Value = bool;
+
+    fn apply(
+        self,
+        mut builder: Builder,
+        f: impl Fn(Builder, Self::Value) -> Builder,
+    ) -> Builder {
+        if self {
+            builder = f(builder, self);
+        }
+
+        builder
+    }
+}
+
+/// Optional arguments are applied when they are `Some`.
+impl<T> CliArg for Option<T> {
+    type Value = T;
+
+    fn apply(
+        self,
+        mut builder: Builder,
+        f: impl Fn(Builder, Self::Value) -> Builder,
+    ) -> Builder {
+        if let Some(value) = self {
+            builder = f(builder, value);
+        }
+
+        builder
+    }
+}
+
+/// Multiple valued arguments are applied once for each value.
+impl<T> CliArg for Vec<T> {
+    type Value = T;
+
+    fn apply(
+        self,
+        mut builder: Builder,
+        f: impl Fn(Builder, Self::Value) -> Builder,
+    ) -> Builder {
+        for value in self {
+            builder = f(builder, value);
+        }
+
+        builder
+    }
+}
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/options/mod.rs firefox-140.10.2/third_party/rust/bindgen/options/mod.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/options/mod.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/options/mod.rs	Mon May 11 04:49:32 2026
@@ -4,13 +4,15 @@
 #[macro_use]
 mod helpers;
 mod as_args;
+#[cfg(feature = "__cli")]
+pub(crate) mod cli;
 
 use crate::callbacks::ParseCallbacks;
 use crate::codegen::{
     AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle,
 };
 use crate::deps::DepfileSpec;
-use crate::features::{RustFeatures, RustTarget};
+use crate::features::{RustEdition, RustFeatures, RustTarget};
 use crate::regex_set::RegexSet;
 use crate::Abi;
 use crate::Builder;
@@ -21,9 +23,7 @@
 use crate::DEFAULT_ANON_FIELDS_PREFIX;
 
 use std::env;
-#[cfg(feature = "experimental")]
-use std::path::Path;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::rc::Rc;
 
 use as_args::AsArgs;
@@ -37,20 +37,20 @@
 /// a block of code with the following items:
 ///
 /// - `default`: The default value for the field. If this item is omitted, `Default::default()` is
-/// used instead, meaning that the type of the field must implement `Default`.
+///   used instead, meaning that the type of the field must implement `Default`.
 /// - `methods`: A block of code containing methods for the `Builder` type. These methods should be
-/// related to the field being declared.
+///   related to the field being declared.
 /// - `as_args`: This item declares how the field should be converted into a valid CLI argument for
-/// `bindgen` and is used in the [`Builder::command_line_flags`] method which is used to do a
-/// roundtrip test of the CLI args in the `bindgen-test` crate. This item can take one of the
-/// following:
+///   `bindgen` and is used in the [`Builder::command_line_flags`] method which is used to do a
+///   roundtrip test of the CLI args in the `bindgen-test` crate. This item can take one of the
+///   following:
 ///   - A string literal with the flag if the type of the field implements the [`AsArgs`] trait.
 ///   - A closure with the signature `|field, args: &mut Vec<String>| -> ()` that pushes arguments
-///   into the `args` buffer based on the value of the field. This is used if the field does not
-///   implement `AsArgs` or if the implementation of the trait is not logically correct for the
-///   option and a custom behavior must be taken into account.
+///     into the `args` buffer based on the value of the field. This is used if the field does not
+///     implement `AsArgs` or if the implementation of the trait is not logically correct for the
+///     option and a custom behavior must be taken into account.
 ///   - The `ignore` literal, which does not emit any CLI arguments for this field. This is useful
-///   if the field cannot be used from the `bindgen` CLI.
+///     if the field cannot be used from the `bindgen` CLI.
 ///
 /// As an example, this would be the declaration of a `bool` field called `be_fun` whose default
 /// value is `false` (the `Default` value for `bool`):
@@ -153,6 +153,64 @@
 }
 
 options! {
+    /// Whether to specify the type of a virtual function receiver
+    use_specific_virtual_function_receiver: bool {
+        methods: {
+            /// Normally, virtual functions have void* as their 'this' type.
+            /// If this flag is enabled, override that behavior to indicate a
+            /// pointer of the specific type.
+            /// Disabled by default.
+            pub fn use_specific_virtual_function_receiver(mut self, doit: bool) -> Builder {
+                self.options.use_specific_virtual_function_receiver = doit;
+                self
+            }
+        },
+        as_args: "--use-specific-virtual-function-receiver",
+    },
+
+    /// Whether we should distinguish between C++'s `char16_t` and `u16`.
+    /// The C++ type `char16_t` is its own special type; it's not a typedef
+    /// of some other integer (this differs from C).
+    /// As standard, bindgen represents C++ `char16_t` as `u16`.
+    /// Rust does not have a `std::os::raw::c_char16_t` type, and thus
+    /// we can't use a built-in Rust type in the generated bindings (and
+    /// nor would it be appropriate as it's a C++-specific type.)
+    /// But for some uses of bindgen, especially when downstream
+    /// post-processing occurs, it's important to distinguish `char16_t`
+    /// from normal `uint16_t`. When this option is enabled, bindgen
+    /// generates a fake type called `bindgen_cchar16_t`. Downstream
+    /// code post-processors should arrange to replace this with a
+    /// real type.
+    use_distinct_char16_t: bool {
+        methods: {
+            /// If this is true, denote `char16_t` as a separate type from `u16`.
+            /// Disabled by default.
+            pub fn use_distinct_char16_t(mut self, doit: bool) -> Builder {
+                self.options.use_distinct_char16_t = doit;
+                self
+            }
+        },
+        as_args: "--use-distinct-char16-t",
+    },
+    /// Whether we should output C++ overloaded operators. By itself,
+    /// this option is not sufficient to produce valid output, because
+    /// such operators will have names that are not acceptable Rust
+    /// names (for example `operator=`). If you use this option, you'll also
+    /// have to rename the resulting functions - for example by using
+    /// [`ParseCallbacks::generated_name_override`].
+    represent_cxx_operators: bool {
+        methods: {
+            /// If this is true, output existence of C++ overloaded operators.
+            /// At present, only operator= is noted.
+            /// Disabled by default.
+            pub fn represent_cxx_operators(mut self, doit: bool) -> Builder {
+                self.options.represent_cxx_operators = doit;
+                self
+            }
+        },
+        as_args: "--represent-cxx-operators",
+    },
+
     /// Types that have been blocklisted and should not appear anywhere in the generated code.
     blocklisted_types: RegexSet {
         methods: {
@@ -489,7 +547,7 @@
                 }
             }
         },
-        as_args: "--rustified-non-exhaustive-enums",
+        as_args: "--rustified-non-exhaustive-enum",
     },
     /// `enum`s marked as modules of constants.
     constified_enum_modules: RegexSet {
@@ -508,7 +566,7 @@
     constified_enums: RegexSet {
         methods: {
             regex_option! {
-                /// Mark the given `enum` as a set o integer constants.
+                /// Mark the given `enum` as a set of integer constants.
                 ///
                 /// This is similar to the [`Builder::constified_enum_module`] style, but the
                 /// constants are generated in the current module instead of in a new module.
@@ -1143,7 +1201,7 @@
         },
         as_args: |module_lines, args| {
             for (module, lines) in module_lines {
-                for line in lines.iter() {
+                for line in lines {
                     args.push("--module-raw-line".to_owned());
                     args.push(module.clone().into());
                     args.push(line.clone().into());
@@ -1179,6 +1237,35 @@
                 self.options.input_headers.push(header.into().into_boxed_str());
                 self
             }
+
+            /// Add input C/C++ header(s) to generate bindings for.
+            ///
+            /// This can be used to generate bindings for a single header:
+            ///
+            /// ```ignore
+            /// let bindings = bindgen::Builder::default()
+            ///     .headers(["input.h"])
+            ///     .generate()
+            ///     .unwrap();
+            /// ```
+            ///
+            /// Or for multiple headers:
+            ///
+            /// ```ignore
+            /// let bindings = bindgen::Builder::default()
+            ///     .headers(["first.h", "second.h", "third.h"])
+            ///     .generate()
+            ///     .unwrap();
+            /// ```
+            pub fn headers<I: IntoIterator>(mut self, headers: I) -> Builder
+            where
+                I::Item: Into<String>,
+            {
+                self.options
+                    .input_headers
+                    .extend(headers.into_iter().map(Into::into).map(Into::into));
+                self
+            }
         },
         // This field is handled specially inside the macro.
         as_args: ignore,
@@ -1205,6 +1292,11 @@
         // This field is handled specially inside the macro.
         as_args: ignore,
     },
+    /// The set of arguments to be passed straight through to Clang for the macro fallback code.
+    fallback_clang_args: Vec<Box<str>> {
+        methods: {},
+        as_args: ignore,
+    },
     /// Tuples of unsaved file contents of the form (name, contents).
     input_header_contents: Vec<(Box<str>, Box<str>)> {
         methods: {
@@ -1234,6 +1326,9 @@
     parse_callbacks: Vec<Rc<dyn ParseCallbacks>> {
         methods: {
             /// Add a new [`ParseCallbacks`] instance to configure types in different situations.
+            ///
+            /// This can also be used with [`CargoCallbacks`](struct@crate::CargoCallbacks) to emit
+            /// `cargo:rerun-if-changed=...` for all `#include`d header files.
             pub fn parse_callbacks(mut self, cb: Box<dyn ParseCallbacks>) -> Self {
                 self.options.parse_callbacks.push(Rc::from(cb));
                 self
@@ -1389,10 +1484,8 @@
             /// Note that they will usually not work. However you can use `-fkeep-inline-functions`
             /// or `-fno-inline-functions` if you are responsible of compiling the library to make
             /// them callable.
-            #[cfg_attr(
-                feature = "experimental",
-                doc = "\nCheck the [`Builder::wrap_static_fns`] method for an alternative."
-            )]
+            ///
+            /// Check the [`Builder::wrap_static_fns`] method for an alternative.
             pub fn generate_inline_functions(mut self, doit: bool) -> Self {
                 self.options.generate_inline_functions = doit;
                 self
@@ -1579,9 +1672,26 @@
             args.push(rust_target.to_string());
         },
     },
+    /// The Rust edition to use for code generation.
+    rust_edition: Option<RustEdition> {
+        methods: {
+            /// Specify the Rust target edition.
+            ///
+            /// The default edition is the latest edition supported by the chosen Rust target.
+            pub fn rust_edition(mut self, rust_edition: RustEdition) -> Self {
+                self.options.rust_edition = Some(rust_edition);
+                self
+            }
+        }
+        as_args: |edition, args| {
+            if let Some(edition) =  edition {
+                args.push("--rust-edition".to_owned());
+                args.push(edition.to_string());
+            }
+        },
+    },
     /// Features to be enabled. They are derived from `rust_target`.
     rust_features: RustFeatures {
-        default: RustTarget::default().into(),
         methods: {},
         // This field cannot be set from the CLI,
         as_args: ignore,
@@ -1814,7 +1924,7 @@
         },
         as_args: "--dynamic-loading",
     },
-    /// Whether to equire successful linkage for all routines in a shared library.
+    /// Whether to require successful linkage for all routines in a shared library.
     dynamic_link_require_all: bool {
         methods: {
             /// Set whether to require successful linkage for all routines in a shared library.
@@ -1879,7 +1989,7 @@
         },
         as_args: "--c-naming",
     },
-    /// Wether to always emit explicit padding fields.
+    /// Whether to always emit explicit padding fields.
     force_explicit_padding: bool {
         methods: {
             /// Set whether to always emit explicit padding fields.
@@ -1951,7 +2061,20 @@
         },
         as_args: "--wrap-unsafe-ops",
     },
-    /// Patterns for functions whose ABI should be overriden.
+    /// Use DSTs to represent structures with flexible array members.
+    flexarray_dst: bool {
+        methods: {
+            /// Use DSTs to represent structures with flexible array members.
+            ///
+            /// This option is disabled by default.
+            pub fn flexarray_dst(mut self, doit: bool) -> Self {
+                self.options.flexarray_dst = doit;
+                self
+            }
+        },
+        as_args: "--flexarray-dst",
+    },
+    /// Patterns for functions whose ABI should be overridden.
     abi_overrides: HashMap<Abi, RegexSet> {
         methods: {
             regex_option! {
@@ -1970,7 +2093,7 @@
             for (abi, set) in overrides {
                 for item in set.get_items() {
                     args.push("--override-abi".to_owned());
-                    args.push(format!("{}={}", item, abi));
+                    args.push(format!("{item}={abi}"));
                 }
             }
         },
@@ -1978,8 +2101,7 @@
     /// Whether to generate wrappers for `static` functions.
     wrap_static_fns: bool {
         methods: {
-            #[cfg(feature = "experimental")]
-            /// Set whether to generate wrappers for `static`` functions.
+            /// Set whether to generate wrappers for `static` functions.
             ///
             /// Passing `true` to this method will generate a C source file with non-`static`
             /// functions that call the `static` functions found in the input headers and can be
@@ -1997,7 +2119,6 @@
     /// The suffix to be added to the function wrappers for `static` functions.
     wrap_static_fns_suffix: Option<String> {
         methods: {
-            #[cfg(feature = "experimental")]
             /// Set the suffix added to the wrappers for `static` functions.
             ///
             /// This option only comes into effect if `true` is passed to the
@@ -2014,7 +2135,6 @@
     /// The path of the file where the wrappers for `static` functions will be emitted.
     wrap_static_fns_path: Option<PathBuf> {
         methods: {
-            #[cfg(feature = "experimental")]
             /// Set the path for the source code file that would be created if any wrapper
             /// functions must be generated due to the presence of `static` functions.
             ///
@@ -2075,5 +2195,92 @@
             }
         },
         as_args: "--emit-diagnostics",
+    },
+    /// Whether to use Clang evaluation on temporary files as a fallback for macros that fail to
+    /// parse.
+    clang_macro_fallback: bool {
+        methods: {
+            /// Use Clang as a fallback for macros that fail to parse using `CExpr`.
+            ///
+            /// This uses a workaround to evaluate each macro in a temporary file. Because this
+            /// results in slower compilation, this option is opt-in.
+            pub fn clang_macro_fallback(mut self) -> Self {
+                self.options.clang_macro_fallback = true;
+                self
+            }
+        },
+        as_args: "--clang-macro-fallback",
     }
+    /// Path to use for temporary files created by clang macro fallback code like precompiled
+    /// headers.
+    clang_macro_fallback_build_dir: Option<PathBuf> {
+        methods: {
+            /// Set a path to a directory to which `.c` and `.h.pch` files should be written for the
+            /// purpose of using clang to evaluate macros that can't be easily parsed.
+            ///
+            /// The default location for `.h.pch` files is the directory that the corresponding
+            /// `.h` file is located in. The default for the temporary `.c` file used for clang
+            /// parsing is the current working directory. Both of these defaults are overridden
+            /// by this option.
+            pub fn clang_macro_fallback_build_dir<P: AsRef<Path>>(mut self, path: P) -> Self {
+                self.options.clang_macro_fallback_build_dir = Some(path.as_ref().to_owned());
+                self
+            }
+        },
+        as_args: "--clang-macro-fallback-build-dir",
+    }
+    /// Whether to always report C++ "deleted" functions.
+    generate_deleted_functions: bool {
+        methods: {
+            /// Set whether to generate C++ functions even marked "=deleted"
+            ///
+            /// Although not useful to call these functions, downstream code
+            /// generators may need to know whether they've been deleted in
+            /// order to determine the relocatability of a C++ type
+            /// (specifically by virtue of which constructors exist.)
+            pub fn generate_deleted_functions(mut self, doit: bool) -> Self {
+                self.options.generate_deleted_functions = doit;
+                self
+            }
+
+        },
+        as_args: "--generate-deleted-functions",
+    },
+    /// Whether to always report C++ "pure virtual" functions.
+    generate_pure_virtual_functions: bool {
+        methods: {
+            /// Set whether to generate C++ functions that are pure virtual.
+            ///
+            /// These functions can't be called, so the only reason
+            /// to generate them is if downstream postprocessors
+            /// need to know of their existence. This is necessary,
+            /// for instance, to determine whether a type itself is
+            /// pure virtual and thus can't be allocated.
+            /// Downstream code generators may choose to make code to
+            /// allow types to be allocated but need to avoid doing so
+            /// if the type contains pure virtual functions.
+            pub fn generate_pure_virtual_functions(mut self, doit: bool) -> Self {
+                self.options.generate_pure_virtual_functions = doit;
+                self
+            }
+
+        },
+        as_args: "--generate-pure-virtual-functions",
+    },
+    /// Whether to always report C++ "private" functions.
+    generate_private_functions: bool {
+        methods: {
+            /// Set whether to generate C++ functions that are private.
+            ///
+            /// These functions can't be called, so the only reason
+            /// to generate them is if downstream postprocessors
+            /// need to know of their existence.
+            pub fn generate_private_functions(mut self, doit: bool) -> Self {
+                self.options.generate_private_functions = doit;
+                self
+            }
+
+        },
+        as_args: "--generate-private-functions",
+    },
 }
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/regex_set.rs firefox-140.10.2/third_party/rust/bindgen/regex_set.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/regex_set.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/regex_set.rs	Mon May 11 04:49:32 2026
@@ -6,7 +6,7 @@
 
 /// A dynamic set of regular expressions.
 #[derive(Clone, Debug, Default)]
-pub struct RegexSet {
+pub(crate) struct RegexSet {
     items: Vec<Box<str>>,
     /// Whether any of the items in the set was ever matched. The length of this
     /// vector is exactly the length of `items`.
@@ -17,18 +17,13 @@
 }
 
 impl RegexSet {
-    /// Create a new RegexSet
-    pub fn new() -> RegexSet {
-        RegexSet::default()
-    }
-
     /// Is this set empty?
-    pub fn is_empty(&self) -> bool {
+    pub(crate) fn is_empty(&self) -> bool {
         self.items.is_empty()
     }
 
     /// Insert a new regex into this set.
-    pub fn insert<S>(&mut self, string: S)
+    pub(crate) fn insert<S>(&mut self, string: S)
     where
         S: AsRef<str>,
     {
@@ -38,13 +33,13 @@
     }
 
     /// Returns slice of String from its field 'items'
-    pub fn get_items(&self) -> &[Box<str>] {
+    pub(crate) fn get_items(&self) -> &[Box<str>] {
         &self.items
     }
 
     /// Returns an iterator over regexes in the set which didn't match any
     /// strings yet.
-    pub fn unmatched_items(&self) -> impl Iterator<Item = &str> {
+    pub(crate) fn unmatched_items(&self) -> impl Iterator<Item = &str> {
         self.items.iter().enumerate().filter_map(move |(i, item)| {
             if !self.record_matches || self.matched[i].get() {
                 return None;
@@ -54,28 +49,29 @@
         })
     }
 
-    /// Construct a RegexSet from the set of entries we've accumulated.
+    /// Construct a `RegexSet` from the set of entries we've accumulated.
     ///
     /// Must be called before calling `matches()`, or it will always return
     /// false.
     #[inline]
-    pub fn build(&mut self, record_matches: bool) {
-        self.build_inner(record_matches, None)
+    #[allow(unused)]
+    pub(crate) fn build(&mut self, record_matches: bool) {
+        self.build_inner(record_matches, None);
     }
 
     #[cfg(all(feature = "__cli", feature = "experimental"))]
-    /// Construct a RegexSet from the set of entries we've accumulated and emit diagnostics if the
+    /// Construct a `RegexSet` from the set of entries we've accumulated and emit diagnostics if the
     /// name of the regex set is passed to it.
     ///
     /// Must be called before calling `matches()`, or it will always return
     /// false.
     #[inline]
-    pub fn build_with_diagnostics(
+    pub(crate) fn build_with_diagnostics(
         &mut self,
         record_matches: bool,
         name: Option<&'static str>,
     ) {
-        self.build_inner(record_matches, name)
+        self.build_inner(record_matches, name);
     }
 
     #[cfg(all(not(feature = "__cli"), feature = "experimental"))]
@@ -90,7 +86,7 @@
         record_matches: bool,
         name: Option<&'static str>,
     ) {
-        self.build_inner(record_matches, name)
+        self.build_inner(record_matches, name);
     }
 
     fn build_inner(
@@ -98,12 +94,12 @@
         record_matches: bool,
         _name: Option<&'static str>,
     ) {
-        let items = self.items.iter().map(|item| format!("^({})$", item));
+        let items = self.items.iter().map(|item| format!("^({item})$"));
         self.record_matches = record_matches;
         self.set = match RxSet::new(items) {
             Ok(x) => Some(x),
             Err(e) => {
-                warn!("Invalid regex in {:?}: {:?}", self.items, e);
+                warn!("Invalid regex in {:?}: {e:?}", self.items);
                 #[cfg(feature = "experimental")]
                 if let Some(name) = _name {
                     invalid_regex_warning(self, e, name);
@@ -114,14 +110,13 @@
     }
 
     /// Does the given `string` match any of the regexes in this set?
-    pub fn matches<S>(&self, string: S) -> bool
+    pub(crate) fn matches<S>(&self, string: S) -> bool
     where
         S: AsRef<str>,
     {
         let s = string.as_ref();
-        let set = match self.set {
-            Some(ref set) => set,
-            None => return false,
+        let Some(ref set) = self.set else {
+            return false;
         };
 
         if !self.record_matches {
@@ -132,7 +127,7 @@
         if !matches.matched_any() {
             return false;
         }
-        for i in matches.iter() {
+        for i in &matches {
             self.matched[i].set(true);
         }
 
@@ -180,20 +175,20 @@
 
                 diagnostic.with_title(
                     "Error while parsing a regular expression.",
-                    Level::Warn,
+                    Level::Warning,
                 );
             } else {
-                diagnostic.with_title(string, Level::Warn);
+                diagnostic.with_title(string, Level::Warning);
             }
         }
         err => {
             let err = err.to_string();
-            diagnostic.with_title(err, Level::Warn);
+            diagnostic.with_title(err, Level::Warning);
         }
     }
 
     diagnostic.add_annotation(
-        format!("This regular expression was passed via `{}`.", name),
+        format!("This regular expression was passed via `{name}`."),
         Level::Note,
     );
 
diff -rNu firefox-140.10.2.orig/third_party/rust/bindgen/time.rs firefox-140.10.2/third_party/rust/bindgen/time.rs
--- firefox-140.10.2.orig/third_party/rust/bindgen/time.rs	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/bindgen/time.rs	Mon May 11 04:49:32 2026
@@ -29,23 +29,23 @@
 
     /// Returns the time elapsed since the timer's creation
     pub fn elapsed(&self) -> Duration {
-        Instant::now() - self.start
+        self.start.elapsed()
     }
 
     fn print_elapsed(&mut self) {
         if self.output {
             let elapsed = self.elapsed();
             let time = (elapsed.as_secs() as f64) * 1e3 +
-                (elapsed.subsec_nanos() as f64) / 1e6;
+                f64::from(elapsed.subsec_nanos()) / 1e6;
             let stderr = io::stderr();
             // Arbitrary output format, subject to change.
-            writeln!(stderr.lock(), "  time: {:>9.3} ms.\t{}", time, self.name)
+            writeln!(stderr.lock(), "  time: {time:>9.3} ms.\t{}", self.name)
                 .expect("timer write should not fail");
         }
     }
 }
 
-impl<'a> Drop for Timer<'a> {
+impl Drop for Timer<'_> {
     fn drop(&mut self) {
         self.print_elapsed();
     }
diff -rNu firefox-140.10.2.orig/third_party/rust/lazycell/.cargo-checksum.json firefox-140.10.2/third_party/rust/lazycell/.cargo-checksum.json
--- firefox-140.10.2.orig/third_party/rust/lazycell/.cargo-checksum.json	Wed May  6 16:54:52 2026
+++ firefox-140.10.2/third_party/rust/lazycell/.cargo-checksum.json	Thu Jan  1 01:00:00 1970
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"54036052985525a153f9e6c9dda6a143b7494a477908fb28f5705f92dd387059","Cargo.toml":"79f5da117603f75361b9a7309f102a9ab70b66d5c1c269a30f66fdea58ccc657","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"03f6ccb4e6040abccf12b31551bbbd1800a5069a17950bbd6db850d85744800f","README.md":"26e4440387d4fc898f377eb5394f3432f8625ed8aa46e02ffb61aac8b2032967","src/lib.rs":"3fcef569bd4feb760925e34aef0e66739a0827cbc1b26ae033f57e322c3a2515","src/serde_impl.rs":"4903fb722748e91bdc4b481c7f3309e79e962f75c9717e7e13edcccd0242a52d"},"package":"830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"}
\ No newline at end of file
diff -rNu firefox-140.10.2.orig/third_party/rust/lazycell/CHANGELOG.md firefox-140.10.2/third_party/rust/lazycell/CHANGELOG.md
--- firefox-140.10.2.orig/third_party/rust/lazycell/CHANGELOG.md	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/lazycell/CHANGELOG.md	Thu Jan  1 01:00:00 1970
@@ -1,197 +0,0 @@
-<a name="v1.3.0"></a>
-## v1.3.0 (2020-08-12)
-
-
-#### Bug Fixes
-
-*   Add custom `impl Default` to support non-Default-able `<T>` types ([b49f4eab](https://github.com/indiv0/lazycell/commit/b49f4eabec49c0a5146ef01017c2506a3c357180))
-* **lazycell:**  Fix unsound aliasing in `LazyCell::fill` ([e789ac1a](https://github.com/indiv0/lazycell/commit/e789ac1a99010ad79c2d09c761fec6d67053647d), closes [#98](https://github.com/indiv0/lazycell/issues/98))
-
-#### Features
-
-*   Implement serde support ([e728a0b6](https://github.com/indiv0/lazycell/commit/e728a0b680e607b793a81b5af7bf7f1d2c0eb5e5))
-
-#### Documentation
-
-*   fix typo ([5f5ba9d5](https://github.com/indiv0/lazycell/commit/5f5ba9d5ac3364f8376c0c872c2e5094974385ba))
-
-
-
-<a name="v1.2.1"></a>
-## v1.2.1 (2018-12-03)
-
-
-#### Features
-
-*   Implement Clone for LazyCell and AtomicLazyCell ([30fe4a8f](https://github.com/indiv0/lazycell/commit/30fe4a8f568059b3c78ed149a810962a676cb2b2))
-
-
-
-<a name="v1.2.0"></a>
-## v1.2.0 (2018-09-19)
-
-
-#### Features
-
-*   add `LazyCell::replace` for infallible access ([a63ffb90](https://github.com/indiv0/lazycell/commit/a63ffb9040a5e0683a9bbf9d3d5ef589f2ca8b7c))
-
-
-
-<a name="v1.1.0"></a>
-## v1.1.0 (2018-09-10)
-
-
-#### Documentation
-
-*   add note regarding LazyCell::borrow_mut ([9d634d1f](https://github.com/indiv0/lazycell/commit/9d634d1fd9a21b7aa075d407bedf9fe77ba8b79f))
-*   describe mutability more consistently ([b8078029](https://github.com/indiv0/lazycell/commit/b80780294611e92efddcdd33a701b3049ab5c5eb), closes [#78](https://github.com/indiv0/lazycell/issues/78))
-
-#### Improvements
-
-*   add NONE constant for an empty AtomicLazyCell ([31aff0da](https://github.com/indiv0/lazycell/commit/31aff0dacf824841c5f38ef4acf0aa71ec4c36eb), closes [#87](https://github.com/indiv0/lazycell/issues/87))
-*   add `LazyCell::borrow_mut_with` and `LazyCell::try_borrow_mut_with` ([fdc6d268](https://github.com/indiv0/lazycell/commit/fdc6d268f0e9a6668768302f45fe2bb4aa9a7c34), closes [#79](https://github.com/indiv0/lazycell/issues/79), [#80](https://github.com/indiv0/lazycell/issues/80))
-
-
-
-<a name="v1.0.0"></a>
-## v1.0.0 (2018-06-06)
-
-
-#### Features
-
-*   Add #![no_std] ([e59f6b55](https://github.com/indiv0/lazycell/commit/e59f6b5531e310d3df26b0eb40b1431937f38096))
-
-
-
-<a name="0.6.0"></a>
-## 0.6.0 (2017-11-25)
-
-
-#### Bug Fixes
-
-*   fix soundness hole in borrow_with ([d1f46bef](https://github.com/indiv0/lazycell/commit/d1f46bef9d1397570aa9c3e87e18e0d16e6d1585))
-
-#### Features
-
-*   add Default derives ([71bc5088](https://github.com/indiv0/lazycell/commit/71bc50880cd8e20002038197c9b890f5b76ad096))
-*   add LazyCell::try_borrow_with ([bffa4028](https://github.com/indiv0/lazycell/commit/bffa402896670b5c78a9ec050d82a58ee98de6fb))
-*   add LazyCell::borrow_mut method ([fd419dea](https://github.com/indiv0/lazycell/commit/fd419dea965ff1ad3853f26f37e8d107c6ca096c))
-
-#### Breaking Changes
-
-*   add `T: Send` for `AtomicLazyCell` `Sync` impl ([668bb2fa](https://github.com/indiv0/lazycell/commit/668bb2fa974fd6707c4c7edad292c76a9017d74d), closes [#67](https://github.com/indiv0/lazycell/issues/67))
-
-#### Improvements
-
-*   add `T: Send` for `AtomicLazyCell` `Sync` impl ([668bb2fa](https://github.com/indiv0/lazycell/commit/668bb2fa974fd6707c4c7edad292c76a9017d74d), closes [#67](https://github.com/indiv0/lazycell/issues/67))
-
-
-
-<a name="v0.5.1"></a>
-## v0.5.1 (2017-03-24)
-
-
-#### Documentation
-
-*   fix missing backticks ([44bafaaf](https://github.com/indiv0/lazycell/commit/44bafaaf93a91641261f58ee38adadcd4af6458e))
-
-#### Improvements
-
-*   derive `Debug` impls ([9da0a5a2](https://github.com/indiv0/lazycell/commit/9da0a5a2ffac1fef03ef02851c2c89d26d67d225))
-
-#### Features
-
-*   Add get method for Copy types ([dc8f8209](https://github.com/indiv0/lazycell/commit/dc8f8209888b6eba6d18717eba6a22614629b997))
-
-
-
-<a name="v0.5.0"></a>
-## v0.5.0 (2016-12-08)
-
-
-#### Features
-
-*   add borrow_with to LazyCell ([a15efa35](https://github.com/indiv0/lazycell/commit/a15efa359ea5a31a66ba57fc5b25f90c87b4b0dd))
-
-
-
-<a name="v0.4.0"></a>
-##  (2016-08-17)
-
-
-#### Breaking Changes
-
-* **LazyCell:**  return Err(value) on full cell ([68f3415d](https://github.com/indiv0/lazycell/commit/68f3415dd5d6a66ba047a133b7028ebe4f1c5070), breaks [#](https://github.com/indiv0/lazycell/issues/))
-
-#### Improvements
-
-* **LazyCell:**  return Err(value) on full cell ([68f3415d](https://github.com/indiv0/lazycell/commit/68f3415dd5d6a66ba047a133b7028ebe4f1c5070), breaks [#](https://github.com/indiv0/lazycell/issues/))
-
-
-
-<a name="v0.3.0"></a>
-##  (2016-08-16)
-
-
-#### Features
-
-*   add AtomicLazyCell which is thread-safe ([85afbd36](https://github.com/indiv0/lazycell/commit/85afbd36d8a148e14cc53654b39ddb523980124d))
-
-#### Improvements
-
-*   Use UnsafeCell instead of RefCell ([3347a8e9](https://github.com/indiv0/lazycell/commit/3347a8e97d2215a47e25c1e2fc953e8052ad8eb6))
-
-
-
-<a name="v0.2.1"></a>
-##  (2016-04-18)
-
-
-#### Documentation
-
-*   put types in between backticks ([607cf939](https://github.com/indiv0/lazycell/commit/607cf939b05e35001ba3070ec7a0b17b064e7be1))
-
-
-
-<a name="v0.2.0"></a>
-## v0.2.0 (2016-03-28)
-
-
-#### Features
-
-* **lazycell:**
-  *  add tests for `LazyCell` struct ([38f1313d](https://github.com/indiv0/lazycell/commit/38f1313d98542ca8c98b424edfa9ba9c3975f99e), closes [#30](https://github.com/indiv0/lazycell/issues/30))
-  *  remove unnecessary `Default` impl ([68c16d2d](https://github.com/indiv0/lazycell/commit/68c16d2df4e9d13d5298162c06edf918246fd758))
-
-#### Documentation
-
-* **CHANGELOG:**  removed unnecessary sections ([1cc0555d](https://github.com/indiv0/lazycell/commit/1cc0555d875898a01b0832ff967aed6b40e720eb))
-* **README:**  add link to documentation ([c8dc33f0](https://github.com/indiv0/lazycell/commit/c8dc33f01f2c0dc187f59ee53a2b73081053012b), closes [#13](https://github.com/indiv0/lazycell/issues/13))
-
-
-
-<a name="v0.1.0"></a>
-## v0.1.0 (2016-03-16)
-
-
-#### Features
-
-* **lib.rs:**  implement Default trait for LazyCell ([150a6304](https://github.com/indiv0/LazyCell/commit/150a6304a230ee1de8424e49c447ec1b2d6578ce))
-
-
-
-<a name="v0.0.1"></a>
-## v0.0.1 (2016-03-16)
-
-
-#### Bug Fixes
-
-* **Cargo.toml:**  loosen restrictions on Clippy version ([84dd8f96](https://github.com/indiv0/LazyCell/commit/84dd8f960000294f9dad47d776a41b98ed812981))
-
-#### Features
-
-*   add initial implementation ([4b39764a](https://github.com/indiv0/LazyCell/commit/4b39764a575bcb701dbd8047b966f72720fd18a4))
-*   add initial commit ([a80407a9](https://github.com/indiv0/LazyCell/commit/a80407a907ef7c9401f120104663172f6965521a))
-
-
-
diff -rNu firefox-140.10.2.orig/third_party/rust/lazycell/Cargo.toml firefox-140.10.2/third_party/rust/lazycell/Cargo.toml
--- firefox-140.10.2.orig/third_party/rust/lazycell/Cargo.toml	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/lazycell/Cargo.toml	Thu Jan  1 01:00:00 1970
@@ -1,34 +0,0 @@
-# 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 believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "lazycell"
-version = "1.3.0"
-authors = ["Alex Crichton <alex@alexcrichton.com>", "Nikita Pekin <contact@nikitapek.in>"]
-include = ["CHANGELOG.md", "Cargo.toml", "LICENSE-MIT", "LICENSE-APACHE", "README.md", "src/**/*.rs"]
-description = "A library providing a lazily filled Cell struct"
-documentation = "http://indiv0.github.io/lazycell/lazycell/"
-readme = "README.md"
-keywords = ["lazycell", "lazy", "cell", "library"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/indiv0/lazycell"
-[dependencies.clippy]
-version = "0.0"
-optional = true
-
-[dependencies.serde]
-version = "^1"
-optional = true
-
-[features]
-nightly = []
-nightly-testing = ["clippy", "nightly"]
diff -rNu firefox-140.10.2.orig/third_party/rust/lazycell/LICENSE-APACHE firefox-140.10.2/third_party/rust/lazycell/LICENSE-APACHE
--- firefox-140.10.2.orig/third_party/rust/lazycell/LICENSE-APACHE	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/lazycell/LICENSE-APACHE	Thu Jan  1 01:00:00 1970
@@ -1,201 +0,0 @@
-                              Apache License
-                        Version 2.0, January 2004
-                     http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-   "License" shall mean the terms and conditions for use, reproduction,
-   and distribution as defined by Sections 1 through 9 of this document.
-
-   "Licensor" shall mean the copyright owner or entity authorized by
-   the copyright owner that is granting the License.
-
-   "Legal Entity" shall mean the union of the acting entity and all
-   other entities that control, are controlled by, or are under common
-   control with that entity. For the purposes of this definition,
-   "control" means (i) the power, direct or indirect, to cause the
-   direction or management of such entity, whether by contract or
-   otherwise, or (ii) ownership of fifty percent (50%) or more of the
-   outstanding shares, or (iii) beneficial ownership of such entity.
-
-   "You" (or "Your") shall mean an individual or Legal Entity
-   exercising permissions granted by this License.
-
-   "Source" form shall mean the preferred form for making modifications,
-   including but not limited to software source code, documentation
-   source, and configuration files.
-
-   "Object" form shall mean any form resulting from mechanical
-   transformation or translation of a Source form, including but
-   not limited to compiled object code, generated documentation,
-   and conversions to other media types.
-
-   "Work" shall mean the work of authorship, whether in Source or
-   Object form, made available under the License, as indicated by a
-   copyright notice that is included in or attached to the work
-   (an example is provided in the Appendix below).
-
-   "Derivative Works" shall mean any work, whether in Source or Object
-   form, that is based on (or derived from) the Work and for which the
-   editorial revisions, annotations, elaborations, or other modifications
-   represent, as a whole, an original work of authorship. For the purposes
-   of this License, Derivative Works shall not include works that remain
-   separable from, or merely link (or bind by name) to the interfaces of,
-   the Work and Derivative Works thereof.
-
-   "Contribution" shall mean any work of authorship, including
-   the original version of the Work and any modifications or additions
-   to that Work or Derivative Works thereof, that is intentionally
-   submitted to Licensor for inclusion in the Work by the copyright owner
-   or by an individual or Legal Entity authorized to submit on behalf of
-   the copyright owner. For the purposes of this definition, "submitted"
-   means any form of electronic, verbal, or written communication sent
-   to the Licensor or its representatives, including but not limited to
-   communication on electronic mailing lists, source code control systems,
-   and issue tracking systems that are managed by, or on behalf of, the
-   Licensor for the purpose of discussing and improving the Work, but
-   excluding communication that is conspicuously marked or otherwise
-   designated in writing by the copyright owner as "Not a Contribution."
-
-   "Contributor" shall mean Licensor and any individual or Legal Entity
-   on behalf of whom a Contribution has been received by Licensor and
-   subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   copyright license to reproduce, prepare Derivative Works of,
-   publicly display, publicly perform, sublicense, and distribute the
-   Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   (except as stated in this section) patent license to make, have made,
-   use, offer to sell, sell, import, and otherwise transfer the Work,
-   where such license applies only to those patent claims licensable
-   by such Contributor that are necessarily infringed by their
-   Contribution(s) alone or by combination of their Contribution(s)
-   with the Work to which such Contribution(s) was submitted. If You
-   institute patent litigation against any entity (including a
-   cross-claim or counterclaim in a lawsuit) alleging that the Work
-   or a Contribution incorporated within the Work constitutes direct
-   or contributory patent infringement, then any patent licenses
-   granted to You under this License for that Work shall terminate
-   as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
-   Work or Derivative Works thereof in any medium, with or without
-   modifications, and in Source or Object form, provided that You
-   meet the following conditions:
-
-   (a) You must give any other recipients of the Work or
-       Derivative Works a copy of this License; and
-
-   (b) You must cause any modified files to carry prominent notices
-       stating that You changed the files; and
-
-   (c) You must retain, in the Source form of any Derivative Works
-       that You distribute, all copyright, patent, trademark, and
-       attribution notices from the Source form of the Work,
-       excluding those notices that do not pertain to any part of
-       the Derivative Works; and
-
-   (d) If the Work includes a "NOTICE" text file as part of its
-       distribution, then any Derivative Works that You distribute must
-       include a readable copy of the attribution notices contained
-       within such NOTICE file, excluding those notices that do not
-       pertain to any part of the Derivative Works, in at least one
-       of the following places: within a NOTICE text file distributed
-       as part of the Derivative Works; within the Source form or
-       documentation, if provided along with the Derivative Works; or,
-       within a display generated by the Derivative Works, if and
-       wherever such third-party notices normally appear. The contents
-       of the NOTICE file are for informational purposes only and
-       do not modify the License. You may add Your own attribution
-       notices within Derivative Works that You distribute, alongside
-       or as an addendum to the NOTICE text from the Work, provided
-       that such additional attribution notices cannot be construed
-       as modifying the License.
-
-   You may add Your own copyright statement to Your modifications and
-   may provide additional or different license terms and conditions
-   for use, reproduction, or distribution of Your modifications, or
-   for any such Derivative Works as a whole, provided Your use,
-   reproduction, and distribution of the Work otherwise complies with
-   the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
-   any Contribution intentionally submitted for inclusion in the Work
-   by You to the Licensor shall be under the terms and conditions of
-   this License, without any additional terms or conditions.
-   Notwithstanding the above, nothing herein shall supersede or modify
-   the terms of any separate license agreement you may have executed
-   with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
-   names, trademarks, service marks, or product names of the Licensor,
-   except as required for reasonable and customary use in describing the
-   origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
-   agreed to in writing, Licensor provides the Work (and each
-   Contributor provides its Contributions) on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-   implied, including, without limitation, any warranties or conditions
-   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-   PARTICULAR PURPOSE. You are solely responsible for determining the
-   appropriateness of using or redistributing the Work and assume any
-   risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
-   whether in tort (including negligence), contract, or otherwise,
-   unless required by applicable law (such as deliberate and grossly
-   negligent acts) or agreed to in writing, shall any Contributor be
-   liable to You for damages, including any direct, indirect, special,
-   incidental, or consequential damages of any character arising as a
-   result of this License or out of the use or inability to use the
-   Work (including but not limited to damages for loss of goodwill,
-   work stoppage, computer failure or malfunction, or any and all
-   other commercial damages or losses), even if such Contributor
-   has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
-   the Work or Derivative Works thereof, You may choose to offer,
-   and charge a fee for, acceptance of support, warranty, indemnity,
-   or other liability obligations and/or rights consistent with this
-   License. However, in accepting such obligations, You may act only
-   on Your own behalf and on Your sole responsibility, not on behalf
-   of any other Contributor, and only if You agree to indemnify,
-   defend, and hold each Contributor harmless for any liability
-   incurred by, or claims asserted against, such Contributor by reason
-   of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-   To apply the Apache License to your work, attach the following
-   boilerplate notice, with the fields enclosed by brackets "[]"
-   replaced with your own identifying information. (Don't include
-   the brackets!)  The text should be enclosed in the appropriate
-   comment syntax for the file format. We also recommend that a
-   file or class name and description of purpose be included on the
-   same "printed page" as the copyright notice for easier
-   identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff -rNu firefox-140.10.2.orig/third_party/rust/lazycell/LICENSE-MIT firefox-140.10.2/third_party/rust/lazycell/LICENSE-MIT
--- firefox-140.10.2.orig/third_party/rust/lazycell/LICENSE-MIT	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/lazycell/LICENSE-MIT	Thu Jan  1 01:00:00 1970
@@ -1,26 +0,0 @@
-Original work Copyright (c) 2014 The Rust Project Developers
-Modified work Copyright (c) 2016-2018 Nikita Pekin and lazycell contributors
-
-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 -rNu firefox-140.10.2.orig/third_party/rust/lazycell/README.md firefox-140.10.2/third_party/rust/lazycell/README.md
--- firefox-140.10.2.orig/third_party/rust/lazycell/README.md	Wed May  6 16:54:53 2026
+++ firefox-140.10.2/third_party/rust/lazycell/README.md	Thu Jan  1 01:00:00 1970
@@ -1,73 +0,0 @@
-# lazycell
-
-<table>
-    <tr>
-        <td><strong>Linux</strong></td>
-        <td><a href="https://travis-ci.org/indiv0/lazycell" title="Travis Build Status"><img src="https://travis-ci.org/indiv0/lazycell.svg?branch=master" alt="travis-badge"></img></a></td>
-    </tr>
-    <tr>
-        <td colspan="2">
-            <a href="https://crates.io/crates/lazycell" title="Crates.io downloads"><img src="https://img.shields.io/crates/d/lazycell.svg" alt="cargo-downloads-badge"></img></a>
-            <a href="https://indiv0.github.io/lazycell/lazycell" title="API Docs"><img src="https://img.shields.io/badge/API-docs-blue.svg" alt="api-docs-badge"></img></a>
-            <a href="https://crates.io/crates/lazycell" title="Crates.io"><img src="https://img.shields.io/crates/v/lazycell.svg" alt="crates-io"></img></a>
-            <a href="#license" title="License: MIT/Apache-2.0"><img src="https://img.shields.io/crates/l/lazycell.svg" alt="license-badge"></img></a>
-            <a href="https://coveralls.io/github/indiv0/lazycell?branch=master" title="Coverage Status"><img src="https://coveralls.io/repos/github/indiv0/lazycell/badge.svg?branch=master" alt="coveralls-badge"></img></a>
-        </td>
-    </tr>
-</table>
-
-Rust library providing a lazily filled Cell.
-
-# Table of Contents
-
-* [Usage](#usage)
-* [Contributing](#contributing)
-* [Credits](#credits)
-* [License](#license)
-
-## Usage
-
-Add the following to your `Cargo.toml`:
-
-```toml
-[dependencies]
-lazycell = "1.3"
-```
-
-And in your `lib.rs` or `main.rs`:
-
-```rust
-extern crate lazycell;
-```
-
-See the [API docs][api-docs] for information on using the crate in your library.
-
-## Contributing
-
-Contributions are always welcome!
-If you have an idea for something to add (code, documentation, tests, examples,
-etc.) feel free to give it a shot.
-
-Please read [CONTRIBUTING.md][contributing] before you start contributing.
-
-## Credits
-
-The LazyCell library is based originally on work by The Rust Project Developers
-for the project [crates.io][crates-io-repo].
-
-The list of contributors to this project can be found at
-[CONTRIBUTORS.md][contributors].
-
-## License
-
-LazyCell is distributed under the terms of both the MIT license and the Apache
-License (Version 2.0).
-
-See [LICENSE-APACHE][license-apache], and [LICENSE-MIT][license-mit] for details.
-
-[api-docs]: https://indiv0.github.io/lazycell/lazycell
-[contributing]: https://github.com/indiv0/lazycell/blob/master/CONTRIBUTING.md "Contribution Guide"
-[contributors]: https://github.com/indiv0/lazycell/blob/master/CONTRIBUTORS.md "List of Contributors"
-[crates-io-repo]: https://github.com/rust-lang/crates.io "rust-lang/crates.io: Source code for crates.io"
-[license-apache]: https://github.com/indiv0/lazycell/blob/master/LICENSE-APACHE "Apache-2.0 License"
-[license-mit]: https://github.com/indiv0/lazycell/blob/master/LICENSE-MIT "MIT License"
diff -rNu firefox-140.10.2.orig/third_party/rust/lazycell/src/lib.rs firefox-140.10.2/third_party/rust/lazycell/src/lib.rs
--- firefox-140.10.2.orig/third_party/rust/lazycell/src/lib.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/lazycell/src/lib.rs	Thu Jan  1 01:00:00 1970
@@ -1,680 +0,0 @@
-// Original work Copyright (c) 2014 The Rust Project Developers
-// Modified work Copyright (c) 2016-2020 Nikita Pekin and the lazycell contributors
-// See the README.md file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg_attr(not(test), no_std)]
-
-#![deny(missing_docs)]
-#![cfg_attr(feature = "nightly", feature(plugin))]
-#![cfg_attr(feature = "clippy", plugin(clippy))]
-
-//! This crate provides a `LazyCell` struct which acts as a lazily filled
-//! `Cell`.
-//!
-//! With a `RefCell`, the inner contents cannot be borrowed for the lifetime of
-//! the entire object, but only of the borrows returned. A `LazyCell` is a
-//! variation on `RefCell` which allows borrows to be tied to the lifetime of
-//! the outer object.
-//!
-//! # Example
-//!
-//! The following example shows a quick example of the basic functionality of
-//! `LazyCell`.
-//!
-//! ```
-//! use lazycell::LazyCell;
-//!
-//! let lazycell = LazyCell::new();
-//!
-//! assert_eq!(lazycell.borrow(), None);
-//! assert!(!lazycell.filled());
-//! lazycell.fill(1).ok();
-//! assert!(lazycell.filled());
-//! assert_eq!(lazycell.borrow(), Some(&1));
-//! assert_eq!(lazycell.into_inner(), Some(1));
-//! ```
-//!
-//! `AtomicLazyCell` is a variant that uses an atomic variable to manage
-//! coordination in a thread-safe fashion. The limitation of an `AtomicLazyCell`
-//! is that after it is initialized, it can't be modified.
-
-
-#[cfg(not(test))]
-#[macro_use]
-extern crate core as std;
-#[cfg(feature = "serde")]
-extern crate serde;
-
-#[cfg(feature = "serde")]
-mod serde_impl;
-
-use std::cell::UnsafeCell;
-use std::mem;
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-/// A lazily filled `Cell`, with mutable contents.
-///
-/// A `LazyCell` is completely frozen once filled, **unless** you have `&mut`
-/// access to it, in which case `LazyCell::borrow_mut` may be used to mutate the
-/// contents.
-#[derive(Debug)]
-pub struct LazyCell<T> {
-    inner: UnsafeCell<Option<T>>,
-}
-
-impl<T> LazyCell<T> {
-    /// Creates a new, empty, `LazyCell`.
-    pub fn new() -> LazyCell<T> {
-        LazyCell { inner: UnsafeCell::new(None) }
-    }
-
-    /// Put a value into this cell.
-    ///
-    /// This function will return `Err(value)` if the cell is already full.
-    pub fn fill(&self, value: T) -> Result<(), T> {
-        let slot = unsafe { &*self.inner.get() };
-        if slot.is_some() {
-            return Err(value);
-        }
-        let slot = unsafe { &mut *self.inner.get() };
-        *slot = Some(value);
-
-        Ok(())
-    }
-
-    /// Put a value into this cell.
-    ///
-    /// Note that this function is infallible but requires `&mut self`. By
-    /// requiring `&mut self` we're guaranteed that no active borrows to this
-    /// cell can exist so we can always fill in the value. This may not always
-    /// be usable, however, as `&mut self` may not be possible to borrow.
-    ///
-    /// # Return value
-    ///
-    /// This function returns the previous value, if any.
-    pub fn replace(&mut self, value: T) -> Option<T> {
-        mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
-    }
-
-    /// Test whether this cell has been previously filled.
-    pub fn filled(&self) -> bool {
-        self.borrow().is_some()
-    }
-
-    /// Borrows the contents of this lazy cell for the duration of the cell
-    /// itself.
-    ///
-    /// This function will return `Some` if the cell has been previously
-    /// initialized, and `None` if it has not yet been initialized.
-    pub fn borrow(&self) -> Option<&T> {
-        unsafe { &*self.inner.get() }.as_ref()
-    }
-
-    /// Borrows the contents of this lazy cell mutably for the duration of the cell
-    /// itself.
-    ///
-    /// This function will return `Some` if the cell has been previously
-    /// initialized, and `None` if it has not yet been initialized.
-    pub fn borrow_mut(&mut self) -> Option<&mut T> {
-        unsafe { &mut *self.inner.get() }.as_mut()
-    }
-
-    /// Borrows the contents of this lazy cell for the duration of the cell
-    /// itself.
-    ///
-    /// If the cell has not yet been filled, the cell is first filled using the
-    /// function provided.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the cell becomes filled as a side effect of `f`.
-    pub fn borrow_with<F: FnOnce() -> T>(&self, f: F) -> &T {
-        if let Some(value) = self.borrow() {
-            return value;
-        }
-        let value = f();
-        if self.fill(value).is_err() {
-            panic!("borrow_with: cell was filled by closure")
-        }
-        self.borrow().unwrap()
-    }
-
-    /// Borrows the contents of this `LazyCell` mutably for the duration of the
-    /// cell itself.
-    ///
-    /// If the cell has not yet been filled, the cell is first filled using the
-    /// function provided.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the cell becomes filled as a side effect of `f`.
-    pub fn borrow_mut_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
-        if !self.filled() {
-            let value = f();
-            if self.fill(value).is_err() {
-                panic!("borrow_mut_with: cell was filled by closure")
-            }
-        }
-
-        self.borrow_mut().unwrap()
-    }
-
-    /// Same as `borrow_with`, but allows the initializing function to fail.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the cell becomes filled as a side effect of `f`.
-    pub fn try_borrow_with<E, F>(&self, f: F) -> Result<&T, E>
-        where F: FnOnce() -> Result<T, E>
-    {
-        if let Some(value) = self.borrow() {
-            return Ok(value);
-        }
-        let value = f()?;
-        if self.fill(value).is_err() {
-            panic!("try_borrow_with: cell was filled by closure")
-        }
-        Ok(self.borrow().unwrap())
-    }
-
-    /// Same as `borrow_mut_with`, but allows the initializing function to fail.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the cell becomes filled as a side effect of `f`.
-    pub fn try_borrow_mut_with<E, F>(&mut self, f: F) -> Result<&mut T, E>
-        where F: FnOnce() -> Result<T, E>
-    {
-        if self.filled() {
-            return Ok(self.borrow_mut().unwrap());
-        }
-        let value = f()?;
-        if self.fill(value).is_err() {
-            panic!("try_borrow_mut_with: cell was filled by closure")
-        }
-        Ok(self.borrow_mut().unwrap())
-    }
-
-    /// Consumes this `LazyCell`, returning the underlying value.
-    pub fn into_inner(self) -> Option<T> {
-        // Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
-        // function. This unsafe can be removed when supporting Rust older than
-        // 1.25 is not needed.
-        #[allow(unused_unsafe)]
-        unsafe { self.inner.into_inner() }
-    }
-}
-
-impl<T: Copy> LazyCell<T> {
-    /// Returns a copy of the contents of the lazy cell.
-    ///
-    /// This function will return `Some` if the cell has been previously initialized,
-    /// and `None` if it has not yet been initialized.
-    pub fn get(&self) -> Option<T> {
-        unsafe { *self.inner.get() }
-    }
-}
-
-impl<T> Default for LazyCell<T> {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-impl <T: Clone> Clone for LazyCell<T> {
-    /// Create a clone of this `LazyCell`
-    ///
-    /// If self has not been initialized, returns an uninitialized `LazyCell`
-    /// otherwise returns a `LazyCell` already initialized with a clone of the
-    /// contents of self.
-    fn clone(&self) -> LazyCell<T> {
-        LazyCell { inner: UnsafeCell::new(self.borrow().map(Clone::clone) ) }
-    }
-}
-
-// Tracks the AtomicLazyCell inner state
-const NONE: usize = 0;
-const LOCK: usize = 1;
-const SOME: usize = 2;
-
-/// A lazily filled and thread-safe `Cell`, with frozen contents.
-#[derive(Debug)]
-pub struct AtomicLazyCell<T> {
-    inner: UnsafeCell<Option<T>>,
-    state: AtomicUsize,
-}
-
-impl<T> AtomicLazyCell<T> {
-    /// An empty `AtomicLazyCell`.
-    pub const NONE: Self = Self {
-        inner: UnsafeCell::new(None),
-        state: AtomicUsize::new(NONE),
-    };
-
-    /// Creates a new, empty, `AtomicLazyCell`.
-    pub fn new() -> AtomicLazyCell<T> {
-        Self::NONE
-    }
-
-    /// Put a value into this cell.
-    ///
-    /// This function will return `Err(value)` if the cell is already full.
-    pub fn fill(&self, t: T) -> Result<(), T> {
-        if NONE != self.state.compare_and_swap(NONE, LOCK, Ordering::Acquire) {
-            return Err(t);
-        }
-
-        unsafe { *self.inner.get() = Some(t) };
-
-        if LOCK != self.state.compare_and_swap(LOCK, SOME, Ordering::Release) {
-            panic!("unable to release lock");
-        }
-
-        Ok(())
-    }
-
-    /// Put a value into this cell.
-    ///
-    /// Note that this function is infallible but requires `&mut self`. By
-    /// requiring `&mut self` we're guaranteed that no active borrows to this
-    /// cell can exist so we can always fill in the value. This may not always
-    /// be usable, however, as `&mut self` may not be possible to borrow.
-    ///
-    /// # Return value
-    ///
-    /// This function returns the previous value, if any.
-    pub fn replace(&mut self, value: T) -> Option<T> {
-        match mem::replace(self.state.get_mut(), SOME) {
-            NONE | SOME => {}
-            _ => panic!("cell in inconsistent state"),
-        }
-        mem::replace(unsafe { &mut *self.inner.get() }, Some(value))
-    }
-
-    /// Test whether this cell has been previously filled.
-    pub fn filled(&self) -> bool {
-        self.state.load(Ordering::Acquire) == SOME
-    }
-
-    /// Borrows the contents of this lazy cell for the duration of the cell
-    /// itself.
-    ///
-    /// This function will return `Some` if the cell has been previously
-    /// initialized, and `None` if it has not yet been initialized.
-    pub fn borrow(&self) -> Option<&T> {
-        match self.state.load(Ordering::Acquire) {
-            SOME => unsafe { &*self.inner.get() }.as_ref(),
-            _ => None,
-        }
-    }
-
-    /// Consumes this `LazyCell`, returning the underlying value.
-    pub fn into_inner(self) -> Option<T> {
-        // Rust 1.25 changed UnsafeCell::into_inner() from unsafe to safe
-        // function. This unsafe can be removed when supporting Rust older than
-        // 1.25 is not needed.
-        #[allow(unused_unsafe)]
-        unsafe { self.inner.into_inner() }
-    }
-}
-
-impl<T: Copy> AtomicLazyCell<T> {
-    /// Returns a copy of the contents of the lazy cell.
-    ///
-    /// This function will return `Some` if the cell has been previously initialized,
-    /// and `None` if it has not yet been initialized.
-    pub fn get(&self) -> Option<T> {
-        match self.state.load(Ordering::Acquire) {
-            SOME => unsafe { *self.inner.get() },
-            _ => None,
-        }
-    }
-}
-
-impl<T> Default for AtomicLazyCell<T> {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-impl<T: Clone> Clone for AtomicLazyCell<T> {
-    /// Create a clone of this `AtomicLazyCell`
-    ///
-    /// If self has not been initialized, returns an uninitialized `AtomicLazyCell`
-    /// otherwise returns an `AtomicLazyCell` already initialized with a clone of the
-    /// contents of self.
-    fn clone(&self) -> AtomicLazyCell<T> {
-        self.borrow().map_or(
-            Self::NONE,
-            |v| AtomicLazyCell {
-                inner: UnsafeCell::new(Some(v.clone())),
-                state: AtomicUsize::new(SOME),
-            }
-        )
-    }
-}
-
-unsafe impl<T: Sync + Send> Sync for AtomicLazyCell<T> {}
-
-unsafe impl<T: Send> Send for AtomicLazyCell<T> {}
-
-#[cfg(test)]
-mod tests {
-    use super::{AtomicLazyCell, LazyCell};
-
-    #[test]
-    fn test_borrow_from_empty() {
-        let lazycell: LazyCell<usize> = LazyCell::new();
-
-        let value = lazycell.borrow();
-        assert_eq!(value, None);
-
-        let value = lazycell.get();
-        assert_eq!(value, None);
-    }
-
-    #[test]
-    fn test_fill_and_borrow() {
-        let lazycell = LazyCell::new();
-
-        assert!(!lazycell.filled());
-        lazycell.fill(1).unwrap();
-        assert!(lazycell.filled());
-
-        let value = lazycell.borrow();
-        assert_eq!(value, Some(&1));
-
-        let value = lazycell.get();
-        assert_eq!(value, Some(1));
-    }
-
-    #[test]
-    fn test_borrow_mut() {
-        let mut lazycell = LazyCell::new();
-        assert!(lazycell.borrow_mut().is_none());
-
-        lazycell.fill(1).unwrap();
-        assert_eq!(lazycell.borrow_mut(), Some(&mut 1));
-
-        *lazycell.borrow_mut().unwrap() = 2;
-        assert_eq!(lazycell.borrow_mut(), Some(&mut 2));
-
-        // official way to reset the cell
-        lazycell = LazyCell::new();
-        assert!(lazycell.borrow_mut().is_none());
-    }
-
-    #[test]
-    fn test_already_filled_error() {
-        let lazycell = LazyCell::new();
-
-        lazycell.fill(1).unwrap();
-        assert_eq!(lazycell.fill(1), Err(1));
-    }
-
-    #[test]
-    fn test_borrow_with() {
-        let lazycell = LazyCell::new();
-
-        let value = lazycell.borrow_with(|| 1);
-        assert_eq!(&1, value);
-    }
-
-    #[test]
-    fn test_borrow_with_already_filled() {
-        let lazycell = LazyCell::new();
-        lazycell.fill(1).unwrap();
-
-        let value = lazycell.borrow_with(|| 1);
-        assert_eq!(&1, value);
-    }
-
-    #[test]
-    fn test_borrow_with_not_called_when_filled() {
-        let lazycell = LazyCell::new();
-
-        lazycell.fill(1).unwrap();
-
-        let value = lazycell.borrow_with(|| 2);
-        assert_eq!(&1, value);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_borrow_with_sound_with_reentrancy() {
-        // Kudos to dbaupp for discovering this issue
-        // https://www.reddit.com/r/rust/comments/5vs9rt/lazycell_a_rust_library_providing_a_lazilyfilled/de527xm/
-        let lazycell: LazyCell<Box<i32>> = LazyCell::new();
-
-        let mut reference: Option<&i32> = None;
-
-        lazycell.borrow_with(|| {
-            let _ = lazycell.fill(Box::new(1));
-            reference = lazycell.borrow().map(|r| &**r);
-            Box::new(2)
-        });
-    }
-
-    #[test]
-    fn test_borrow_mut_with() {
-        let mut lazycell = LazyCell::new();
-
-        {
-            let value = lazycell.borrow_mut_with(|| 1);
-            assert_eq!(&mut 1, value);
-            *value = 2;
-        }
-        assert_eq!(&2, lazycell.borrow().unwrap());
-    }
-
-    #[test]
-    fn test_borrow_mut_with_already_filled() {
-        let mut lazycell = LazyCell::new();
-        lazycell.fill(1).unwrap();
-
-        let value = lazycell.borrow_mut_with(|| 1);
-        assert_eq!(&1, value);
-    }
-
-    #[test]
-    fn test_borrow_mut_with_not_called_when_filled() {
-        let mut lazycell = LazyCell::new();
-
-        lazycell.fill(1).unwrap();
-
-        let value = lazycell.borrow_mut_with(|| 2);
-        assert_eq!(&1, value);
-    }
-
-    #[test]
-    fn test_try_borrow_with_ok() {
-        let lazycell = LazyCell::new();
-        let result = lazycell.try_borrow_with::<(), _>(|| Ok(1));
-        assert_eq!(result, Ok(&1));
-    }
-
-    #[test]
-    fn test_try_borrow_with_err() {
-        let lazycell = LazyCell::<()>::new();
-        let result = lazycell.try_borrow_with(|| Err(1));
-        assert_eq!(result, Err(1));
-    }
-
-    #[test]
-    fn test_try_borrow_with_already_filled() {
-        let lazycell = LazyCell::new();
-        lazycell.fill(1).unwrap();
-        let result = lazycell.try_borrow_with::<(), _>(|| unreachable!());
-        assert_eq!(result, Ok(&1));
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_try_borrow_with_sound_with_reentrancy() {
-        let lazycell: LazyCell<Box<i32>> = LazyCell::new();
-
-        let mut reference: Option<&i32> = None;
-
-        let _ = lazycell.try_borrow_with::<(), _>(|| {
-            let _ = lazycell.fill(Box::new(1));
-            reference = lazycell.borrow().map(|r| &**r);
-            Ok(Box::new(2))
-        });
-    }
-
-    #[test]
-    fn test_try_borrow_mut_with_ok() {
-        let mut lazycell = LazyCell::new();
-        {
-            let result = lazycell.try_borrow_mut_with::<(), _>(|| Ok(1));
-            assert_eq!(result, Ok(&mut 1));
-            *result.unwrap() = 2;
-        }
-        assert_eq!(&mut 2, lazycell.borrow().unwrap());
-    }
-
-    #[test]
-    fn test_try_borrow_mut_with_err() {
-        let mut lazycell = LazyCell::<()>::new();
-        let result = lazycell.try_borrow_mut_with(|| Err(1));
-        assert_eq!(result, Err(1));
-    }
-
-    #[test]
-    fn test_try_borrow_mut_with_already_filled() {
-        let mut lazycell = LazyCell::new();
-        lazycell.fill(1).unwrap();
-        let result = lazycell.try_borrow_mut_with::<(), _>(|| unreachable!());
-        assert_eq!(result, Ok(&mut 1));
-    }
-
-    #[test]
-    fn test_into_inner() {
-        let lazycell = LazyCell::new();
-
-        lazycell.fill(1).unwrap();
-        let value = lazycell.into_inner();
-        assert_eq!(value, Some(1));
-    }
-
-    #[test]
-    fn test_atomic_borrow_from_empty() {
-        let lazycell: AtomicLazyCell<usize> = AtomicLazyCell::new();
-
-        let value = lazycell.borrow();
-        assert_eq!(value, None);
-
-        let value = lazycell.get();
-        assert_eq!(value, None);
-    }
-
-    #[test]
-    fn test_atomic_fill_and_borrow() {
-        let lazycell = AtomicLazyCell::new();
-
-        assert!(!lazycell.filled());
-        lazycell.fill(1).unwrap();
-        assert!(lazycell.filled());
-
-        let value = lazycell.borrow();
-        assert_eq!(value, Some(&1));
-
-        let value = lazycell.get();
-        assert_eq!(value, Some(1));
-    }
-
-    #[test]
-    fn test_atomic_already_filled_panic() {
-        let lazycell = AtomicLazyCell::new();
-
-        lazycell.fill(1).unwrap();
-        assert_eq!(1, lazycell.fill(1).unwrap_err());
-    }
-
-    #[test]
-    fn test_atomic_into_inner() {
-        let lazycell = AtomicLazyCell::new();
-
-        lazycell.fill(1).unwrap();
-        let value = lazycell.into_inner();
-        assert_eq!(value, Some(1));
-    }
-
-    #[test]
-    fn normal_replace() {
-        let mut cell = LazyCell::new();
-        assert_eq!(cell.fill(1), Ok(()));
-        assert_eq!(cell.replace(2), Some(1));
-        assert_eq!(cell.replace(3), Some(2));
-        assert_eq!(cell.borrow(), Some(&3));
-
-        let mut cell = LazyCell::new();
-        assert_eq!(cell.replace(2), None);
-    }
-
-    #[test]
-    fn atomic_replace() {
-        let mut cell = AtomicLazyCell::new();
-        assert_eq!(cell.fill(1), Ok(()));
-        assert_eq!(cell.replace(2), Some(1));
-        assert_eq!(cell.replace(3), Some(2));
-        assert_eq!(cell.borrow(), Some(&3));
-    }
-
-    #[test]
-    fn clone() {
-        let mut cell = LazyCell::new();
-        let clone1 = cell.clone();
-        assert_eq!(clone1.borrow(), None);
-        assert_eq!(cell.fill(1), Ok(()));
-        let mut clone2 = cell.clone();
-        assert_eq!(clone1.borrow(), None);
-        assert_eq!(clone2.borrow(), Some(&1));
-        assert_eq!(cell.replace(2), Some(1));
-        assert_eq!(clone1.borrow(), None);
-        assert_eq!(clone2.borrow(), Some(&1));
-        assert_eq!(clone1.fill(3), Ok(()));
-        assert_eq!(clone2.replace(4), Some(1));
-        assert_eq!(clone1.borrow(), Some(&3));
-        assert_eq!(clone2.borrow(), Some(&4));
-        assert_eq!(cell.borrow(), Some(&2));
-    }
-
-    #[test]
-    fn clone_atomic() {
-        let mut cell = AtomicLazyCell::new();
-        let clone1 = cell.clone();
-        assert_eq!(clone1.borrow(), None);
-        assert_eq!(cell.fill(1), Ok(()));
-        let mut clone2 = cell.clone();
-        assert_eq!(clone1.borrow(), None);
-        assert_eq!(clone2.borrow(), Some(&1));
-        assert_eq!(cell.replace(2), Some(1));
-        assert_eq!(clone1.borrow(), None);
-        assert_eq!(clone2.borrow(), Some(&1));
-        assert_eq!(clone1.fill(3), Ok(()));
-        assert_eq!(clone2.replace(4), Some(1));
-        assert_eq!(clone1.borrow(), Some(&3));
-        assert_eq!(clone2.borrow(), Some(&4));
-        assert_eq!(cell.borrow(), Some(&2));
-    }
-
-    #[test]
-    fn default() {
-        #[derive(Default)]
-        struct Defaultable;
-        struct NonDefaultable;
-
-        let _: LazyCell<Defaultable> = LazyCell::default();
-        let _: LazyCell<NonDefaultable> = LazyCell::default();
-
-        let _: AtomicLazyCell<Defaultable> = AtomicLazyCell::default();
-        let _: AtomicLazyCell<NonDefaultable> = AtomicLazyCell::default();
-    }
-}
diff -rNu firefox-140.10.2.orig/third_party/rust/lazycell/src/serde_impl.rs firefox-140.10.2/third_party/rust/lazycell/src/serde_impl.rs
--- firefox-140.10.2.orig/third_party/rust/lazycell/src/serde_impl.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/lazycell/src/serde_impl.rs	Thu Jan  1 01:00:00 1970
@@ -1,86 +0,0 @@
-// Copyright (c) 2020 Nikita Pekin and the lazycell contributors
-// See the README.md file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.use serde::ser::{Serialize, Serializer};
-use serde::ser::{Serialize, Serializer};
-use serde::de::{self, Deserialize, Deserializer, Visitor};
-
-use std::fmt;
-use std::marker::PhantomData;
-
-use super::{LazyCell, AtomicLazyCell};
-
-impl<T: Serialize> Serialize for LazyCell<T> {
-    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
-        match self.borrow() {
-            Some(val) => serializer.serialize_some(val),
-            None => serializer.serialize_none()
-        }
-    }
-}
-
-
-impl<T: Serialize> Serialize for AtomicLazyCell<T> {
-    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
-        match self.borrow() {
-            Some(val) => serializer.serialize_some(val),
-            None => serializer.serialize_none()
-        }
-    }
-}
-
-struct LazyCellVisitor<T>(PhantomData<*const T>);
-impl<'de, T: Deserialize<'de>> Visitor<'de> for LazyCellVisitor<T> {
-    type Value = LazyCell<T>;
-
-    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        formatter.write_str("a LazyCell")
-    }
-
-    fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
-        let mut cell = LazyCell::new();
-        cell.replace(T::deserialize(deserializer)?);
-        Ok(cell)
-    }
-
-    fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
-        Ok(LazyCell::new())
-    }
-}
-
-impl<'de, T: Deserialize<'de>> Deserialize<'de> for LazyCell<T> {
-    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
-        deserializer.deserialize_option(LazyCellVisitor(PhantomData))
-    }
-}
-
-
-struct AtomicLazyCellVisitor<T>(PhantomData<*const T>);
-impl<'de, T: Deserialize<'de>> Visitor<'de> for AtomicLazyCellVisitor<T> {
-    type Value = AtomicLazyCell<T>;
-
-    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        formatter.write_str("an AtomicLazyCell")
-    }
-
-    fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
-        let mut cell = AtomicLazyCell::new();
-        cell.replace(T::deserialize(deserializer)?);
-        Ok(cell)
-    }
-
-    fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
-        Ok(AtomicLazyCell::new())
-    }
-}
-
-
-impl<'de, T: Deserialize<'de>> Deserialize<'de> for AtomicLazyCell<T> {
-    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
-        deserializer.deserialize_option(AtomicLazyCellVisitor(PhantomData))
-    }
-}
diff -rNu firefox-140.10.2.orig/third_party/rust/neqo-crypto/src/agent.rs firefox-140.10.2/third_party/rust/neqo-crypto/src/agent.rs
--- firefox-140.10.2.orig/third_party/rust/neqo-crypto/src/agent.rs	Wed May  6 16:54:54 2026
+++ firefox-140.10.2/third_party/rust/neqo-crypto/src/agent.rs	Mon May 11 04:49:32 2026
@@ -1089,7 +1089,7 @@
                 return Err(Error::CertificateLoading);
             };
             secstatus_to_res(unsafe {
-                ssl::SSL_ConfigServerCert(agent.fd, *cert, *key, null(), 0)
+                ssl::SSL_ConfigServerCert(agent.fd, (*cert).cast(), (*key).cast(), null(), 0)
             })?;
         }
 
diff -rNu firefox-140.10.2.orig/toolkit/crashreporter/client/app/src/ui/macos/mod.rs firefox-140.10.2/toolkit/crashreporter/client/app/src/ui/macos/mod.rs
--- firefox-140.10.2.orig/toolkit/crashreporter/client/app/src/ui/macos/mod.rs	Wed May  6 16:54:55 2026
+++ firefox-140.10.2/toolkit/crashreporter/client/app/src/ui/macos/mod.rs	Mon May 11 04:49:32 2026
@@ -170,7 +170,7 @@
                     cocoa::NSArray(<cocoa::NSArray as NSArray_NSArrayCreation<
                         cocoa::NSRunLoopMode,
                     >>::arrayWithObjects_count_(
-                        objects.as_slice().as_ptr() as *const *mut u64,
+                        objects.as_slice().as_ptr() as *const *mut _,
                         objects
                             .as_slice()
                             .len()
@@ -1082,8 +1082,8 @@
                             cocoa::NSAttributedStringKey,
                             cocoa::id,
                         >>::dictionaryWithObject_forKey_(
-                            cocoa::NSColor::placeholderTextColor().0 as u64,
-                            cocoa::NSForegroundColorAttributeName.0 as u64,
+                            std::mem::transmute(cocoa::NSColor::placeholderTextColor().0),
+                            std::mem::transmute(cocoa::NSForegroundColorAttributeName.0),
                         ),
                     );
                     let string = StrongRef::new(cocoa::NSAttributedString(
diff -rNu firefox-140.10.2.orig/tools/profiler/rust-api/build.rs firefox-140.10.2/tools/profiler/rust-api/build.rs
--- firefox-140.10.2.orig/tools/profiler/rust-api/build.rs	Wed May  6 16:54:55 2026
+++ firefox-140.10.2/tools/profiler/rust-api/build.rs	Mon May 11 04:49:32 2026
@@ -88,6 +88,11 @@
         // successfully. Otherwise, it fails to build because MarkerSchema has
         // some std::strings as its fields.
         .opaque_type("std::string")
+        .opaque_type("std::unique_ptr")
+        .opaque_type("mozilla::Maybe")
+        .opaque_type("mozilla::MallocAllocPolicy")
+        .opaque_type("mozilla::Variant")
+        .opaque_type("mozilla::baseprofiler::UniqueJSONStrings")
         // std::vector needs to be converted to an opaque type because, if it's
         // not an opaque type, bindgen can't find its size properly and
         // MarkerSchema's total size reduces. That causes a heap buffer overflow.
