Snap for 8730993 from 0336a0dd1f2ad6c5e7edd70d95d1c6c6df213bc7 to mainline-tzdata3-release

Change-Id: I293b579aa32be29e9ce3d9b42318fddf01290483
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index f1c8552..2263767 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "89032649044d875983a851fff6fbde2d4e2ceaeb"
+    "sha1": "696455d1c15e682b2b89f81f409315ea4964aef3"
   }
 }
diff --git a/Android.bp b/Android.bp
index 9166c33..305d025 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,4 @@
-// This file is generated by cargo2android.py --config cargo2android.json.
+// This file is generated by cargo2android.py --run --dependencies --features=clap,runtime,which-rustfmt --host-first-multilib --copy-out.
 // Do not modify this file as changes will be overridden on upgrade.
 
 package {
@@ -43,10 +43,7 @@
 
 rust_binary_host {
     name: "bindgen",
-    // has rustc warnings
     crate_name: "bindgen",
-    cargo_env_compat: true,
-    cargo_pkg_version: "0.59.2",
     srcs: [
         "src/main.rs",
         ":copy_bindgen_build_out",
@@ -79,10 +76,7 @@
 
 rust_library_host {
     name: "libbindgen",
-    // has rustc warnings
     crate_name: "bindgen",
-    cargo_env_compat: true,
-    cargo_pkg_version: "0.59.2",
     srcs: [
         "src/lib.rs",
         ":copy_bindgen_build_out",
@@ -111,3 +105,33 @@
     ],
     compile_multilib: "first",
 }
+
+// dependent_library ["feature_list"]
+//   ansi_term-0.11.0
+//   atty-0.2.14
+//   bitflags-1.2.1 "default"
+//   cexpr-0.4.0
+//   cfg-if-1.0.0
+//   clang-sys-1.2.0 "clang_3_5,clang_3_6,clang_3_7,clang_3_8,clang_3_9,clang_4_0,clang_5_0,clang_6_0,libloading,runtime"
+//   clap-2.33.3 "ansi_term,atty,color,default,strsim,suggestions,vec_map"
+//   glob-0.3.0
+//   lazy_static-1.4.0
+//   lazycell-1.3.0
+//   libc-0.2.93 "default,std"
+//   libloading-0.7.0
+//   memchr-2.3.4 "std,use_std"
+//   nom-5.1.2 "alloc,std"
+//   peeking_take_while-0.1.2
+//   proc-macro2-1.0.26
+//   quote-1.0.9
+//   regex-1.4.5 "std,unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment"
+//   regex-syntax-0.6.23 "unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment"
+//   rustc-hash-1.1.0 "default,std"
+//   shlex-1.0.0
+//   strsim-0.8.0
+//   textwrap-0.11.0
+//   unicode-width-0.1.8 "default"
+//   unicode-xid-0.2.1 "default"
+//   vec_map-0.8.2
+//   version_check-0.9.3
+//   which-3.1.1
diff --git a/Cargo.lock b/Cargo.lock
index d79a408..7fc4535 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -33,7 +33,7 @@
 
 [[package]]
 name = "bindgen"
-version = "0.59.2"
+version = "0.58.1"
 dependencies = [
  "bitflags",
  "cexpr",
@@ -50,7 +50,6 @@
  "regex",
  "rustc-hash",
  "shlex",
- "tempfile",
  "which",
 ]
 
@@ -62,24 +61,30 @@
 
 [[package]]
 name = "cexpr"
-version = "0.6.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
 dependencies = [
  "nom",
 ]
 
 [[package]]
 name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "cfg-if"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "clang-sys"
-version = "1.2.0"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
+checksum = "0659001ab56b791be01d4b729c44376edc6718cf389a502e579b77b758f3296c"
 dependencies = [
  "glob",
  "libc",
@@ -108,16 +113,10 @@
 checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
 
 [[package]]
-name = "either"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
-
-[[package]]
 name = "env_logger"
-version = "0.9.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
+checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd"
 dependencies = [
  "atty",
  "humantime",
@@ -127,17 +126,6 @@
 ]
 
 [[package]]
-name = "getrandom"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi",
-]
-
-[[package]]
 name = "glob"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -145,18 +133,18 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.19"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "humantime"
-version = "2.1.0"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a"
 
 [[package]]
 name = "lazy_static"
@@ -172,27 +160,27 @@
 
 [[package]]
 name = "libc"
-version = "0.2.98"
+version = "0.2.80"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
+checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
 
 [[package]]
 name = "libloading"
-version = "0.7.0"
+version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
+checksum = "1090080fe06ec2648d0da3881d9453d97e71a45f00eb179af7fdd7e3f686fdb0"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "winapi",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.14"
+version = "0.4.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
 ]
 
 [[package]]
@@ -202,19 +190,12 @@
 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
 
 [[package]]
-name = "minimal-lexical"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677"
-
-[[package]]
 name = "nom"
-version = "7.0.0"
+version = "5.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1"
+checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
 dependencies = [
  "memchr",
- "minimal-lexical",
  "version_check",
 ]
 
@@ -225,103 +206,40 @@
 checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 
 [[package]]
-name = "ppv-lite86"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
-
-[[package]]
 name = "proc-macro2"
-version = "1.0.28"
+version = "1.0.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
+checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
 dependencies = [
  "unicode-xid",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.9"
+version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
-name = "rand"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
-dependencies = [
- "libc",
- "rand_chacha",
- "rand_core",
- "rand_hc",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
 name = "regex"
-version = "1.4.6"
+version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
+checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
 dependencies = [
  "aho-corasick",
  "memchr",
  "regex-syntax",
+ "thread_local",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.25"
+version = "0.6.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
-
-[[package]]
-name = "remove_dir_all"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
-dependencies = [
- "winapi",
-]
+checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
 
 [[package]]
 name = "rustc-hash"
@@ -342,24 +260,10 @@
 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
 
 [[package]]
-name = "tempfile"
-version = "3.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
-dependencies = [
- "cfg-if",
- "libc",
- "rand",
- "redox_syscall",
- "remove_dir_all",
- "winapi",
-]
-
-[[package]]
 name = "termcolor"
-version = "1.1.2"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
 dependencies = [
  "winapi-util",
 ]
@@ -374,6 +278,15 @@
 ]
 
 [[package]]
+name = "thread_local"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
 name = "unicode-width"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -381,9 +294,9 @@
 
 [[package]]
 name = "unicode-xid"
-version = "0.2.2"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
 
 [[package]]
 name = "vec_map"
@@ -393,24 +306,16 @@
 
 [[package]]
 name = "version_check"
-version = "0.9.3"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
-
-[[package]]
-name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
 
 [[package]]
 name = "which"
-version = "4.2.1"
+version = "3.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cc009ab82a2afc94b9e467ab4214aee9cad1356cd9191264203d7d72006e00d"
+checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
 dependencies = [
- "either",
- "lazy_static",
  "libc",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index 8b8853a..7cf9236 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,16 +3,17 @@
 # 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.
+# to registry (e.g., crates.io) dependencies
 #
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
+# 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]
 edition = "2018"
 name = "bindgen"
-version = "0.59.2"
+version = "0.58.1"
 authors = ["Jyun-Yan You <jyyou.tw@gmail.com>", "Emilio Cobos Álvarez <emilio@crisal.io>", "Nick Fitzgerald <fitzgen@gmail.com>", "The Servo project developers"]
 build = "build.rs"
 include = ["LICENSE", "README.md", "Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"]
@@ -37,7 +38,7 @@
 version = "1.0.3"
 
 [dependencies.cexpr]
-version = "0.6"
+version = "0.4"
 
 [dependencies.clang-sys]
 version = "1"
@@ -48,7 +49,7 @@
 optional = true
 
 [dependencies.env_logger]
-version = "0.9.0"
+version = "0.8"
 optional = true
 
 [dependencies.lazy_static]
@@ -84,7 +85,7 @@
 version = "1"
 
 [dependencies.which]
-version = "4.2.1"
+version = "3.0"
 optional = true
 default-features = false
 [dev-dependencies.clap]
@@ -96,9 +97,6 @@
 [dev-dependencies.shlex]
 version = "1"
 
-[dev-dependencies.tempfile]
-version = "3"
-
 [features]
 default = ["logging", "clap", "runtime", "which-rustfmt"]
 logging = ["env_logger", "log"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index ba41a22..dd30f09 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -14,7 +14,7 @@
 repository = "https://github.com/rust-lang/rust-bindgen"
 documentation = "https://docs.rs/bindgen"
 homepage = "https://rust-lang.github.io/rust-bindgen/"
-version = "0.59.2"
+version = "0.58.1"
 edition = "2018"
 build = "build.rs"
 
@@ -43,11 +43,10 @@
 diff = "0.1"
 clap = "2"
 shlex = "1"
-tempfile = "3"
 
 [dependencies]
 bitflags = "1.0.3"
-cexpr = "0.6"
+cexpr = "0.4"
 # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982
 clap = { version = "2", optional = true }
 clang-sys = { version = "1", features = ["clang_6_0"] }
@@ -56,14 +55,16 @@
 peeking_take_while = "0.1.2"
 quote = { version = "1", default-features = false }
 regex = { version = "1.0", default-features = false , features = [ "std", "unicode"]}
-which = { version = "4.2.1", optional = true, default-features = false }
+which = { version = "3.0", optional = true, default-features = false }
 shlex = "1"
 rustc-hash = "1.0.1"
+# New validation in 0.3.6 breaks bindgen-integration:
+# https://github.com/alexcrichton/proc-macro2/commit/489c642.
 proc-macro2 = { version = "1", default-features = false }
 
 [dependencies.env_logger]
 optional = true
-version = "0.9.0"
+version = "0.8"
 
 [dependencies.log]
 optional = true
diff --git a/METADATA b/METADATA
index 85b1cce..bed57d2 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/bindgen/bindgen-0.59.2.crate"
+    value: "https://static.crates.io/crates/bindgen/bindgen-0.58.1.crate"
   }
-  version: "0.59.2"
+  version: "0.58.1"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 3
-    day: 1
+    year: 2021
+    month: 4
+    day: 16
   }
 }
diff --git a/README.md b/README.md
index 7b2dbbc..e1ad557 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@
 
 ## MSRV
 
-The minimum supported Rust version is **1.46**.
+The minimum supported Rust version is **1.40**.
 
 No MSRV bump policy has been established yet, so MSRV may increase in any release.
 
@@ -60,10 +60,6 @@
     - 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].
diff --git a/TEST_MAPPING b/TEST_MAPPING
index e4ec3b3..a731acb 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,24 +1,14 @@
 // Generated by update_crate_tests.py for tests that depend on this crate.
 {
-  "imports": [
-    {
-      "path": "external/rust/crates/libsqlite3-sys"
-    }
-  ],
   "presubmit": [
     {
       "name": "keystore2_test"
     },
     {
-      "name": "legacykeystore_test"
-    }
-  ],
-  "presubmit-rust": [
-    {
-      "name": "keystore2_test"
+      "name": "libsqlite3-sys_device_test_src_lib"
     },
     {
-      "name": "legacykeystore_test"
+      "name": "vpnprofilestore_test"
     }
   ]
 }
diff --git a/build.rs b/build.rs
index fcc0bb2..cb40cb0 100644
--- a/build.rs
+++ b/build.rs
@@ -79,12 +79,4 @@
     println!("cargo:rerun-if-env-changed=LIBCLANG_PATH");
     println!("cargo:rerun-if-env-changed=LIBCLANG_STATIC_PATH");
     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()
-    );
-    println!(
-        "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}",
-        std::env::var("TARGET").unwrap().replace("-", "_")
-    );
 }
diff --git a/cargo2android.json b/cargo2android.json
deleted file mode 100644
index 9e5e68b..0000000
--- a/cargo2android.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "copy-out": true,
-  "features": "clap,runtime,which-rustfmt",
-  "host-first-multilib": true,
-  "run": true
-}
\ No newline at end of file
diff --git a/src/callbacks.rs b/src/callbacks.rs
index 9b34544..e288af4 100644
--- a/src/callbacks.rs
+++ b/src/callbacks.rs
@@ -95,12 +95,4 @@
     ) -> Option<ImplementsTrait> {
         None
     }
-
-    /// Provide a list of custom derive attributes.
-    ///
-    /// If no additional attributes are wanted, this function should return an
-    /// empty `Vec`.
-    fn add_derives(&self, _name: &str) -> Vec<String> {
-        vec![]
-    }
 }
diff --git a/src/clang.rs b/src/clang.rs
index 074d459..6612508 100644
--- a/src/clang.rs
+++ b/src/clang.rs
@@ -4,7 +4,9 @@
 #![allow(non_upper_case_globals, dead_code)]
 
 use crate::ir::context::BindgenContext;
+use cexpr;
 use clang_sys::*;
+use regex;
 use std::ffi::{CStr, CString};
 use std::fmt;
 use std::hash::Hash;
@@ -83,7 +85,7 @@
 
             let mut result = Vec::with_capacity(count);
             for i in 0..count {
-                let string_ptr = (*manglings).Strings.add(i);
+                let string_ptr = (*manglings).Strings.offset(i as isize);
                 result.push(cxstring_to_string_leaky(*string_ptr));
             }
             clang_disposeStringSet(manglings);
@@ -221,12 +223,12 @@
     /// not tracking the type declaration but the location of the cursor, given
     /// clang doesn't expose a proper declaration for these types.
     pub fn is_template_like(&self) -> bool {
-        matches!(
-            self.kind(),
+        match self.kind() {
             CXCursor_ClassTemplate |
-                CXCursor_ClassTemplatePartialSpecialization |
-                CXCursor_TypeAliasTemplateDecl
-        )
+            CXCursor_ClassTemplatePartialSpecialization |
+            CXCursor_TypeAliasTemplateDecl => true,
+            _ => false,
+        }
     }
 
     /// Is this Cursor pointing to a function-like macro definition?
@@ -239,7 +241,7 @@
         self.x.kind
     }
 
-    /// Returns true if the cursor is a definition
+    /// Returns true is the cursor is a definition
     pub fn is_definition(&self) -> bool {
         unsafe { clang_isCursorDefinition(self.x) != 0 }
     }
@@ -273,7 +275,7 @@
             return parent.is_in_non_fully_specialized_template();
         }
 
-        true
+        return true;
     }
 
     /// Is this cursor pointing a valid referent?
@@ -400,9 +402,12 @@
     where
         Visitor: FnMut(Cursor) -> CXChildVisitResult,
     {
-        let data = &mut visitor as *mut Visitor;
         unsafe {
-            clang_visitChildren(self.x, visit_children::<Visitor>, data.cast());
+            clang_visitChildren(
+                self.x,
+                visit_children::<Visitor>,
+                mem::transmute(&mut visitor),
+            );
         }
     }
 
@@ -464,27 +469,6 @@
         unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 }
     }
 
-    /// Is the referent a defaulted function?
-    pub fn is_defaulted_function(&self) -> bool {
-        unsafe { clang_CXXMethod_isDefaulted(self.x) != 0 }
-    }
-
-    /// Is the referent a deleted function?
-    pub fn is_deleted_function(&self) -> bool {
-        // Unfortunately, libclang doesn't yet have an API for checking if a
-        // member function is deleted, but the following should be a good
-        // enough approximation.
-        // Deleted functions are implicitly inline according to paragraph 4 of
-        // [dcl.fct.def.delete] in the C++ standard. Normal inline functions
-        // have a definition in the same translation unit, so if this is an
-        // inline function without a definition, and it's not a defaulted
-        // function, we can reasonably safely conclude that it's a deleted
-        // function.
-        self.is_inlined_function() &&
-            self.definition().is_none() &&
-            !self.is_defaulted_function()
-    }
-
     /// Get the width of this cursor's referent bit field, or `None` if the
     /// referent is not a bit field.
     pub fn bit_width(&self) -> Option<u32> {
@@ -895,7 +879,7 @@
 where
     Visitor: FnMut(Cursor) -> CXChildVisitResult,
 {
-    let func: &mut Visitor = unsafe { &mut *(data as *mut Visitor) };
+    let func: &mut Visitor = unsafe { mem::transmute(data) };
     let child = Cursor { x: cur };
 
     (*func)(child)
@@ -1022,7 +1006,7 @@
         let s = unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) };
         // Clang 5.0 introduced changes in the spelling API so it returned the
         // full qualified name. Let's undo that here.
-        if s.split("::").all(is_valid_identifier) {
+        if s.split("::").all(|s| is_valid_identifier(s)) {
             if let Some(s) = s.split("::").last() {
                 return s.to_owned();
             }
@@ -1050,7 +1034,7 @@
                 ctx.target_pointer_size() as c_longlong
             }
             // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813
-            CXType_Auto if self.is_non_deductible_auto_type() => -6,
+            CXType_Auto if self.is_non_deductible_auto_type() => return -6,
             _ => unsafe { clang_Type_getSizeOf(self.x) },
         }
     }
@@ -1063,7 +1047,7 @@
                 ctx.target_pointer_size() as c_longlong
             }
             // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813
-            CXType_Auto if self.is_non_deductible_auto_type() => -6,
+            CXType_Auto if self.is_non_deductible_auto_type() => return -6,
             _ => unsafe { clang_Type_getAlignOf(self.x) },
         }
     }
@@ -1281,12 +1265,12 @@
         // nasty... But can happen in <type_traits>. Unfortunately I couldn't
         // reduce it enough :(
         self.template_args().map_or(false, |args| args.len() > 0) &&
-            !matches!(
-                self.declaration().kind(),
+            match self.declaration().kind() {
                 CXCursor_ClassTemplatePartialSpecialization |
-                    CXCursor_TypeAliasTemplateDecl |
-                    CXCursor_TemplateTemplateParameter
-            )
+                CXCursor_TypeAliasTemplateDecl |
+                CXCursor_TemplateTemplateParameter => false,
+                _ => true,
+            }
     }
 
     /// Is this type an associated template type? Eg `T::Associated` in
@@ -1401,12 +1385,6 @@
     }
 }
 
-impl fmt::Debug for SourceLocation {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{}", self)
-    }
-}
-
 /// A comment in the source text.
 ///
 /// Comments are sort of parsed by Clang, and have a tree structure.
@@ -1705,7 +1683,11 @@
             Contents: contents.as_ptr(),
             Length: contents.as_bytes().len() as c_ulong,
         };
-        UnsavedFile { x, name, contents }
+        UnsavedFile {
+            x: x,
+            name: name,
+            contents: contents,
+        }
     }
 }
 
@@ -1816,7 +1798,7 @@
 
         if let Some(refd) = c.referenced() {
             if refd != *c {
-                println!();
+                println!("");
                 print_cursor(
                     depth,
                     String::from(prefix) + "referenced.",
@@ -1827,7 +1809,7 @@
 
         let canonical = c.canonical();
         if canonical != *c {
-            println!();
+            println!("");
             print_cursor(
                 depth,
                 String::from(prefix) + "canonical.",
@@ -1837,7 +1819,7 @@
 
         if let Some(specialized) = c.specialized() {
             if specialized != *c {
-                println!();
+                println!("");
                 print_cursor(
                     depth,
                     String::from(prefix) + "specialized.",
@@ -1847,7 +1829,7 @@
         }
 
         if let Some(parent) = c.fallible_semantic_parent() {
-            println!();
+            println!("");
             print_cursor(
                 depth,
                 String::from(prefix) + "semantic-parent.",
@@ -1895,34 +1877,34 @@
 
         let canonical = ty.canonical_type();
         if canonical != *ty {
-            println!();
+            println!("");
             print_type(depth, String::from(prefix) + "canonical.", &canonical);
         }
 
         if let Some(pointee) = ty.pointee_type() {
             if pointee != *ty {
-                println!();
+                println!("");
                 print_type(depth, String::from(prefix) + "pointee.", &pointee);
             }
         }
 
         if let Some(elem) = ty.elem_type() {
             if elem != *ty {
-                println!();
+                println!("");
                 print_type(depth, String::from(prefix) + "elements.", &elem);
             }
         }
 
         if let Some(ret) = ty.ret_type() {
             if ret != *ty {
-                println!();
+                println!("");
                 print_type(depth, String::from(prefix) + "return.", &ret);
             }
         }
 
         let named = ty.named();
         if named != *ty && named.is_valid() {
-            println!();
+            println!("");
             print_type(depth, String::from(prefix) + "named.", &named);
         }
     }
@@ -1930,13 +1912,13 @@
     print_indent(depth, "(");
     print_cursor(depth, "", c);
 
-    println!();
+    println!("");
     let ty = c.cur_type();
     print_type(depth, "type.", &ty);
 
     let declaration = ty.declaration();
     if declaration != *c && declaration.kind() != CXCursor_NoDeclFound {
-        println!();
+        println!("");
         print_cursor(depth, "type.declaration.", &declaration);
     }
 
@@ -1944,7 +1926,7 @@
     let mut found_children = false;
     c.visit(|s| {
         if !found_children {
-            println!();
+            println!("");
             found_children = true;
         }
         ast_dump(&s, depth + 1)
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs
index 2ce6894..205995b 100644
--- a/src/codegen/helpers.rs
+++ b/src/codegen/helpers.rs
@@ -230,14 +230,14 @@
     }
 
     pub fn byte_array_expr(bytes: &[u8]) -> TokenStream {
-        let mut bytes: Vec<_> = bytes.to_vec();
+        let mut bytes: Vec<_> = bytes.iter().cloned().collect();
         bytes.push(0);
         quote! { [ #(#bytes),* ] }
     }
 
     pub fn cstr_expr(mut string: String) -> TokenStream {
         string.push('\0');
-        let b = proc_macro2::Literal::byte_string(string.as_bytes());
+        let b = proc_macro2::Literal::byte_string(&string.as_bytes());
         quote! {
             #b
         }
@@ -271,7 +271,7 @@
         }
 
         warn!("Unknown non-finite float number: {:?}", f);
-        Err(())
+        return Err(());
     }
 
     pub fn arguments_from_signature(
diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs
index 0e2cd33..b8fdd0d 100644
--- a/src/codegen/impl_debug.rs
+++ b/src/codegen/impl_debug.rs
@@ -2,6 +2,7 @@
 use crate::ir::context::BindgenContext;
 use crate::ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName};
 use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
+use proc_macro2;
 
 pub fn gen_debug_impl(
     ctx: &BindgenContext,
@@ -22,8 +23,8 @@
             }
             CompKind::Struct => {
                 let processed_fields = fields.iter().filter_map(|f| match f {
-                    Field::DataMember(ref fd) => fd.impl_debug(ctx, ()),
-                    Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()),
+                    &Field::DataMember(ref fd) => fd.impl_debug(ctx, ()),
+                    &Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()),
                 });
 
                 for (i, (fstring, toks)) in processed_fields.enumerate() {
@@ -180,27 +181,27 @@
                         format!("{}: Array with length {}", name, len),
                         vec![],
                     ))
-                } else if len < RUST_DERIVE_IN_ARRAY_LIMIT ||
-                    ctx.options().rust_features().larger_arrays
-                {
+                } else if len < RUST_DERIVE_IN_ARRAY_LIMIT {
                     // 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![]))
                 } 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>()
-                        }],
-                    ))
+                    if ctx.options().use_core {
+                        // There is no String in core; reducing field visibility to avoid breaking
+                        // no_std setups.
+                        Some((format!("{}: [...]", name), 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>()
+                            }],
+                        ))
+                    }
                 }
             }
             TypeKind::Vector(_, len) => {
diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs
index 960306f..5f2600e 100644
--- a/src/codegen/impl_partialeq.rs
+++ b/src/codegen/impl_partialeq.rs
@@ -2,6 +2,7 @@
 use crate::ir::context::BindgenContext;
 use crate::ir::item::{IsOpaque, Item};
 use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
+use proc_macro2;
 
 /// Generate a manual implementation of `PartialEq` trait for the
 /// specified compound type.
@@ -50,7 +51,7 @@
                 }
                 Field::Bitfields(ref bu) => {
                     for bitfield in bu.bitfields() {
-                        if bitfield.name().is_some() {
+                        if let Some(_) = bitfield.name() {
                             let getter_name = bitfield.getter_name();
                             let name_ident = ctx.rust_ident_raw(getter_name);
                             tokens.push(quote! {
@@ -103,7 +104,7 @@
         TypeKind::Opaque => quote_equals(name_ident),
 
         TypeKind::TemplateInstantiation(ref inst) => {
-            if inst.is_opaque(ctx, ty_item) {
+            if inst.is_opaque(ctx, &ty_item) {
                 quote! {
                     &self. #name_ident [..] == &other. #name_ident [..]
                 }
@@ -113,9 +114,7 @@
         }
 
         TypeKind::Array(_, len) => {
-            if len <= RUST_DERIVE_IN_ARRAY_LIMIT ||
-                ctx.options().rust_features().larger_arrays
-            {
+            if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
                 quote_equals(name_ident)
             } else {
                 quote! {
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 19886e3..e62b1a8 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -48,6 +48,7 @@
 use quote::TokenStreamExt;
 
 use crate::{Entry, HashMap, HashSet};
+use std;
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::collections::VecDeque;
@@ -57,7 +58,7 @@
 use std::str::FromStr;
 
 // Name of type defined in constified enum module
-pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &str = "Type";
+pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &'static str = "Type";
 
 fn top_level_path(
     ctx: &BindgenContext,
@@ -617,18 +618,12 @@
             return;
         }
 
-        let mut attrs = vec![];
-        if let Some(comment) = item.comment(ctx) {
-            attrs.push(attributes::doc(comment));
-        }
-
         let ty = self.ty().to_rust_ty_or_opaque(ctx, &());
 
         if let Some(val) = self.val() {
             match *val {
                 VarType::Bool(val) => {
                     result.push(quote! {
-                        #(#attrs)*
                         pub const #canonical_ident : #ty = #val ;
                     });
                 }
@@ -648,7 +643,6 @@
                         helpers::ast_ty::uint_expr(val as _)
                     };
                     result.push(quote! {
-                        #(#attrs)*
                         pub const #canonical_ident : #ty = #val ;
                     });
                 }
@@ -665,49 +659,37 @@
                     match String::from_utf8(bytes.clone()) {
                         Ok(string) => {
                             let cstr = helpers::ast_ty::cstr_expr(string);
-                            if ctx
-                                .options()
-                                .rust_features
-                                .static_lifetime_elision
-                            {
-                                result.push(quote! {
-                                    #(#attrs)*
-                                    pub const #canonical_ident : &#ty = #cstr ;
-                                });
-                            } else {
-                                result.push(quote! {
-                                    #(#attrs)*
-                                    pub const #canonical_ident : &'static #ty = #cstr ;
-                                });
-                            }
+                            result.push(quote! {
+                                pub const #canonical_ident : &'static #ty = #cstr ;
+                            });
                         }
                         Err(..) => {
                             let bytes = helpers::ast_ty::byte_array_expr(bytes);
                             result.push(quote! {
-                                #(#attrs)*
                                 pub const #canonical_ident : #ty = #bytes ;
                             });
                         }
                     }
                 }
                 VarType::Float(f) => {
-                    if let Ok(expr) = helpers::ast_ty::float_expr(ctx, f) {
-                        result.push(quote! {
-                            #(#attrs)*
+                    match helpers::ast_ty::float_expr(ctx, f) {
+                        Ok(expr) => result.push(quote! {
                             pub const #canonical_ident : #ty = #expr ;
-                        });
+                        }),
+                        Err(..) => return,
                     }
                 }
                 VarType::Char(c) => {
                     result.push(quote! {
-                        #(#attrs)*
                         pub const #canonical_ident : #ty = #c ;
                     });
                 }
             }
         } else {
+            let mut attrs = vec![];
+
             // If necessary, apply a `#[link_name]` attribute
-            let link_name = self.mangled_name().unwrap_or_else(|| self.name());
+            let link_name = self.mangled_name().unwrap_or(self.name());
             if !utils::names_will_be_identical_after_mangling(
                 &canonical_name,
                 link_name,
@@ -765,6 +747,7 @@
                 // converted to rust types in fields, arguments, and such.
                 // NOTE(emilio): If you add to this list, make sure to also add
                 // it to BindgenContext::compute_allowlisted_and_codegen_items.
+                return;
             }
             TypeKind::TemplateInstantiation(ref inst) => {
                 inst.codegen(ctx, result, item)
@@ -894,9 +877,12 @@
 
                 // We prefer using `pub use` over `pub type` because of:
                 // https://github.com/rust-lang/rust/issues/26264
-                // These are the only characters allowed in simple
-                // paths, eg `good::dogs::Bront`.
-                if inner_rust_type.to_string().chars().all(|c| matches!(c, 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ')) && outer_params.is_empty() &&
+                if inner_rust_type.to_string().chars().all(|c| match c {
+                    // These are the only characters allowed in simple
+                    // paths, eg `good::dogs::Bront`.
+                    'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ' => true,
+                    _ => false,
+                }) && outer_params.is_empty() &&
                     !is_opaque &&
                     alias_style == AliasVariation::TypeAlias &&
                     inner_item.expect_type().canonical_type(ctx).is_enum()
@@ -1507,10 +1493,7 @@
         let mut ctor_impl = quote! {};
 
         // We cannot generate any constructor if the underlying storage can't
-        // implement AsRef<[u8]> / AsMut<[u8]> / etc, or can't derive Default.
-        //
-        // We don't check `larger_arrays` here because Default does still have
-        // the 32 items limitation.
+        // implement AsRef<[u8]> / AsMut<[u8]> / etc.
         let mut generate_ctor = layout.size <= RUST_DERIVE_IN_ARRAY_LIMIT;
 
         let mut access_spec = !fields_should_be_private;
@@ -1520,9 +1503,7 @@
                 continue;
             }
 
-            if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT &&
-                !ctx.options().rust_features().larger_arrays
-            {
+            if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT {
                 continue;
             }
 
@@ -1772,7 +1753,7 @@
 
                 let inner_item = ctx.resolve_item(base.ty);
                 let mut inner = inner_item.to_rust_ty_or_opaque(ctx, &());
-                inner.append_implicit_template_params(ctx, inner_item);
+                inner.append_implicit_template_params(ctx, &inner_item);
                 let field_name = ctx.rust_ident(&base.field_name);
 
                 struct_layout.saw_base(inner_item.expect_type());
@@ -1807,14 +1788,6 @@
                     (),
                 );
             }
-            // Check whether an explicit padding field is needed
-            // at the end.
-            if let Some(comp_layout) = layout {
-                fields.extend(
-                    struct_layout
-                        .add_tail_padding(&canonical_name, comp_layout),
-                );
-            }
         }
 
         if is_opaque {
@@ -2015,24 +1988,10 @@
         let mut derives: Vec<_> = derivable_traits.into();
         derives.extend(item.annotations().derives().iter().map(String::as_str));
 
-        // The custom derives callback may return a list of derive attributes;
-        // add them to the end of the list.
-        let custom_derives;
-        if let Some(cb) = &ctx.options().parse_callbacks {
-            custom_derives = cb.add_derives(&canonical_name);
-            // 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()));
-        };
-
         if !derives.is_empty() {
             attributes.push(attributes::derives(&derives))
         }
 
-        if item.annotations().must_use_type() || ctx.must_use_type_by_name(item)
-        {
-            attributes.push(attributes::must_use());
-        }
-
         let mut tokens = if is_union && struct_layout.is_rust_union() {
             quote! {
                 #( #attributes )*
@@ -2131,11 +2090,11 @@
                                 })
                                 .flat_map(|field| {
                                     let name = field.name().unwrap();
-                                    field.offset().map(|offset| {
+                                    field.offset().and_then(|offset| {
                                         let field_offset = offset / 8;
                                         let field_name = ctx.rust_ident(name);
 
-                                        quote! {
+                                        Some(quote! {
                                             assert_eq!(
                                                 unsafe {
                                                     &(*(::#prefix::ptr::null::<#canonical_ident>())).#field_name as *const _ as usize
@@ -2143,7 +2102,7 @@
                                                 #field_offset,
                                                 concat!("Offset of field: ", stringify!(#canonical_ident), "::", stringify!(#field_name))
                                             );
-                                        }
+                                        })
                                     })
                                 })
                                 .collect::<Vec<proc_macro2::TokenStream>>();
@@ -2228,32 +2187,9 @@
 
         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()
-                    }
-                }
-            } 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
-            // involved.
             result.push(quote! {
                 impl #generics Default for #ty_for_impl {
-                    fn default() -> Self {
-                        #body
-                    }
+                    fn default() -> Self { unsafe { ::#prefix::mem::zeroed() } }
                 }
             });
         }
@@ -2353,7 +2289,7 @@
             return;
         }
         let function = function_item.expect_function();
-        let times_seen = function.codegen(ctx, result, function_item);
+        let times_seen = function.codegen(ctx, result, &function_item);
         let times_seen = match times_seen {
             Some(seen) => seen,
             None => return,
@@ -2419,7 +2355,7 @@
         }
 
         let mut exprs =
-            helpers::ast_ty::arguments_from_signature(signature, ctx);
+            helpers::ast_ty::arguments_from_signature(&signature, ctx);
 
         let mut stmts = vec![];
 
@@ -2476,7 +2412,8 @@
             #( #stmts );*
         };
 
-        let mut attrs = vec![attributes::inline()];
+        let mut attrs = vec![];
+        attrs.push(attributes::inline());
 
         if signature.must_use() &&
             ctx.options().rust_features().must_use_function
@@ -2517,13 +2454,19 @@
 
 impl EnumVariation {
     fn is_rust(&self) -> bool {
-        matches!(*self, EnumVariation::Rust { .. })
+        match *self {
+            EnumVariation::Rust { .. } => true,
+            _ => false,
+        }
     }
 
     /// Both the `Const` and `ModuleConsts` variants will cause this to return
     /// true.
     fn is_const(&self) -> bool {
-        matches!(*self, EnumVariation::Consts | EnumVariation::ModuleConsts)
+        match *self {
+            EnumVariation::Consts | EnumVariation::ModuleConsts => true,
+            _ => false,
+        }
     }
 }
 
@@ -2601,7 +2544,10 @@
 
     /// Returns true if the builder is for a rustified enum.
     fn is_rust_enum(&self) -> bool {
-        matches!(*self, EnumBuilder::Rust { .. })
+        match *self {
+            EnumBuilder::Rust { .. } => true,
+            _ => false,
+        }
     }
 
     /// Create a new enum given an item builder, a canonical name, a name for
@@ -2998,43 +2944,18 @@
             attrs.push(attributes::doc(comment));
         }
 
-        if item.annotations().must_use_type() || ctx.must_use_type_by_name(item)
-        {
-            attrs.push(attributes::must_use());
-        }
-
         if !variation.is_const() {
             let mut derives = derives_of_item(item, ctx);
-            // For backwards compat, enums always derive Debug/Clone/Eq/PartialEq/Hash, even
+            // For backwards compat, enums always derive Clone/Eq/PartialEq/Hash, even
             // if we don't generate those by default.
-            if !item.annotations().disallow_debug() {
-                derives.insert(DerivableTraits::DEBUG);
-            }
-            if !item.annotations().disallow_copy() {
-                derives.insert(DerivableTraits::COPY);
-            }
             derives.insert(
                 DerivableTraits::CLONE |
+                    DerivableTraits::COPY |
                     DerivableTraits::HASH |
                     DerivableTraits::PARTIAL_EQ |
                     DerivableTraits::EQ,
             );
-            let mut derives: Vec<_> = derives.into();
-            for derive in item.annotations().derives().iter() {
-                if !derives.contains(&derive.as_str()) {
-                    derives.push(derive);
-                }
-            }
-
-            // The custom derives callback may return a list of derive attributes;
-            // add them to the end of the list.
-            let custom_derives;
-            if let Some(cb) = &ctx.options().parse_callbacks {
-                custom_derives = cb.add_derives(&name);
-                // 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()));
-            };
-
+            let derives: Vec<_> = derives.into();
             attrs.push(attributes::derives(&derives));
         }
 
@@ -3092,7 +3013,7 @@
 
         let constant_mangling_prefix = if ctx.options().prepend_enum_name {
             if enum_ty.name().is_none() {
-                parent_canonical_name.as_deref()
+                parent_canonical_name.as_ref().map(|n| &**n)
             } else {
                 Some(&*name)
             }
@@ -3651,12 +3572,13 @@
                     let void = c_void(ctx);
                     return Ok(void.to_ptr(/* is_const = */ false));
                 }
+                let template_params = item
+                    .used_template_params(ctx)
+                    .into_iter()
+                    .filter(|param| param.is_template_param(ctx, &()))
+                    .collect::<Vec<_>>();
 
-                if item.is_opaque(ctx, &()) &&
-                    item.used_template_params(ctx)
-                        .into_iter()
-                        .any(|param| param.is_template_param(ctx, &()))
-                {
+                if item.is_opaque(ctx, &()) && !template_params.is_empty() {
                     self.try_to_opaque(ctx, item)
                 } else if let Some(ty) = self
                     .name()
@@ -3685,8 +3607,10 @@
                     inner.into_resolver().through_type_refs().resolve(ctx);
                 let inner_ty = inner.expect_type();
 
-                let is_objc_pointer =
-                    matches!(inner_ty.kind(), TypeKind::ObjCInterface(..));
+                let is_objc_pointer = match inner_ty.kind() {
+                    TypeKind::ObjCInterface(..) => true,
+                    _ => false,
+                };
 
                 // Regardless if we can properly represent the inner type, we
                 // should always generate a proper pointer here, so use
@@ -3819,8 +3743,8 @@
         _: &(),
     ) -> error::Result<proc_macro2::TokenStream> {
         // TODO: we might want to consider ignoring the reference return value.
-        let ret = utils::fnsig_return_ty(ctx, self);
-        let arguments = utils::fnsig_arguments(ctx, self);
+        let ret = utils::fnsig_return_ty(ctx, &self);
+        let arguments = utils::fnsig_arguments(ctx, &self);
         let abi = self.abi();
 
         match abi {
@@ -4062,12 +3986,12 @@
             impl_items.push(impl_item);
         }
 
+        let instance_method_names: Vec<_> =
+            self.methods().iter().map(|m| m.rust_name()).collect();
+
         for class_method in self.class_methods() {
-            let ambiquity = self
-                .methods()
-                .iter()
-                .map(|m| m.rust_name())
-                .any(|x| x == class_method.rust_name());
+            let ambiquity =
+                instance_method_names.contains(&class_method.rust_name());
             let prefix = if ambiquity { "class_" } else { "" };
             let impl_item = objc_method_codegen(
                 ctx,
@@ -4274,16 +4198,6 @@
             }
         }
 
-        if let Some(spec) = context.options().depfile.as_ref() {
-            match spec.write(context.deps()) {
-                Ok(()) => info!(
-                    "Your depfile was generated successfully into: {}",
-                    spec.depfile_path.display()
-                ),
-                Err(e) => warn!("{}", e),
-            }
-        }
-
         context.resolve_item(context.root_module()).codegen(
             context,
             &mut result,
@@ -4659,7 +4573,7 @@
                     TypeKind::Array(t, _) => {
                         let stream =
                             if ctx.options().array_pointers_in_arguments {
-                                arg_ty.to_rust_ty_or_opaque(ctx, arg_item)
+                                arg_ty.to_rust_ty_or_opaque(ctx, &arg_item)
                             } else {
                                 t.to_rust_ty_or_opaque(ctx, &())
                             };
diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs
index 657be0b..2e4b973 100644
--- a/src/codegen/struct_layout.rs
+++ b/src/codegen/struct_layout.rs
@@ -217,11 +217,8 @@
         let padding_layout = if self.is_packed || is_union {
             None
         } else {
-            let force_padding = self.ctx.options().force_explicit_padding;
-
             // Otherwise the padding is useless.
-            let need_padding = force_padding ||
-                padding_bytes >= field_layout.align ||
+            let need_padding = padding_bytes >= field_layout.align ||
                 field_layout.align > MAX_GUARANTEED_ALIGN;
 
             debug!(
@@ -239,14 +236,11 @@
                 field_layout
             );
 
-            let padding_align = if force_padding {
-                1
-            } else {
-                cmp::min(field_layout.align, MAX_GUARANTEED_ALIGN)
-            };
-
             if need_padding && padding_bytes != 0 {
-                Some(Layout::new(padding_bytes, padding_align))
+                Some(Layout::new(
+                    padding_bytes,
+                    cmp::min(field_layout.align, MAX_GUARANTEED_ALIGN),
+                ))
             } else {
                 None
             }
@@ -268,37 +262,6 @@
         padding_layout.map(|layout| self.padding_field(layout))
     }
 
-    pub fn add_tail_padding(
-        &mut self,
-        comp_name: &str,
-        comp_layout: Layout,
-    ) -> Option<proc_macro2::TokenStream> {
-        // Only emit an padding field at the end of a struct if the
-        // user configures explicit padding.
-        if !self.ctx.options().force_explicit_padding {
-            return None;
-        }
-
-        // Padding doesn't make sense for rust unions.
-        if self.is_rust_union {
-            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,
-            self.latest_offset,
-            comp_layout.size
-        );
-        let size = comp_layout.size - self.latest_offset;
-        Some(self.padding_field(Layout::new(size, 0)))
-    }
-
     pub fn pad_struct(
         &mut self,
         layout: Layout,
@@ -433,6 +396,6 @@
 
         // Else, just align the obvious way.
         self.latest_offset += self.padding_bytes(layout);
-        false
+        return false;
     }
 }
diff --git a/src/deps.rs b/src/deps.rs
deleted file mode 100644
index 479c396..0000000
--- a/src/deps.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-/// Generating build depfiles from parsed bindings.
-use std::{collections::BTreeSet, path::PathBuf};
-
-#[derive(Debug)]
-pub(crate) struct DepfileSpec {
-    pub output_module: String,
-    pub depfile_path: PathBuf,
-}
-
-impl DepfileSpec {
-    pub fn write(&self, deps: &BTreeSet<String>) -> std::io::Result<()> {
-        let mut buf = format!("{}:", self.output_module);
-
-        for file in deps {
-            buf = format!("{} {}", buf, file);
-        }
-
-        std::fs::write(&self.depfile_path, &buf)
-    }
-}
diff --git a/src/features.rs b/src/features.rs
index a786f07..4ec9dee 100644
--- a/src/features.rs
+++ b/src/features.rs
@@ -87,9 +87,8 @@
         $x_macro!(
             /// Rust stable 1.0
             => Stable_1_0 => 1.0;
-            /// Rust stable 1.17
-            ///  * Static lifetime elision ([RFC 1623](https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md))
-            => Stable_1_17 => 1.17;
+            /// Rust stable 1.1
+            => Stable_1_1 => 1.1;
             /// Rust stable 1.19
             ///  * Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md))
             => Stable_1_19 => 1.19;
@@ -124,9 +123,6 @@
             /// Rust stable 1.40
             /// * `non_exhaustive` enums/structs ([Tracking issue](https://github.com/rust-lang/rust/issues/44109))
             => Stable_1_40 => 1.40;
-            /// Rust stable 1.47
-            /// * `larger_arrays` ([Tracking issue](https://github.com/rust-lang/rust/pull/74060))
-            => Stable_1_47 => 1.47;
             /// Nightly rust
             ///  * `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202))
             => Nightly => nightly;
@@ -138,7 +134,7 @@
 rust_target_base!(rust_target_values_def);
 
 /// Latest stable release of Rust
-pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_47;
+pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_40;
 
 /// Create RustFeatures struct definition, new(), and a getter for each field
 macro_rules! rust_feature_def {
@@ -192,9 +188,6 @@
 // documentation for the relevant variant in the rust_target_base macro
 // definition.
 rust_feature_def!(
-    Stable_1_17 {
-        => static_lifetime_elision;
-    }
     Stable_1_19 {
         => untagged_union;
     }
@@ -229,9 +222,6 @@
     Stable_1_40 {
         => non_exhaustive;
     }
-    Stable_1_47 {
-        => larger_arrays;
-    }
     Nightly {
         => thiscall_abi;
     }
@@ -253,8 +243,7 @@
     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.core_ffi_c_void &&
                 !f_1_0.untagged_union &&
                 !f_1_0.associated_const &&
                 !f_1_0.builtin_clone_impls &&
@@ -263,8 +252,7 @@
         );
         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.core_ffi_c_void &&
                 f_1_21.untagged_union &&
                 f_1_21.associated_const &&
                 f_1_21.builtin_clone_impls &&
@@ -273,8 +261,7 @@
         );
         let f_nightly = RustFeatures::from(RustTarget::Nightly);
         assert!(
-            f_nightly.static_lifetime_elision &&
-                f_nightly.core_ffi_c_void &&
+            f_nightly.core_ffi_c_void &&
                 f_nightly.untagged_union &&
                 f_nightly.associated_const &&
                 f_nightly.builtin_clone_impls &&
@@ -293,7 +280,6 @@
     #[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);
diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs
index f63458e..be62666 100644
--- a/src/ir/analysis/derive.rs
+++ b/src/ir/analysis/derive.rs
@@ -9,7 +9,6 @@
 use crate::ir::derive::CanDerive;
 use crate::ir::function::FunctionSig;
 use crate::ir::item::{IsOpaque, Item};
-use crate::ir::layout::Layout;
 use crate::ir::template::TemplateParameters;
 use crate::ir::traversal::{EdgeKind, Trace};
 use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
@@ -160,7 +159,7 @@
             return can_derive;
         }
 
-        if self.derive_trait.not_by_name(self.ctx, item) {
+        if self.derive_trait.not_by_name(self.ctx, &item) {
             trace!(
                 "    cannot derive {} for explicitly excluded type",
                 self.derive_trait
@@ -224,13 +223,13 @@
                 let inner_type =
                     self.ctx.resolve_type(inner).canonical_type(self.ctx);
                 if let TypeKind::Function(ref sig) = *inner_type.kind() {
-                    self.derive_trait.can_derive_fnptr(sig)
+                    return self.derive_trait.can_derive_fnptr(sig);
                 } else {
-                    self.derive_trait.can_derive_pointer()
+                    return self.derive_trait.can_derive_pointer();
                 }
             }
             TypeKind::Function(ref sig) => {
-                self.derive_trait.can_derive_fnptr(sig)
+                return self.derive_trait.can_derive_fnptr(sig)
             }
 
             // Complex cases need more information
@@ -256,7 +255,7 @@
                     return CanDerive::No;
                 }
 
-                if self.derive_trait.can_derive_large_array(self.ctx) {
+                if self.derive_trait.can_derive_large_array() {
                     trace!("    array can derive {}", self.derive_trait);
                     return CanDerive::Yes;
                 }
@@ -271,7 +270,7 @@
                     "    array is small enough to derive {}",
                     self.derive_trait
                 );
-                CanDerive::Yes
+                return CanDerive::Yes;
             }
             TypeKind::Vector(t, len) => {
                 let inner_type =
@@ -286,7 +285,7 @@
                     return CanDerive::No;
                 }
                 assert_ne!(len, 0, "vectors cannot have zero length");
-                self.derive_trait.can_derive_vector()
+                return self.derive_trait.can_derive_vector();
             }
 
             TypeKind::Comp(ref info) => {
@@ -378,7 +377,7 @@
                 // Bitfield units are always represented as arrays of u8, but
                 // they're not traced as arrays, so we need to check here
                 // instead.
-                if !self.derive_trait.can_derive_large_array(self.ctx) &&
+                if !self.derive_trait.can_derive_large_array() &&
                     info.has_too_large_bitfield_unit() &&
                     !item.is_opaque(self.ctx, &())
                 {
@@ -390,7 +389,7 @@
                 }
 
                 let pred = self.derive_trait.consider_edge_comp();
-                self.constrain_join(item, pred)
+                return self.constrain_join(item, pred);
             }
 
             TypeKind::ResolvedTypeRef(..) |
@@ -398,12 +397,12 @@
             TypeKind::Alias(..) |
             TypeKind::BlockPointer(..) => {
                 let pred = self.derive_trait.consider_edge_typeref();
-                self.constrain_join(item, pred)
+                return self.constrain_join(item, pred);
             }
 
             TypeKind::TemplateInstantiation(..) => {
                 let pred = self.derive_trait.consider_edge_tmpl_inst();
-                self.constrain_join(item, pred)
+                return self.constrain_join(item, pred);
             }
 
             TypeKind::Opaque => unreachable!(
@@ -471,7 +470,10 @@
     fn consider_edge_comp(&self) -> EdgePredicate {
         match self {
             DeriveTrait::PartialEqOrPartialOrd => consider_edge_default,
-            _ => |kind| matches!(kind, EdgeKind::BaseMember | EdgeKind::Field),
+            _ => |kind| match kind {
+                EdgeKind::BaseMember | EdgeKind::Field => true,
+                _ => false,
+            },
         }
     }
 
@@ -494,37 +496,48 @@
         }
     }
 
-    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) -> bool {
+        match self {
+            DeriveTrait::Copy => true,
+            _ => false,
         }
     }
 
     fn can_derive_union(&self) -> bool {
-        matches!(self, DeriveTrait::Copy)
+        match self {
+            DeriveTrait::Copy => true,
+            _ => false,
+        }
     }
 
     fn can_derive_compound_with_destructor(&self) -> bool {
-        !matches!(self, DeriveTrait::Copy)
+        match self {
+            DeriveTrait::Copy => false,
+            _ => true,
+        }
     }
 
     fn can_derive_compound_with_vtable(&self) -> bool {
-        !matches!(self, DeriveTrait::Default)
+        match self {
+            DeriveTrait::Default => false,
+            _ => true,
+        }
     }
 
     fn can_derive_compound_forward_decl(&self) -> bool {
-        matches!(self, DeriveTrait::Copy | DeriveTrait::Debug)
+        match self {
+            DeriveTrait::Copy | DeriveTrait::Debug => true,
+            _ => false,
+        }
     }
 
     fn can_derive_incomplete_array(&self) -> bool {
-        !matches!(
-            self,
+        match self {
             DeriveTrait::Copy |
-                DeriveTrait::Hash |
-                DeriveTrait::PartialEqOrPartialOrd
-        )
+            DeriveTrait::Hash |
+            DeriveTrait::PartialEqOrPartialOrd => false,
+            _ => true,
+        }
     }
 
     fn can_derive_fnptr(&self, f: &FunctionSig) -> CanDerive {
@@ -673,10 +686,10 @@
             Some(ty) => {
                 let mut can_derive = self.constrain_type(item, ty);
                 if let CanDerive::Yes = can_derive {
-                    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)
+                    if !self.derive_trait.can_derive_large_array() &&
+                        ty.layout(self.ctx).map_or(false, |l| {
+                            l.align > RUST_DERIVE_IN_ARRAY_LIMIT
+                        })
                     {
                         // We have to be conservative: the struct *could* have enough
                         // padding that we emit an array that is longer than
diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs
index 74fd73d..5fa22e3 100644
--- a/src/ir/analysis/has_destructor.rs
+++ b/src/ir/analysis/has_destructor.rs
@@ -41,16 +41,16 @@
 
 impl<'ctx> HasDestructorAnalysis<'ctx> {
     fn consider_edge(kind: EdgeKind) -> bool {
-        // These are the only edges that can affect whether a type has a
-        // destructor or not.
-        matches!(
-            kind,
+        match kind {
+            // These are the only edges that can affect whether a type has a
+            // destructor or not.
             EdgeKind::TypeReference |
-                EdgeKind::BaseMember |
-                EdgeKind::Field |
-                EdgeKind::TemplateArgument |
-                EdgeKind::TemplateDeclaration
-        )
+            EdgeKind::BaseMember |
+            EdgeKind::Field |
+            EdgeKind::TemplateArgument |
+            EdgeKind::TemplateDeclaration => true,
+            _ => false,
+        }
     }
 
     fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs
index 8ac47a6..7f5f911 100644
--- a/src/ir/analysis/has_vtable.rs
+++ b/src/ir/analysis/has_vtable.rs
@@ -79,14 +79,14 @@
 
 impl<'ctx> HasVtableAnalysis<'ctx> {
     fn consider_edge(kind: EdgeKind) -> bool {
-        // These are the only edges that can affect whether a type has a
-        // vtable or not.
-        matches!(
-            kind,
+        match kind {
+            // These are the only edges that can affect whether a type has a
+            // vtable or not.
             EdgeKind::TypeReference |
-                EdgeKind::BaseMember |
-                EdgeKind::TemplateDeclaration
-        )
+            EdgeKind::BaseMember |
+            EdgeKind::TemplateDeclaration => true,
+            _ => false,
+        }
     }
 
     fn insert<Id: Into<ItemId>>(
diff --git a/src/ir/analysis/mod.rs b/src/ir/analysis/mod.rs
index eb9a1c0..ec4d20f 100644
--- a/src/ir/analysis/mod.rs
+++ b/src/ir/analysis/mod.rs
@@ -184,7 +184,7 @@
     let mut dependencies = HashMap::default();
 
     for &item in ctx.allowlisted_items() {
-        dependencies.entry(item).or_insert_with(Vec::new);
+        dependencies.entry(item).or_insert(vec![]);
 
         {
             // We reverse our natural IR graph edges to find dependencies
@@ -197,7 +197,7 @@
                     {
                         dependencies
                             .entry(sub_item)
-                            .or_insert_with(Vec::new)
+                            .or_insert(vec![])
                             .push(item);
                     }
                 },
diff --git a/src/ir/analysis/sizedness.rs b/src/ir/analysis/sizedness.rs
index 251c374..a3ef753 100644
--- a/src/ir/analysis/sizedness.rs
+++ b/src/ir/analysis/sizedness.rs
@@ -112,17 +112,17 @@
 
 impl<'ctx> SizednessAnalysis<'ctx> {
     fn consider_edge(kind: EdgeKind) -> bool {
-        // These are the only edges that can affect whether a type is
-        // zero-sized or not.
-        matches!(
-            kind,
+        match kind {
+            // These are the only edges that can affect whether a type is
+            // zero-sized or not.
             EdgeKind::TemplateArgument |
-                EdgeKind::TemplateParameterDefinition |
-                EdgeKind::TemplateDeclaration |
-                EdgeKind::TypeReference |
-                EdgeKind::BaseMember |
-                EdgeKind::Field
-        )
+            EdgeKind::TemplateParameterDefinition |
+            EdgeKind::TemplateDeclaration |
+            EdgeKind::TypeReference |
+            EdgeKind::BaseMember |
+            EdgeKind::Field => true,
+            _ => false,
+        }
     }
 
     /// Insert an incremental result, and return whether this updated our
diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs
index e88b774..c2f18b1 100644
--- a/src/ir/analysis/template_params.rs
+++ b/src/ir/analysis/template_params.rs
@@ -239,7 +239,7 @@
 
         let args = instantiation
             .template_arguments()
-            .iter()
+            .into_iter()
             .map(|a| {
                 a.into_resolver()
                     .through_type_refs()
@@ -399,8 +399,8 @@
             .collect();
 
         for item in allowlisted_and_blocklisted_items {
-            dependencies.entry(item).or_insert_with(Vec::new);
-            used.entry(item).or_insert_with(|| Some(ItemSet::new()));
+            dependencies.entry(item).or_insert(vec![]);
+            used.entry(item).or_insert(Some(ItemSet::new()));
 
             {
                 // We reverse our natural IR graph edges to find dependencies
@@ -408,11 +408,10 @@
                 item.trace(
                     ctx,
                     &mut |sub_item: ItemId, _| {
-                        used.entry(sub_item)
-                            .or_insert_with(|| Some(ItemSet::new()));
+                        used.entry(sub_item).or_insert(Some(ItemSet::new()));
                         dependencies
                             .entry(sub_item)
-                            .or_insert_with(Vec::new)
+                            .or_insert(vec![])
                             .push(item);
                     },
                     &(),
@@ -422,42 +421,39 @@
             // Additionally, whether a template instantiation's template
             // arguments are used depends on whether the template declaration's
             // generic template parameters are used.
-            let item_kind =
-                ctx.resolve_item(item).as_type().map(|ty| ty.kind());
-            if let Some(&TypeKind::TemplateInstantiation(ref inst)) = item_kind
-            {
-                let decl = ctx.resolve_type(inst.template_definition());
-                let args = inst.template_arguments();
+            ctx.resolve_item(item).as_type().map(|ty| match ty.kind() {
+                &TypeKind::TemplateInstantiation(ref inst) => {
+                    let decl = ctx.resolve_type(inst.template_definition());
+                    let args = inst.template_arguments();
 
-                // Although template definitions should always have
-                // template parameters, there is a single exception:
-                // opaque templates. Hence the unwrap_or.
-                let params = decl.self_template_params(ctx);
+                    // Although template definitions should always have
+                    // template parameters, there is a single exception:
+                    // opaque templates. Hence the unwrap_or.
+                    let params = decl.self_template_params(ctx);
 
-                for (arg, param) in args.iter().zip(params.iter()) {
-                    let arg = arg
-                        .into_resolver()
-                        .through_type_aliases()
-                        .through_type_refs()
-                        .resolve(ctx)
-                        .id();
+                    for (arg, param) in args.iter().zip(params.iter()) {
+                        let arg = arg
+                            .into_resolver()
+                            .through_type_aliases()
+                            .through_type_refs()
+                            .resolve(ctx)
+                            .id();
 
-                    let param = param
-                        .into_resolver()
-                        .through_type_aliases()
-                        .through_type_refs()
-                        .resolve(ctx)
-                        .id();
+                        let param = param
+                            .into_resolver()
+                            .through_type_aliases()
+                            .through_type_refs()
+                            .resolve(ctx)
+                            .id();
 
-                    used.entry(arg).or_insert_with(|| Some(ItemSet::new()));
-                    used.entry(param).or_insert_with(|| Some(ItemSet::new()));
+                        used.entry(arg).or_insert(Some(ItemSet::new()));
+                        used.entry(param).or_insert(Some(ItemSet::new()));
 
-                    dependencies
-                        .entry(arg)
-                        .or_insert_with(Vec::new)
-                        .push(param);
+                        dependencies.entry(arg).or_insert(vec![]).push(param);
+                    }
                 }
-            }
+                _ => {}
+            });
         }
 
         if cfg!(feature = "testing_only_extra_assertions") {
@@ -486,10 +482,10 @@
         }
 
         UsedTemplateParameters {
-            ctx,
-            used,
-            dependencies,
-            allowlisted_items,
+            ctx: ctx,
+            used: used,
+            dependencies: dependencies,
+            allowlisted_items: allowlisted_items,
         }
     }
 
diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs
index 9bcda50..12664f6 100644
--- a/src/ir/annotations.rs
+++ b/src/ir/annotations.rs
@@ -25,7 +25,7 @@
 /// documentation:
 ///
 /// http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html
-#[derive(Default, Clone, PartialEq, Debug)]
+#[derive(Clone, PartialEq, Debug)]
 pub struct Annotations {
     /// Whether this item is marked as opaque. Only applies to types.
     opaque: bool,
@@ -42,8 +42,6 @@
     disallow_debug: bool,
     /// Manually disable deriving/implement default on this type.
     disallow_default: bool,
-    /// Whether to add a #[must_use] annotation to this type.
-    must_use_type: bool,
     /// Whether fields should be marked as private or not. You can set this on
     /// structs (it will apply to all the fields), or individual fields.
     private_fields: Option<bool>,
@@ -77,6 +75,23 @@
     }
 }
 
+impl Default for Annotations {
+    fn default() -> Self {
+        Annotations {
+            opaque: false,
+            hide: false,
+            use_instead_of: None,
+            disallow_copy: false,
+            disallow_debug: false,
+            disallow_default: false,
+            private_fields: None,
+            accessor_kind: None,
+            constify_enum_variant: false,
+            derives: vec![],
+        }
+    }
+}
+
 impl Annotations {
     /// Construct new annotations for the given cursor and its bindgen comments
     /// (if any).
@@ -125,7 +140,7 @@
     ///
     /// That is, code for `Foo` is used to generate `Bar`.
     pub fn use_instead_of(&self) -> Option<&[String]> {
-        self.use_instead_of.as_deref()
+        self.use_instead_of.as_ref().map(|s| &**s)
     }
 
     /// The list of derives that have been specified in this annotation.
@@ -148,11 +163,6 @@
         self.disallow_default
     }
 
-    /// Should this type get a `#[must_use]` annotation?
-    pub fn must_use_type(&self) -> bool {
-        self.must_use_type
-    }
-
     /// Should the fields be private?
     pub fn private_fields(&self) -> Option<bool> {
         self.private_fields
@@ -180,7 +190,6 @@
                     "nocopy" => self.disallow_copy = true,
                     "nodebug" => self.disallow_debug = true,
                     "nodefault" => self.disallow_default = true,
-                    "mustusetype" => self.must_use_type = true,
                     "replaces" => {
                         self.use_instead_of = Some(
                             attr.value.split("::").map(Into::into).collect(),
diff --git a/src/ir/comment.rs b/src/ir/comment.rs
index c96e3eb..4ebe19a 100644
--- a/src/ir/comment.rs
+++ b/src/ir/comment.rs
@@ -1,5 +1,7 @@
 //! Utilities for manipulating C/C++ comments.
 
+use std::iter;
+
 /// The type of a comment.
 #[derive(Debug, PartialEq, Eq)]
 enum Kind {
@@ -13,7 +15,7 @@
 
 /// Preprocesses a C/C++ comment so that it is a valid Rust comment.
 pub fn preprocess(comment: &str, indent: usize) -> String {
-    match self::kind(comment) {
+    match self::kind(&comment) {
         Some(Kind::SingleLines) => preprocess_single_lines(comment, indent),
         Some(Kind::MultiLine) => preprocess_multi_line(comment, indent),
         None => comment.to_owned(),
@@ -33,7 +35,7 @@
 
 fn make_indent(indent: usize) -> String {
     const RUST_INDENTATION: usize = 4;
-    " ".repeat(indent * RUST_INDENTATION)
+    iter::repeat(' ').take(indent * RUST_INDENTATION).collect()
 }
 
 /// Preprocesses multiple single line comments.
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index a221e52..52dcddd 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -111,10 +111,11 @@
 
     /// Is this a virtual method?
     pub fn is_virtual(&self) -> bool {
-        matches!(
-            self.kind,
-            MethodKind::Virtual { .. } | MethodKind::VirtualDestructor { .. }
-        )
+        match self.kind {
+            MethodKind::Virtual { .. } |
+            MethodKind::VirtualDestructor { .. } => true,
+            _ => false,
+        }
     }
 
     /// Is this a static method?
@@ -629,7 +630,7 @@
                         bitfield_unit_count,
                         unit_size_in_bits,
                         unit_align,
-                        mem::take(&mut bitfields_in_unit),
+                        mem::replace(&mut bitfields_in_unit, vec![]),
                         packed,
                     );
 
@@ -638,12 +639,15 @@
                     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);
+            } else {
+                if offset != 0 &&
+                    (bitfield_width == 0 ||
+                        (offset & (bitfield_align * 8 - 1)) +
+                            bitfield_width >
+                            bitfield_size * 8)
+                {
+                    offset = align_to(offset, bitfield_align * 8);
+                }
             }
         }
 
@@ -702,24 +706,24 @@
 /// after.
 #[derive(Debug)]
 enum CompFields {
-    Before(Vec<RawField>),
-    After {
+    BeforeComputingBitfieldUnits(Vec<RawField>),
+    AfterComputingBitfieldUnits {
         fields: Vec<Field>,
         has_bitfield_units: bool,
     },
-    Error,
+    ErrorComputingBitfieldUnits,
 }
 
 impl Default for CompFields {
     fn default() -> CompFields {
-        CompFields::Before(vec![])
+        CompFields::BeforeComputingBitfieldUnits(vec![])
     }
 }
 
 impl CompFields {
     fn append_raw_field(&mut self, raw: RawField) {
         match *self {
-            CompFields::Before(ref mut raws) => {
+            CompFields::BeforeComputingBitfieldUnits(ref mut raws) => {
                 raws.push(raw);
             }
             _ => {
@@ -732,7 +736,9 @@
 
     fn compute_bitfield_units(&mut self, ctx: &BindgenContext, packed: bool) {
         let raws = match *self {
-            CompFields::Before(ref mut raws) => mem::take(raws),
+            CompFields::BeforeComputingBitfieldUnits(ref mut raws) => {
+                mem::replace(raws, vec![])
+            }
             _ => {
                 panic!("Already computed bitfield units");
             }
@@ -742,23 +748,25 @@
 
         match result {
             Ok((fields, has_bitfield_units)) => {
-                *self = CompFields::After {
+                *self = CompFields::AfterComputingBitfieldUnits {
                     fields,
                     has_bitfield_units,
                 };
             }
             Err(()) => {
-                *self = CompFields::Error;
+                *self = CompFields::ErrorComputingBitfieldUnits;
             }
         }
     }
 
     fn deanonymize_fields(&mut self, ctx: &BindgenContext, methods: &[Method]) {
         let fields = match *self {
-            CompFields::After { ref mut fields, .. } => fields,
+            CompFields::AfterComputingBitfieldUnits {
+                ref mut fields, ..
+            } => fields,
             // Nothing to do here.
-            CompFields::Error => return,
-            CompFields::Before(_) => {
+            CompFields::ErrorComputingBitfieldUnits => return,
+            CompFields::BeforeComputingBitfieldUnits(_) => {
                 panic!("Not yet computed bitfield units.");
             }
         };
@@ -770,7 +778,7 @@
         ) -> bool {
             methods.iter().any(|method| {
                 let method_name = ctx.resolve_func(method.signature()).name();
-                method_name == name || ctx.rust_mangle(method_name) == name
+                method_name == name || ctx.rust_mangle(&method_name) == name
             })
         }
 
@@ -812,7 +820,7 @@
         for field in fields.iter_mut() {
             match *field {
                 Field::DataMember(FieldData { ref mut name, .. }) => {
-                    if name.is_some() {
+                    if let Some(_) = *name {
                         continue;
                     }
 
@@ -850,13 +858,13 @@
         T: Tracer,
     {
         match *self {
-            CompFields::Error => {}
-            CompFields::Before(ref fields) => {
+            CompFields::ErrorComputingBitfieldUnits => {}
+            CompFields::BeforeComputingBitfieldUnits(ref fields) => {
                 for f in fields {
                     tracer.visit_kind(f.ty().into(), EdgeKind::Field);
                 }
             }
-            CompFields::After { ref fields, .. } => {
+            CompFields::AfterComputingBitfieldUnits { ref fields, .. } => {
                 for f in fields {
                     f.trace(context, tracer, &());
                 }
@@ -892,7 +900,7 @@
 
 impl FieldMethods for FieldData {
     fn name(&self) -> Option<&str> {
-        self.name.as_deref()
+        self.name.as_ref().map(|n| &**n)
     }
 
     fn ty(&self) -> TypeId {
@@ -900,7 +908,7 @@
     }
 
     fn comment(&self) -> Option<&str> {
-        self.comment.as_deref()
+        self.comment.as_ref().map(|c| &**c)
     }
 
     fn bitfield_width(&self) -> Option<u32> {
@@ -1105,17 +1113,21 @@
         }
 
         // empty union case
-        if !self.has_fields() {
+        if self.fields().is_empty() {
             return None;
         }
 
         let mut max_size = 0;
         // Don't allow align(0)
         let mut max_align = 1;
-        self.each_known_field_layout(ctx, |layout| {
-            max_size = cmp::max(max_size, layout.size);
-            max_align = cmp::max(max_align, layout.align);
-        });
+        for field in self.fields() {
+            let field_layout = field.layout(ctx);
+
+            if let Some(layout) = field_layout {
+                max_size = cmp::max(max_size, layout.size);
+                max_align = cmp::max(max_align, layout.align);
+            }
+        }
 
         Some(Layout::new(max_size, max_align))
     }
@@ -1123,54 +1135,24 @@
     /// Get this type's set of fields.
     pub fn fields(&self) -> &[Field] {
         match self.fields {
-            CompFields::Error => &[],
-            CompFields::After { ref fields, .. } => fields,
-            CompFields::Before(..) => {
+            CompFields::ErrorComputingBitfieldUnits => &[],
+            CompFields::AfterComputingBitfieldUnits { ref fields, .. } => {
+                fields
+            }
+            CompFields::BeforeComputingBitfieldUnits(_) => {
                 panic!("Should always have computed bitfield units first");
             }
         }
     }
 
-    fn has_fields(&self) -> bool {
-        match self.fields {
-            CompFields::Error => false,
-            CompFields::After { ref fields, .. } => !fields.is_empty(),
-            CompFields::Before(ref raw_fields) => !raw_fields.is_empty(),
-        }
-    }
-
-    fn each_known_field_layout(
-        &self,
-        ctx: &BindgenContext,
-        mut callback: impl FnMut(Layout),
-    ) {
-        match self.fields {
-            CompFields::Error => {}
-            CompFields::After { ref fields, .. } => {
-                for field in fields.iter() {
-                    if let Some(layout) = field.layout(ctx) {
-                        callback(layout);
-                    }
-                }
-            }
-            CompFields::Before(ref raw_fields) => {
-                for field in raw_fields.iter() {
-                    let field_ty = ctx.resolve_type(field.0.ty);
-                    if let Some(layout) = field_ty.layout(ctx) {
-                        callback(layout);
-                    }
-                }
-            }
-        }
-    }
-
     fn has_bitfields(&self) -> bool {
         match self.fields {
-            CompFields::Error => false,
-            CompFields::After {
-                has_bitfield_units, ..
+            CompFields::ErrorComputingBitfieldUnits => false,
+            CompFields::AfterComputingBitfieldUnits {
+                has_bitfield_units,
+                ..
             } => has_bitfield_units,
-            CompFields::Before(_) => {
+            CompFields::BeforeComputingBitfieldUnits(_) => {
                 panic!("Should always have computed bitfield units first");
             }
         }
@@ -1267,7 +1249,6 @@
         let mut ci = CompInfo::new(kind);
         ci.is_forward_declaration =
             location.map_or(true, |cur| match cur.kind() {
-                CXCursor_ParmDecl => true,
                 CXCursor_StructDecl | CXCursor_UnionDecl |
                 CXCursor_ClassDecl => !cur.is_definition(),
                 _ => false,
@@ -1393,26 +1374,21 @@
                     let inner = Item::parse(cur, Some(potential_id), ctx)
                         .expect("Inner ClassDecl");
 
-                    // If we avoided recursion parsing this type (in
-                    // `Item::from_ty_with_id()`), then this might not be a
-                    // valid type ID, so check and gracefully handle this.
-                    if ctx.resolve_item_fallible(inner).is_some() {
-                        let inner = inner.expect_type_id(ctx);
+                    let inner = inner.expect_type_id(ctx);
 
-                        ci.inner_types.push(inner);
+                    ci.inner_types.push(inner);
 
-                        // A declaration of an union or a struct without name
-                        // could also be an unnamed field, unfortunately.
-                        if cur.spelling().is_empty() &&
-                            cur.kind() != CXCursor_EnumDecl
-                        {
-                            let ty = cur.cur_type();
-                            let public = cur.public_accessible();
-                            let offset = cur.offset_of_field().ok();
+                    // A declaration of an union or a struct without name could
+                    // also be an unnamed field, unfortunately.
+                    if cur.spelling().is_empty() &&
+                        cur.kind() != CXCursor_EnumDecl
+                    {
+                        let ty = cur.cur_type();
+                        let public = cur.public_accessible();
+                        let offset = cur.offset_of_field().ok();
 
-                            maybe_anonymous_struct_field =
-                                Some((inner, ty, public, offset));
-                        }
+                        maybe_anonymous_struct_field =
+                            Some((inner, ty, public, offset));
                     }
                 }
                 CXCursor_PackedAttr => {
@@ -1621,17 +1597,23 @@
         // Even though `libclang` doesn't expose `#pragma packed(...)`, we can
         // detect it through its effects.
         if let Some(parent_layout) = layout {
-            let mut packed = false;
-            self.each_known_field_layout(ctx, |layout| {
-                packed = packed || layout.align > parent_layout.align;
-            });
-            if packed {
+            if self.fields().iter().any(|f| match *f {
+                Field::Bitfields(ref unit) => {
+                    unit.layout().align > parent_layout.align
+                }
+                Field::DataMember(ref data) => {
+                    let field_ty = ctx.resolve_type(data.ty());
+                    field_ty.layout(ctx).map_or(false, |field_ty_layout| {
+                        field_ty_layout.align > parent_layout.align
+                    })
+                }
+            }) {
                 info!("Found a struct that was defined within `#pragma packed(...)`");
                 return true;
-            }
-
-            if self.has_own_virtual_method && parent_layout.align == 1 {
-                return true;
+            } else if self.has_own_virtual_method {
+                if parent_layout.align == 1 {
+                    return true;
+                }
             }
         }
 
@@ -1644,13 +1626,10 @@
     }
 
     /// Compute this compound structure's bitfield allocation units.
-    pub fn compute_bitfield_units(
-        &mut self,
-        ctx: &BindgenContext,
-        layout: Option<&Layout>,
-    ) {
-        let packed = self.is_packed(ctx, layout);
-        self.fields.compute_bitfield_units(ctx, packed)
+    pub fn compute_bitfield_units(&mut self, ctx: &BindgenContext) {
+        // TODO(emilio): If we could detect #pragma packed here we'd fix layout
+        // tests in divide-by-zero-in-struct-layout.rs
+        self.fields.compute_bitfield_units(ctx, self.packed_attr)
     }
 
     /// Assign for each anonymous field a generated name.
@@ -1761,7 +1740,7 @@
         // is a type parameter), then we can't compute bitfield units. We are
         // left with no choice but to make the whole struct opaque, or else we
         // might generate structs with incorrect sizes and alignments.
-        if let CompFields::Error = self.fields {
+        if let CompFields::ErrorComputingBitfieldUnits = self.fields {
             return true;
         }
 
diff --git a/src/ir/context.rs b/src/ir/context.rs
index a9e19fb..ccb05e7 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -29,7 +29,7 @@
 use proc_macro2::{Ident, Span};
 use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
-use std::collections::{BTreeSet, HashMap as StdHashMap};
+use std::collections::HashMap as StdHashMap;
 use std::iter::IntoIterator;
 use std::mem;
 
@@ -299,7 +299,7 @@
 /// types.
 #[derive(Eq, PartialEq, Hash, Debug)]
 enum TypeKey {
-    Usr(String),
+    USR(String),
     Declaration(Cursor),
 }
 
@@ -354,9 +354,6 @@
     /// This needs to be an std::HashMap because the cexpr API requires it.
     parsed_macros: StdHashMap<Vec<u8>, cexpr::expr::EvalResult>,
 
-    /// A set of all the included filenames.
-    deps: BTreeSet<String>,
-
     /// The active replacements collected from replaces="xxx" annotations.
     replacements: HashMap<Vec<String>, ItemId>,
 
@@ -548,16 +545,8 @@
         let root_module = Self::build_root_module(ItemId(0));
         let root_module_id = root_module.id().as_module_id_unchecked();
 
-        // depfiles need to include the explicitly listed headers too
-        let mut deps = BTreeSet::default();
-        if let Some(filename) = &options.input_header {
-            deps.insert(filename.clone());
-        }
-        deps.extend(options.extra_input_headers.iter().cloned());
-
         BindgenContext {
             items: vec![Some(root_module)],
-            deps,
             types: Default::default(),
             type_params: Default::default(),
             modules: Default::default(),
@@ -640,20 +629,7 @@
 
     /// Get the user-provided callbacks by reference, if any.
     pub fn parse_callbacks(&self) -> Option<&dyn ParseCallbacks> {
-        self.options().parse_callbacks.as_deref()
-    }
-
-    /// Add another path to the set of included files.
-    pub fn include_file(&mut self, filename: String) {
-        if let Some(cbs) = self.parse_callbacks() {
-            cbs.include_file(&filename);
-        }
-        self.deps.insert(filename);
-    }
-
-    /// Get any included files.
-    pub fn deps(&self) -> &BTreeSet<String> {
-        &self.deps
+        self.options().parse_callbacks.as_ref().map(|t| &**t)
     }
 
     /// Define a new item.
@@ -702,10 +678,8 @@
         // Unnamed items can have an USR, but they can't be referenced from
         // other sites explicitly and the USR can match if the unnamed items are
         // nested, so don't bother tracking them.
-        if !is_type || is_template_instantiation {
-            return;
-        }
-        if let Some(mut declaration) = declaration {
+        if is_type && !is_template_instantiation && declaration.is_some() {
+            let mut declaration = declaration.unwrap();
             if !declaration.is_valid() {
                 if let Some(location) = location {
                     if location.is_template_like() {
@@ -734,7 +708,7 @@
             let key = if is_unnamed {
                 TypeKey::Declaration(declaration)
             } else if let Some(usr) = declaration.usr() {
-                TypeKey::Usr(usr)
+                TypeKey::USR(usr)
             } else {
                 warn!(
                     "Valid declaration with no USR: {:?}, {:?}",
@@ -831,32 +805,31 @@
     // TODO: Move all this syntax crap to other part of the code.
 
     /// Mangles a name so it doesn't conflict with any keyword.
-    #[rustfmt::skip]
     pub fn rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str> {
-        if name.contains('@') ||
-            name.contains('?') ||
-            name.contains('$') ||
-            matches!(
-                name,
+        if name.contains("@") ||
+            name.contains("?") ||
+            name.contains("$") ||
+            match name {
                 "abstract" | "alignof" | "as" | "async" | "become" |
-                    "box" | "break" | "const" | "continue" | "crate" | "do" |
-                    "dyn" | "else" | "enum" | "extern" | "false" | "final" |
-                    "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" |
-                    "macro" | "match" | "mod" | "move" | "mut" | "offsetof" |
-                    "override" | "priv" | "proc" | "pub" | "pure" | "ref" |
-                    "return" | "Self" | "self" | "sizeof" | "static" |
-                    "struct" | "super" | "trait" | "true" | "try" | "type" | "typeof" |
-                    "unsafe" | "unsized" | "use" | "virtual" | "where" |
-                    "while" | "yield" | "str" | "bool" | "f32" | "f64" |
-                    "usize" | "isize" | "u128" | "i128" | "u64" | "i64" |
-                    "u32" | "i32" | "u16" | "i16" | "u8" | "i8" | "_"
-            )
+                "box" | "break" | "const" | "continue" | "crate" | "do" |
+                "dyn" | "else" | "enum" | "extern" | "false" | "final" |
+                "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" |
+                "macro" | "match" | "mod" | "move" | "mut" | "offsetof" |
+                "override" | "priv" | "proc" | "pub" | "pure" | "ref" |
+                "return" | "Self" | "self" | "sizeof" | "static" |
+                "struct" | "super" | "trait" | "true" | "type" | "typeof" |
+                "unsafe" | "unsized" | "use" | "virtual" | "where" |
+                "while" | "yield" | "str" | "bool" | "f32" | "f64" |
+                "usize" | "isize" | "u128" | "i128" | "u64" | "i64" |
+                "u32" | "i32" | "u16" | "i16" | "u8" | "i8" | "_" => true,
+                _ => false,
+            }
         {
             let mut s = name.to_owned();
             s = s.replace("@", "_");
             s = s.replace("?", "_");
             s = s.replace("$", "_");
-            s.push('_');
+            s.push_str("_");
             return Cow::Owned(s);
         }
         Cow::Borrowed(name)
@@ -906,10 +879,11 @@
                 None => continue,
             };
 
-            if let TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) =
-                *ty.kind()
-            {
-                typerefs.push((id, *ty, loc, parent_id));
+            match *ty.kind() {
+                TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) => {
+                    typerefs.push((id, ty.clone(), loc, parent_id));
+                }
+                _ => {}
             };
         }
         typerefs
@@ -980,14 +954,15 @@
         assert!(self.collected_typerefs());
 
         let need_bitfield_allocation =
-            mem::take(&mut self.need_bitfield_allocation);
+            mem::replace(&mut self.need_bitfield_allocation, vec![]);
         for id in need_bitfield_allocation {
             self.with_loaned_item(id, |ctx, item| {
-                let ty = item.kind_mut().as_type_mut().unwrap();
-                let layout = ty.layout(ctx);
-                ty.as_comp_mut()
+                item.kind_mut()
+                    .as_type_mut()
                     .unwrap()
-                    .compute_bitfield_units(ctx, layout.as_ref());
+                    .as_comp_mut()
+                    .unwrap()
+                    .compute_bitfield_units(ctx);
             });
         }
     }
@@ -1123,8 +1098,7 @@
                     .ancestors(immut_self)
                     .find(|id| immut_self.resolve_item(*id).is_module())
             };
-            let new_module =
-                new_module.unwrap_or_else(|| self.root_module.into());
+            let new_module = new_module.unwrap_or(self.root_module.into());
 
             if new_module == old_module {
                 // Already in the correct module.
@@ -1332,12 +1306,12 @@
             // any sense of template parameter usage, and you're on your own.
             let mut used_params = HashMap::default();
             for &id in self.allowlisted_items() {
-                used_params.entry(id).or_insert_with(|| {
+                used_params.entry(id).or_insert(
                     id.self_template_params(self)
                         .into_iter()
                         .map(|p| p.into())
-                        .collect()
-                });
+                        .collect(),
+                );
             }
             self.used_template_parameters = Some(used_params);
         }
@@ -1423,7 +1397,7 @@
 
     fn build_root_module(id: ItemId) -> Item {
         let module = Module::new(Some("root".into()), ModuleKind::Normal);
-        Item::new(id, None, None, id, ItemKind::Module(module), None)
+        Item::new(id, None, None, id, ItemKind::Module(module))
     }
 
     /// Get the root module.
@@ -1733,7 +1707,6 @@
                             None,
                             self.current_module.into(),
                             ItemKind::Type(sub_ty),
-                            Some(child.location()),
                         );
 
                         // Bypass all the validations in add_item explicitly.
@@ -1798,7 +1771,6 @@
             None,
             self.current_module.into(),
             ItemKind::Type(ty),
-            Some(location.location()),
         );
 
         // Bypass all the validations in add_item explicitly.
@@ -1820,7 +1792,7 @@
             .or_else(|| {
                 decl.cursor()
                     .usr()
-                    .and_then(|usr| self.types.get(&TypeKey::Usr(usr)))
+                    .and_then(|usr| self.types.get(&TypeKey::USR(usr)))
             })
             .cloned()
     }
@@ -1836,8 +1808,8 @@
     ) -> Option<TypeId> {
         use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef};
         debug!(
-            "builtin_or_resolved_ty: {:?}, {:?}, {:?}, {:?}",
-            ty, location, with_id, parent_id
+            "builtin_or_resolved_ty: {:?}, {:?}, {:?}",
+            ty, location, parent_id
         );
 
         if let Some(decl) = ty.canonical_declaration(location.as_ref()) {
@@ -1853,32 +1825,32 @@
                 //     of it, or
                 //   * we have already parsed and resolved this type, and
                 //     there's nothing left to do.
-                if let Some(location) = location {
-                    if decl.cursor().is_template_like() &&
-                        *ty != decl.cursor().cur_type()
-                    {
-                        // For specialized type aliases, there's no way to get the
-                        // template parameters as of this writing (for a struct
-                        // specialization we wouldn't be in this branch anyway).
-                        //
-                        // Explicitly return `None` if there aren't any
-                        // unspecialized parameters (contains any `TypeRef`) so we
-                        // resolve the canonical type if there is one and it's
-                        // exposed.
-                        //
-                        // This is _tricky_, I know :(
-                        if decl.cursor().kind() ==
-                            CXCursor_TypeAliasTemplateDecl &&
-                            !location.contains_cursor(CXCursor_TypeRef) &&
-                            ty.canonical_type().is_valid_and_exposed()
-                        {
-                            return None;
-                        }
+                if decl.cursor().is_template_like() &&
+                    *ty != decl.cursor().cur_type() &&
+                    location.is_some()
+                {
+                    let location = location.unwrap();
 
-                        return self
-                            .instantiate_template(with_id, id, ty, location)
-                            .or(Some(id));
+                    // For specialized type aliases, there's no way to get the
+                    // template parameters as of this writing (for a struct
+                    // specialization we wouldn't be in this branch anyway).
+                    //
+                    // Explicitly return `None` if there aren't any
+                    // unspecialized parameters (contains any `TypeRef`) so we
+                    // resolve the canonical type if there is one and it's
+                    // exposed.
+                    //
+                    // This is _tricky_, I know :(
+                    if decl.cursor().kind() == CXCursor_TypeAliasTemplateDecl &&
+                        !location.contains_cursor(CXCursor_TypeRef) &&
+                        ty.canonical_type().is_valid_and_exposed()
+                    {
+                        return None;
                     }
+
+                    return self
+                        .instantiate_template(with_id, id, ty, location)
+                        .or_else(|| Some(id));
                 }
 
                 return Some(self.build_ty_wrapper(with_id, id, parent_id, ty));
@@ -1932,16 +1904,14 @@
     ) -> TypeId {
         let spelling = ty.spelling();
         let layout = ty.fallible_layout(self).ok();
-        let location = ty.declaration().location();
         let type_kind = TypeKind::ResolvedTypeRef(wrapped_id);
         let ty = Type::new(Some(spelling), layout, type_kind, is_const);
         let item = Item::new(
             with_id,
             None,
             None,
-            parent_id.unwrap_or_else(|| self.current_module.into()),
+            parent_id.unwrap_or(self.current_module.into()),
             ItemKind::Type(ty),
-            Some(location),
         );
         self.add_builtin_item(item);
         with_id.as_type_id_unchecked()
@@ -2002,7 +1972,6 @@
         let spelling = ty.spelling();
         let is_const = ty.is_const();
         let layout = ty.fallible_layout(self).ok();
-        let location = ty.declaration().location();
         let ty = Type::new(Some(spelling), layout, type_kind, is_const);
         let id = self.next_item_id();
         let item = Item::new(
@@ -2011,7 +1980,6 @@
             None,
             self.root_module.into(),
             ItemKind::Type(ty),
-            Some(location),
         );
         self.add_builtin_item(item);
         Some(id.as_type_id_unchecked())
@@ -2083,7 +2051,10 @@
         id: Id,
     ) -> bool {
         let id = id.into();
-        matches!(self.replacements.get(path), Some(replaced_by) if *replaced_by != id)
+        match self.replacements.get(path) {
+            Some(replaced_by) if *replaced_by != id => true,
+            _ => false,
+        }
     }
 
     /// Is the type with the given `name` marked as opaque?
@@ -2118,9 +2089,11 @@
             module_name = Some(spelling)
         }
 
+        let tokens = cursor.tokens();
+        let mut iter = tokens.iter();
         let mut kind = ModuleKind::Normal;
         let mut found_namespace_keyword = false;
-        for token in cursor.tokens().iter() {
+        while let Some(token) = iter.next() {
             match token.spelling() {
                 b"inline" => {
                     assert!(!found_namespace_keyword);
@@ -2200,7 +2173,6 @@
             None,
             self.current_module.into(),
             ItemKind::Module(module),
-            Some(cursor.location()),
         );
 
         let module_id = module.id().as_module_id_unchecked();
@@ -2248,6 +2220,11 @@
         assert!(self.in_codegen_phase());
         assert!(self.current_module == self.root_module);
 
+        let cb = match self.options.parse_callbacks {
+            Some(ref cb) => cb,
+            None => return CanDerive::No,
+        };
+
         *self
             .blocklisted_types_implement_traits
             .borrow_mut()
@@ -2257,27 +2234,8 @@
             .or_insert_with(|| {
                 item.expect_type()
                     .name()
-                    .and_then(|name| match self.options.parse_callbacks {
-                        Some(ref cb) => cb.blocklisted_type_implements_trait(
-                            name,
-                            derive_trait,
-                        ),
-                        // Sized integer types from <stdint.h> get mapped to Rust primitive
-                        // types regardless of whether they are blocklisted, so ensure that
-                        // standard traits are considered derivable for them too.
-                        None => match name {
-                            "int8_t" | "uint8_t" | "int16_t" | "uint16_t" |
-                            "int32_t" | "uint32_t" | "int64_t" |
-                            "uint64_t" | "uintptr_t" | "intptr_t" |
-                            "ptrdiff_t" => Some(CanDerive::Yes),
-                            "size_t" if self.options.size_t_is_usize => {
-                                Some(CanDerive::Yes)
-                            }
-                            "ssize_t" if self.options.size_t_is_usize => {
-                                Some(CanDerive::Yes)
-                            }
-                            _ => Some(CanDerive::No),
-                        },
+                    .and_then(|name| {
+                        cb.blocklisted_type_implements_trait(name, derive_trait)
                     })
                     .unwrap_or(CanDerive::No)
             })
@@ -2418,7 +2376,7 @@
         let codegen_items = if self.options().allowlist_recursively {
             AllowlistedItemsTraversal::new(
                 self,
-                roots,
+                roots.clone(),
                 traversal::codegen_edges,
             )
             .collect::<ItemSet>()
@@ -2682,12 +2640,6 @@
         let name = item.path_for_allowlisting(self)[1..].join("::");
         self.options().no_hash_types.matches(&name)
     }
-
-    /// Check if `--must-use-type` flag is enabled for this item.
-    pub fn must_use_type_by_name(&self, item: &Item) -> bool {
-        let name = item.path_for_allowlisting(self)[1..].join("::");
-        self.options().must_use_types.matches(&name)
-    }
 }
 
 /// A builder struct for configuring item resolution options.
@@ -2719,7 +2671,7 @@
     pub fn new<Id: Into<ItemId>>(id: Id) -> ItemResolver {
         let id = id.into();
         ItemResolver {
-            id,
+            id: id,
             through_type_refs: false,
             through_type_aliases: false,
         }
@@ -2742,16 +2694,8 @@
         assert!(ctx.collected_typerefs());
 
         let mut id = self.id;
-        let mut seen_ids = HashSet::default();
         loop {
             let item = ctx.resolve_item(id);
-
-            // Detect cycles and bail out. These can happen in certain cases
-            // involving incomplete qualified dependent types (#2085).
-            if !seen_ids.insert(id) {
-                return item;
-            }
-
             let ty_kind = item.as_type().map(|t| t.kind());
             match ty_kind {
                 Some(&TypeKind::ResolvedTypeRef(next_id))
@@ -2786,7 +2730,7 @@
     /// Construct a new `PartialType`.
     pub fn new(decl: Cursor, id: ItemId) -> PartialType {
         // assert!(decl == decl.canonical());
-        PartialType { decl, id }
+        PartialType { decl: decl, id: id }
     }
 
     /// The cursor pointing to this partial type's declaration location.
diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs
index 97455c9..15d4136 100644
--- a/src/ir/enum_ty.rs
+++ b/src/ir/enum_ty.rs
@@ -86,7 +86,7 @@
         } else {
             Some(type_name)
         };
-        let type_name = type_name.as_deref();
+        let type_name = type_name.as_ref().map(String::as_str);
 
         let definition = declaration.definition().unwrap_or(declaration);
         definition.visit(|cursor| {
@@ -286,7 +286,7 @@
 
     /// Get this variant's documentation.
     pub fn comment(&self) -> Option<&str> {
-        self.comment.as_deref()
+        self.comment.as_ref().map(|s| &**s)
     }
 
     /// Returns whether this variant should be enforced to be a constant by code
diff --git a/src/ir/function.rs b/src/ir/function.rs
index a3a2bbf..a6f63a6 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -28,9 +28,7 @@
 }
 
 impl FunctionKind {
-    /// Given a clang cursor, return the kind of function it represents, or
-    /// `None` otherwise.
-    pub fn from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind> {
+    fn from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind> {
         // FIXME(emilio): Deduplicate logic with `ir::comp`.
         Some(match cursor.kind() {
             clang_sys::CXCursor_FunctionDecl => FunctionKind::Function,
@@ -123,7 +121,7 @@
 
     /// Get this function's name.
     pub fn mangled_name(&self) -> Option<&str> {
-        self.mangled_name.as_deref()
+        self.mangled_name.as_ref().map(|n| &**n)
     }
 
     /// Get this function's signature type.
@@ -187,7 +185,10 @@
 impl Abi {
     /// Returns whether this Abi is known or not.
     fn is_unknown(&self) -> bool {
-        matches!(*self, Abi::Unknown(..))
+        match *self {
+            Abi::Unknown(..) => true,
+            _ => false,
+        }
     }
 }
 
@@ -337,7 +338,7 @@
             });
 
             let cursor = arg_cur.unwrap_or(*cursor);
-            let ty = arg_ty.unwrap_or_else(|| cursor.cur_type());
+            let ty = arg_ty.unwrap_or(cursor.cur_type());
             (name, Item::from_ty_or_ref(ty, cursor, None, ctx))
         })
         .collect()
@@ -357,7 +358,7 @@
             argument_types,
             is_variadic,
             must_use,
-            abi,
+            abi: abi,
         }
     }
 
@@ -408,7 +409,7 @@
             CXCursor_CXXMethod |
             CXCursor_ObjCInstanceMethodDecl |
             CXCursor_ObjCClassMethodDecl => {
-                args_from_ty_and_cursor(ty, &cursor, ctx)
+                args_from_ty_and_cursor(&ty, &cursor, ctx)
             }
             _ => {
                 // For non-CXCursor_FunctionDecl, visiting the cursor's children
@@ -431,7 +432,7 @@
                     // right AST for functions tagged as stdcall and such...
                     //
                     // https://bugs.llvm.org/show_bug.cgi?id=45919
-                    args_from_ty_and_cursor(ty, &cursor, ctx)
+                    args_from_ty_and_cursor(&ty, &cursor, ctx)
                 } else {
                     args
                 }
@@ -519,7 +520,7 @@
             warn!("Unknown calling convention: {:?}", call_conv);
         }
 
-        Ok(Self::new(ret, args, ty.is_variadic(), must_use, abi))
+        Ok(Self::new(ret.into(), args, ty.is_variadic(), must_use, abi))
     }
 
     /// Get this function signature's return type.
@@ -564,7 +565,10 @@
             return false;
         }
 
-        matches!(self.abi, Abi::C | Abi::Unknown(..))
+        match self.abi {
+            Abi::C | Abi::Unknown(..) => true,
+            _ => false,
+        }
     }
 }
 
@@ -591,13 +595,10 @@
             return Err(ParseError::Continue);
         }
 
-        if cursor.is_inlined_function() {
-            if !context.options().generate_inline_functions {
-                return Err(ParseError::Continue);
-            }
-            if cursor.is_deleted_function() {
-                return Err(ParseError::Continue);
-            }
+        if !context.options().generate_inline_functions &&
+            cursor.is_inlined_function()
+        {
+            return Err(ParseError::Continue);
         }
 
         let linkage = cursor.linkage();
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 8692575..4541504 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -4,7 +4,7 @@
 use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult};
 use super::annotations::Annotations;
 use super::comment;
-use super::comp::{CompKind, MethodKind};
+use super::comp::MethodKind;
 use super::context::{BindgenContext, ItemId, PartialType, TypeId};
 use super::derive::{
     CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq,
@@ -417,8 +417,6 @@
     parent_id: ItemId,
     /// The item kind.
     kind: ItemKind,
-    /// The source location of the item.
-    location: Option<clang::SourceLocation>,
 }
 
 impl AsRef<ItemId> for Item {
@@ -435,20 +433,18 @@
         annotations: Option<Annotations>,
         parent_id: ItemId,
         kind: ItemKind,
-        location: Option<clang::SourceLocation>,
     ) -> Self {
         debug_assert!(id != parent_id || kind.is_module());
         Item {
-            id,
+            id: id,
             local_id: LazyCell::new(),
             next_child_local_id: Cell::new(1),
             canonical_name: LazyCell::new(),
             path_for_allowlisting: LazyCell::new(),
-            parent_id,
-            comment,
+            parent_id: parent_id,
+            comment: comment,
             annotations: annotations.unwrap_or_default(),
-            kind,
-            location,
+            kind: kind,
         }
     }
 
@@ -458,15 +454,10 @@
         ty: &clang::Type,
         ctx: &mut BindgenContext,
     ) -> TypeId {
-        let location = ty.declaration().location();
         let ty = Opaque::from_clang_ty(ty, ctx);
         let kind = ItemKind::Type(ty);
         let parent = ctx.root_module().into();
-        ctx.add_item(
-            Item::new(with_id, None, None, parent, kind, Some(location)),
-            None,
-            None,
-        );
+        ctx.add_item(Item::new(with_id, None, None, parent, kind), None, None);
         with_id.as_type_id_unchecked()
     }
 
@@ -621,7 +612,10 @@
 
     /// Is this item a module?
     pub fn is_module(&self) -> bool {
-        matches!(self.kind, ItemKind::Module(..))
+        match self.kind {
+            ItemKind::Module(..) => true,
+            _ => false,
+        }
     }
 
     /// Get this item's annotations.
@@ -641,24 +635,13 @@
             return true;
         }
 
-        if !ctx.options().blocklisted_files.is_empty() {
-            if let Some(location) = &self.location {
-                let (file, _, _, _) = location.location();
-                if let Some(filename) = file.name() {
-                    if ctx.options().blocklisted_files.matches(&filename) {
-                        return true;
-                    }
-                }
-            }
-        }
-
         let path = self.path_for_allowlisting(ctx);
         let name = path[1..].join("::");
         ctx.options().blocklisted_items.matches(&name) ||
             match self.kind {
                 ItemKind::Type(..) => {
                     ctx.options().blocklisted_types.matches(&name) ||
-                        ctx.is_replaced_type(path, self.id)
+                        ctx.is_replaced_type(&path, self.id)
                 }
                 ItemKind::Function(..) => {
                     ctx.options().blocklisted_functions.matches(&name)
@@ -675,7 +658,10 @@
 
     /// Is this item a var type?
     pub fn is_var(&self) -> bool {
-        matches!(*self.kind(), ItemKind::Var(..))
+        match *self.kind() {
+            ItemKind::Var(..) => true,
+            _ => false,
+        }
     }
 
     /// Take out item NameOptions
@@ -736,7 +722,7 @@
                         .through_type_refs()
                         .resolve(ctx)
                         .push_disambiguated_name(ctx, to, level + 1);
-                    to.push('_');
+                    to.push_str("_");
                 }
                 to.push_str(&format!("close{}", level));
             }
@@ -849,7 +835,7 @@
             if ctx.options().enable_cxx_namespaces {
                 return path.last().unwrap().clone();
             }
-            return path.join("_");
+            return path.join("_").to_owned();
         }
 
         let base_name = target.base_name(ctx);
@@ -887,7 +873,7 @@
 
             // If target is anonymous we need find its first named ancestor.
             if target.is_anon() {
-                for id in ids_iter.by_ref() {
+                while let Some(id) = ids_iter.next() {
                     ids.push(id);
 
                     if !ctx.resolve_item(id).is_anon() {
@@ -918,12 +904,6 @@
             names.push(base_name);
         }
 
-        if ctx.options().c_naming {
-            if let Some(prefix) = self.c_naming_prefix() {
-                names.insert(0, prefix.to_string());
-            }
-        }
-
         let name = names.join("_");
 
         let name = if opt.user_mangled == UserMangled::Yes {
@@ -1074,23 +1054,6 @@
         path.reverse();
         path
     }
-
-    /// 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,
-        };
-
-        Some(match ty.kind() {
-            TypeKind::Comp(ref ci) => match ci.kind() {
-                CompKind::Struct => "struct",
-                CompKind::Union => "union",
-            },
-            TypeKind::Enum(..) => "enum",
-            _ => return None,
-        })
-    }
 }
 
 impl<T> IsOpaque for T
@@ -1118,7 +1081,7 @@
         );
         self.annotations.opaque() ||
             self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) ||
-            ctx.opaque_by_name(self.path_for_allowlisting(ctx))
+            ctx.opaque_by_name(&self.path_for_allowlisting(ctx))
     }
 }
 
@@ -1128,16 +1091,20 @@
 {
     fn has_vtable(&self, ctx: &BindgenContext) -> bool {
         let id: ItemId = (*self).into();
-        id.as_type_id(ctx).map_or(false, |id| {
-            !matches!(ctx.lookup_has_vtable(id), HasVtableResult::No)
-        })
+        id.as_type_id(ctx)
+            .map_or(false, |id| match ctx.lookup_has_vtable(id) {
+                HasVtableResult::No => false,
+                _ => true,
+            })
     }
 
     fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool {
         let id: ItemId = (*self).into();
-        id.as_type_id(ctx).map_or(false, |id| {
-            matches!(ctx.lookup_has_vtable(id), HasVtableResult::SelfHasVtable)
-        })
+        id.as_type_id(ctx)
+            .map_or(false, |id| match ctx.lookup_has_vtable(id) {
+                HasVtableResult::SelfHasVtable => true,
+                _ => false,
+            })
     }
 }
 
@@ -1317,7 +1284,7 @@
         let id = ctx.next_item_id();
         let module = ctx.root_module().into();
         ctx.add_item(
-            Item::new(id, None, None, module, ItemKind::Type(ty), None),
+            Item::new(id, None, None, module, ItemKind::Type(ty)),
             None,
             None,
         );
@@ -1355,7 +1322,6 @@
                                 annotations,
                                 relevant_parent_id,
                                 ItemKind::$what(item),
-                                Some(cursor.location()),
                             ),
                             declaration,
                             Some(cursor),
@@ -1403,7 +1369,7 @@
                     }
                     ctx.known_semantic_parent(definition)
                         .or(parent_id)
-                        .unwrap_or_else(|| ctx.current_module().into())
+                        .unwrap_or(ctx.current_module().into())
                 }
                 None => relevant_parent_id,
             };
@@ -1449,7 +1415,9 @@
                             );
                         }
                         Some(filename) => {
-                            ctx.include_file(filename);
+                            if let Some(cb) = ctx.parse_callbacks() {
+                                cb.include_file(&filename)
+                            }
                         }
                     }
                 }
@@ -1535,9 +1503,8 @@
                 potential_id,
                 None,
                 None,
-                parent_id.unwrap_or_else(|| current_module.into()),
+                parent_id.unwrap_or(current_module.into()),
                 ItemKind::Type(Type::new(None, None, kind, is_const)),
-                Some(location.location()),
             ),
             None,
             None,
@@ -1593,21 +1560,9 @@
             }
         }
 
-        // Treat all types that are declared inside functions as opaque. The Rust binding
-        // won't be able to do anything with them anyway.
-        //
-        // (If we don't do this check here, we can have subtle logic bugs because we generally
-        // 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);
-                return Ok(Item::new_opaque_type(id, ty, ctx));
-            }
-        }
-
         let decl = {
-            let canonical_def = ty.canonical_type().declaration().definition();
-            canonical_def.unwrap_or_else(|| ty.declaration())
+            let decl = ty.declaration();
+            decl.definition().unwrap_or(decl)
         };
 
         let comment = decl.raw_comment().or_else(|| location.raw_comment());
@@ -1615,7 +1570,7 @@
             Annotations::new(&decl).or_else(|| Annotations::new(&location));
 
         if let Some(ref annotations) = annotations {
-            if let Some(replaced) = annotations.use_instead_of() {
+            if let Some(ref replaced) = annotations.use_instead_of() {
                 ctx.replace(replaced, id);
             }
         }
@@ -1669,7 +1624,6 @@
                         annotations,
                         relevant_parent_id,
                         ItemKind::Type(item),
-                        Some(location.location()),
                     ),
                     declaration,
                     Some(location),
@@ -1864,7 +1818,11 @@
                 clang_sys::CXChildVisit_Continue
             });
 
-            definition?
+            if let Some(def) = definition {
+                def
+            } else {
+                return None;
+            }
         };
         assert!(is_template_with_spelling(&definition, &ty_spelling));
 
@@ -1898,7 +1856,6 @@
             None,
             parent,
             ItemKind::Type(Type::named(name)),
-            Some(location.location()),
         );
         ctx.add_type_param(item, definition);
         Some(id.as_type_id_unchecked())
@@ -1949,7 +1906,7 @@
             path.push(CONSTIFIED_ENUM_MODULE_REPR_NAME.into());
         }
 
-        path
+        return path;
     }
 
     fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String> {
@@ -1982,8 +1939,8 @@
     /// Construct a new `NameOptions`
     pub fn new(item: &'a Item, ctx: &'a BindgenContext) -> Self {
         NameOptions {
-            item,
-            ctx,
+            item: item,
+            ctx: ctx,
             within_namespaces: false,
             user_mangled: UserMangled::Yes,
         }
diff --git a/src/ir/layout.rs b/src/ir/layout.rs
index 6cf9113..28a6604 100644
--- a/src/ir/layout.rs
+++ b/src/ir/layout.rs
@@ -64,7 +64,7 @@
             next_align *= 2;
         }
         Layout {
-            size,
+            size: size,
             align: next_align / 2,
             packed: false,
         }
diff --git a/src/ir/module.rs b/src/ir/module.rs
index d5aca94..13b7c19 100644
--- a/src/ir/module.rs
+++ b/src/ir/module.rs
@@ -32,15 +32,15 @@
     /// Construct a new `Module`.
     pub fn new(name: Option<String>, kind: ModuleKind) -> Self {
         Module {
-            name,
-            kind,
+            name: name,
+            kind: kind,
             children: ItemSet::new(),
         }
     }
 
     /// Get this module's name.
     pub fn name(&self) -> Option<&str> {
-        self.name.as_deref()
+        self.name.as_ref().map(|n| &**n)
     }
 
     /// Get a mutable reference to this module's children.
diff --git a/src/ir/objc.rs b/src/ir/objc.rs
index 0845ad0..91855c6 100644
--- a/src/ir/objc.rs
+++ b/src/ir/objc.rs
@@ -89,10 +89,12 @@
     pub fn rust_name(&self) -> String {
         if let Some(ref cat) = self.category {
             format!("{}_{}", self.name(), cat)
-        } else if self.is_protocol {
-            format!("P{}", self.name())
         } else {
-            format!("I{}", self.name().to_owned())
+            if self.is_protocol {
+                format!("P{}", self.name())
+            } else {
+                format!("I{}", self.name().to_owned())
+            }
         }
     }
 
@@ -147,34 +149,28 @@
                     // Gather protocols this interface conforms to
                     let needle = format!("P{}", c.spelling());
                     let items_map = ctx.items();
-                    debug!(
-                        "Interface {} conforms to {}, find the item",
-                        interface.name, needle
-                    );
+                    debug!("Interface {} conforms to {}, find the item", interface.name, needle);
 
-                    for (id, item) in items_map {
+                    for (id, item) in items_map
+                    {
                         if let Some(ty) = item.as_type() {
-                            if let TypeKind::ObjCInterface(ref protocol) =
-                                *ty.kind()
-                            {
-                                if protocol.is_protocol {
-                                    debug!(
-                                        "Checking protocol {}, ty.name {:?}",
-                                        protocol.name,
-                                        ty.name()
-                                    );
-                                    if Some(needle.as_ref()) == ty.name() {
-                                        debug!(
-                                            "Found conforming protocol {:?}",
-                                            item
-                                        );
-                                        interface.conforms_to.push(id);
-                                        break;
+                            match *ty.kind() {
+                                TypeKind::ObjCInterface(ref protocol) => {
+                                    if protocol.is_protocol
+                                    {
+                                        debug!("Checking protocol {}, ty.name {:?}", protocol.name, ty.name());
+                                        if Some(needle.as_ref()) == ty.name() {
+                                            debug!("Found conforming protocol {:?}", item);
+                                            interface.conforms_to.push(id);
+                                            break;
+                                        }
                                     }
                                 }
+                                _ => {}
                             }
                         }
                     }
+
                 }
                 CXCursor_ObjCInstanceMethodDecl |
                 CXCursor_ObjCClassMethodDecl => {
@@ -182,10 +178,8 @@
                     let signature =
                         FunctionSig::from_ty(&c.cur_type(), &c, ctx)
                             .expect("Invalid function sig");
-                    let is_class_method =
-                        c.kind() == CXCursor_ObjCClassMethodDecl;
-                    let method =
-                        ObjCMethod::new(&name, signature, is_class_method);
+                    let is_class_method = c.kind() == CXCursor_ObjCClassMethodDecl;
+                    let method = ObjCMethod::new(&name, signature, is_class_method);
                     interface.add_method(method);
                 }
                 CXCursor_TemplateTypeParameter => {
@@ -195,7 +189,7 @@
                 CXCursor_ObjCSuperClassRef => {
                     let item = Item::from_ty_or_ref(c.cur_type(), c, None, ctx);
                     interface.parent_class = Some(item.into());
-                }
+                },
                 _ => {}
             }
             CXChildVisit_Continue
@@ -224,7 +218,7 @@
 
         ObjCMethod {
             name: name.to_owned(),
-            rust_name,
+            rust_name: rust_name.to_owned(),
             signature,
             is_class_method,
         }
@@ -267,7 +261,7 @@
             .collect();
 
         // No arguments
-        if args.is_empty() && split_name.len() == 1 {
+        if args.len() == 0 && split_name.len() == 1 {
             let name = &split_name[0];
             return quote! {
                 #name
@@ -275,12 +269,13 @@
         }
 
         // Check right amount of arguments
-        assert!(
-            args.len() == split_name.len() - 1,
-            "Incorrect method name or arguments for objc method, {:?} vs {:?}",
-            args,
-            split_name
-        );
+        if args.len() != split_name.len() - 1 {
+            panic!(
+                "Incorrect method name or arguments for objc method, {:?} vs {:?}",
+                args,
+                split_name,
+            );
+        }
 
         // Get arguments without type signatures to pass to `msg_send!`
         let mut args_without_types = vec![];
diff --git a/src/ir/template.rs b/src/ir/template.rs
index 8b06748..b519fff 100644
--- a/src/ir/template.rs
+++ b/src/ir/template.rs
@@ -134,10 +134,10 @@
     where
         Self: ItemAncestors,
     {
-        let mut ancestors: Vec<_> = self.ancestors(ctx).collect();
-        ancestors.reverse();
+        let ancestors: Vec<_> = self.ancestors(ctx).collect();
         ancestors
             .into_iter()
+            .rev()
             .flat_map(|id| id.self_template_params(ctx).into_iter())
             .collect()
     }
diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs
index 088e744..430dd02 100644
--- a/src/ir/traversal.rs
+++ b/src/ir/traversal.rs
@@ -24,9 +24,9 @@
     }
 }
 
-impl From<Edge> for ItemId {
-    fn from(val: Edge) -> Self {
-        val.to
+impl Into<ItemId> for Edge {
+    fn into(self) -> ItemId {
+        self.to
     }
 }
 
@@ -424,10 +424,10 @@
         }
 
         ItemTraversal {
-            ctx,
-            seen,
-            queue,
-            predicate,
+            ctx: ctx,
+            seen: seen,
+            queue: queue,
+            predicate: predicate,
             currently_traversing: None,
         }
     }
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index d573408..e6eecc3 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -39,6 +39,7 @@
 /// traits, and so if we have a type containing an array with more than this
 /// many items, we won't be able to derive common traits on that type.
 ///
+/// We need type-level integers yesterday :'(
 pub const RUST_DERIVE_IN_ARRAY_LIMIT: usize = 32;
 
 impl Type {
@@ -87,17 +88,23 @@
 
     /// Get this type's name.
     pub fn name(&self) -> Option<&str> {
-        self.name.as_deref()
+        self.name.as_ref().map(|name| &**name)
     }
 
     /// Whether this is a block pointer type.
     pub fn is_block_pointer(&self) -> bool {
-        matches!(self.kind, TypeKind::BlockPointer(..))
+        match self.kind {
+            TypeKind::BlockPointer(..) => true,
+            _ => false,
+        }
     }
 
     /// Is this a compound type?
     pub fn is_comp(&self) -> bool {
-        matches!(self.kind, TypeKind::Comp(..))
+        match self.kind {
+            TypeKind::Comp(..) => true,
+            _ => false,
+        }
     }
 
     /// Is this a union?
@@ -110,43 +117,58 @@
 
     /// Is this type of kind `TypeKind::TypeParam`?
     pub fn is_type_param(&self) -> bool {
-        matches!(self.kind, TypeKind::TypeParam)
+        match self.kind {
+            TypeKind::TypeParam => true,
+            _ => false,
+        }
     }
 
     /// Is this a template instantiation type?
     pub fn is_template_instantiation(&self) -> bool {
-        matches!(self.kind, TypeKind::TemplateInstantiation(..))
+        match self.kind {
+            TypeKind::TemplateInstantiation(..) => true,
+            _ => false,
+        }
     }
 
     /// Is this a template alias type?
     pub fn is_template_alias(&self) -> bool {
-        matches!(self.kind, TypeKind::TemplateAlias(..))
+        match self.kind {
+            TypeKind::TemplateAlias(..) => true,
+            _ => false,
+        }
     }
 
     /// Is this a function type?
     pub fn is_function(&self) -> bool {
-        matches!(self.kind, TypeKind::Function(..))
+        match self.kind {
+            TypeKind::Function(..) => true,
+            _ => false,
+        }
     }
 
     /// Is this an enum type?
     pub fn is_enum(&self) -> bool {
-        matches!(self.kind, TypeKind::Enum(..))
+        match self.kind {
+            TypeKind::Enum(..) => true,
+            _ => false,
+        }
     }
 
     /// Is this either a builtin or named type?
     pub fn is_builtin_or_type_param(&self) -> bool {
-        matches!(
-            self.kind,
+        match self.kind {
             TypeKind::Void |
-                TypeKind::NullPtr |
-                TypeKind::Function(..) |
-                TypeKind::Array(..) |
-                TypeKind::Reference(..) |
-                TypeKind::Pointer(..) |
-                TypeKind::Int(..) |
-                TypeKind::Float(..) |
-                TypeKind::TypeParam
-        )
+            TypeKind::NullPtr |
+            TypeKind::Function(..) |
+            TypeKind::Array(..) |
+            TypeKind::Reference(..) |
+            TypeKind::Pointer(..) |
+            TypeKind::Int(..) |
+            TypeKind::Float(..) |
+            TypeKind::TypeParam => true,
+            _ => false,
+        }
     }
 
     /// Creates a new named type, with name `name`.
@@ -157,17 +179,26 @@
 
     /// Is this a floating point type?
     pub fn is_float(&self) -> bool {
-        matches!(self.kind, TypeKind::Float(..))
+        match self.kind {
+            TypeKind::Float(..) => true,
+            _ => false,
+        }
     }
 
     /// Is this a boolean type?
     pub fn is_bool(&self) -> bool {
-        matches!(self.kind, TypeKind::Int(IntKind::Bool))
+        match self.kind {
+            TypeKind::Int(IntKind::Bool) => true,
+            _ => false,
+        }
     }
 
     /// Is this an integer type?
     pub fn is_integer(&self) -> bool {
-        matches!(self.kind, TypeKind::Int(..))
+        match self.kind {
+            TypeKind::Int(..) => true,
+            _ => false,
+        }
     }
 
     /// Cast this type to an integer kind, or `None` if it is not an integer
@@ -186,15 +217,19 @@
 
     /// Is this a reference to another type?
     pub fn is_type_ref(&self) -> bool {
-        matches!(
-            self.kind,
-            TypeKind::ResolvedTypeRef(_) | TypeKind::UnresolvedTypeRef(_, _, _)
-        )
+        match self.kind {
+            TypeKind::ResolvedTypeRef(_) |
+            TypeKind::UnresolvedTypeRef(_, _, _) => true,
+            _ => false,
+        }
     }
 
     /// Is this an unresolved reference?
     pub fn is_unresolved_ref(&self) -> bool {
-        matches!(self.kind, TypeKind::UnresolvedTypeRef(_, _, _))
+        match self.kind {
+            TypeKind::UnresolvedTypeRef(_, _, _) => true,
+            _ => false,
+        }
     }
 
     /// Is this a incomplete array type?
@@ -244,14 +279,14 @@
         match self.kind {
             TypeKind::TypeParam => {
                 let name = self.name().expect("Unnamed named type?");
-                !clang::is_valid_identifier(name)
+                !clang::is_valid_identifier(&name)
             }
             _ => false,
         }
     }
 
     /// Takes `name`, and returns a suitable identifier representation for it.
-    fn sanitize_name(name: &str) -> Cow<str> {
+    fn sanitize_name<'a>(name: &'a str) -> Cow<'a, str> {
         if clang::is_valid_identifier(name) {
             return Cow::Borrowed(name);
         }
@@ -266,8 +301,12 @@
         ctx: &BindgenContext,
     ) -> Option<Cow<'a, str>> {
         let name_info = match *self.kind() {
-            TypeKind::Pointer(inner) => Some((inner, Cow::Borrowed("ptr"))),
-            TypeKind::Reference(inner) => Some((inner, Cow::Borrowed("ref"))),
+            TypeKind::Pointer(inner) => {
+                Some((inner.into(), Cow::Borrowed("ptr")))
+            }
+            TypeKind::Reference(inner) => {
+                Some((inner.into(), Cow::Borrowed("ref")))
+            }
             TypeKind::Array(inner, length) => {
                 Some((inner, format!("array{}", length).into()))
             }
@@ -337,16 +376,16 @@
     /// There are some types we don't want to stop at when finding an opaque
     /// item, so we can arrive to the proper item that needs to be generated.
     pub fn should_be_traced_unconditionally(&self) -> bool {
-        matches!(
-            self.kind,
+        match self.kind {
             TypeKind::Comp(..) |
-                TypeKind::Function(..) |
-                TypeKind::Pointer(..) |
-                TypeKind::Array(..) |
-                TypeKind::Reference(..) |
-                TypeKind::TemplateInstantiation(..) |
-                TypeKind::ResolvedTypeRef(..)
-        )
+            TypeKind::Function(..) |
+            TypeKind::Pointer(..) |
+            TypeKind::Array(..) |
+            TypeKind::Reference(..) |
+            TypeKind::TemplateInstantiation(..) |
+            TypeKind::ResolvedTypeRef(..) => true,
+            _ => false,
+        }
     }
 }
 
@@ -753,7 +792,7 @@
             (ty.template_args().is_some() && ty_kind != CXType_Typedef)
         {
             // This is a template instantiation.
-            match TemplateInstantiation::from_ty(ty, ctx) {
+            match TemplateInstantiation::from_ty(&ty, ctx) {
                 Some(inst) => TypeKind::TemplateInstantiation(inst),
                 None => TypeKind::Opaque,
             }
@@ -1082,16 +1121,7 @@
                     let inner = cursor.typedef_type().expect("Not valid Type?");
                     let inner =
                         Item::from_ty_or_ref(inner, location, None, ctx);
-                    if inner == potential_id {
-                        warn!(
-                            "Generating oqaque type instead of self-referential \
-                            typedef");
-                        // This can happen if we bail out of recursive situations
-                        // within the clang parsing.
-                        TypeKind::Opaque
-                    } else {
-                        TypeKind::Alias(inner)
-                    }
+                    TypeKind::Alias(inner)
                 }
                 CXType_Enum => {
                     let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?");
diff --git a/src/ir/var.rs b/src/ir/var.rs
index cd17937..49c4f30 100644
--- a/src/ir/var.rs
+++ b/src/ir/var.rs
@@ -88,7 +88,7 @@
 
     /// Get this variable's mangled name.
     pub fn mangled_name(&self) -> Option<&str> {
-        self.mangled_name.as_deref()
+        self.mangled_name.as_ref().map(|n| &**n)
     }
 }
 
@@ -282,7 +282,7 @@
                             .parse_callbacks()
                             .and_then(|c| c.int_macro(&name, value))
                             .unwrap_or_else(|| {
-                                default_macro_constant_type(ctx, value)
+                                default_macro_constant_type(&ctx, value)
                             });
 
                         (TypeKind::Int(kind), VarType::Int(value))
@@ -398,8 +398,11 @@
 
     let parser = expr::IdentifierParser::new(ctx.parsed_macros());
 
-    if let Ok((_, (id, val))) = parser.macro_definition(&cexpr_tokens) {
-        return Some((id.into(), val));
+    match parser.macro_definition(&cexpr_tokens) {
+        Ok((_, (id, val))) => {
+            return Some((id.into(), val));
+        }
+        _ => {}
     }
 
     // Try without the last token, to workaround a libclang bug in versions
diff --git a/src/lib.rs b/src/lib.rs
index 9a90dac..d0253db 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -51,7 +51,6 @@
 
 mod clang;
 mod codegen;
-mod deps;
 mod features;
 mod ir;
 mod parse;
@@ -89,7 +88,7 @@
 pub(crate) use std::collections::hash_map::Entry;
 
 /// Default prefix for the anon fields.
-pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_";
+pub const DEFAULT_ANON_FIELDS_PREFIX: &'static str = "__bindgen_anon_";
 
 fn file_is_cpp(name_file: &str) -> bool {
     name_file.ends_with(".hpp") ||
@@ -308,7 +307,6 @@
             (&self.options.blocklisted_types, "--blocklist-type"),
             (&self.options.blocklisted_functions, "--blocklist-function"),
             (&self.options.blocklisted_items, "--blocklist-item"),
-            (&self.options.blocklisted_files, "--blocklist-file"),
             (&self.options.opaque_types, "--opaque-type"),
             (&self.options.allowlisted_functions, "--allowlist-function"),
             (&self.options.allowlisted_types, "--allowlist-type"),
@@ -318,7 +316,6 @@
             (&self.options.no_debug_types, "--no-debug"),
             (&self.options.no_default_types, "--no-default"),
             (&self.options.no_hash_types, "--no-hash"),
-            (&self.options.must_use_types, "--must-use-type"),
         ];
 
         for (set, flag) in regex_sets {
@@ -560,14 +557,6 @@
             output_vector.push("--translate-enum-integer-types".into());
         }
 
-        if self.options.c_naming {
-            output_vector.push("--c-naming".into());
-        }
-
-        if self.options.force_explicit_padding {
-            output_vector.push("--explicit-padding".into());
-        }
-
         // Add clang arguments
 
         output_vector.push("--".into());
@@ -615,19 +604,6 @@
         self
     }
 
-    /// Add a depfile output which will be written alongside the generated bindings.
-    pub fn depfile<H: Into<String>, D: Into<PathBuf>>(
-        mut self,
-        output_module: H,
-        depfile: D,
-    ) -> Builder {
-        self.options.depfile = Some(deps::DepfileSpec {
-            output_module: output_module.into(),
-            depfile_path: depfile.into(),
-        });
-        self
-    }
-
     /// Add `contents` as an input C/C++ header named `name`.
     ///
     /// The file `name` will be added to the clang arguments.
@@ -822,13 +798,6 @@
         self
     }
 
-    /// Hide any contents of the given file from the generated bindings,
-    /// regardless of whether it's a type, function, module etc.
-    pub fn blocklist_file<T: AsRef<str>>(mut self, arg: T) -> Builder {
-        self.options.blocklisted_files.insert(arg);
-        self
-    }
-
     /// Treat the given type as opaque in the generated bindings. Regular
     /// expressions are supported.
     ///
@@ -1432,22 +1401,11 @@
         self
     }
 
-    /// If true, always emit explicit padding fields.
-    ///
-    /// If a struct needs to be serialized in its native format (padding bytes
-    /// and all), for example writing it to a file or sending it on the network,
-    /// then this should be enabled, as anything reading the padding bytes of
-    /// a struct may lead to Undefined Behavior.
-    pub fn explicit_padding(mut self, doit: bool) -> Self {
-        self.options.force_explicit_padding = doit;
-        self
-    }
-
     /// Generate the Rust bindings using the options built up thus far.
     pub fn generate(mut self) -> Result<Bindings, ()> {
         // Add any extra arguments from the environment to the clang command line.
         if let Some(extra_clang_args) =
-            get_target_dependent_env_var("BINDGEN_EXTRA_CLANG_ARGS")
+            env::var("BINDGEN_EXTRA_CLANG_ARGS").ok()
         {
             // Try to parse it with shell quoting. If we fail, make it one single big argument.
             if let Some(strings) = shlex::split(&extra_clang_args) {
@@ -1459,13 +1417,11 @@
 
         // Transform input headers to arguments on the clang command line.
         self.options.input_header = self.input_headers.pop();
-        self.options.extra_input_headers = self.input_headers;
-        self.options.clang_args.extend(
-            self.options.extra_input_headers.iter().flat_map(|header| {
-                iter::once("-include".into())
-                    .chain(iter::once(header.to_string()))
-            }),
-        );
+        self.options
+            .clang_args
+            .extend(self.input_headers.drain(..).flat_map(|header| {
+                iter::once("-include".into()).chain(iter::once(header))
+            }));
 
         self.options.input_unsaved_files.extend(
             self.input_header_contents
@@ -1597,13 +1553,6 @@
         self
     }
 
-    /// Add `#[must_use]` for the given type. Regular
-    /// expressions are supported.
-    pub fn must_use_type<T: Into<String>>(mut self, arg: T) -> Builder {
-        self.options.must_use_types.insert(arg.into());
-        self
-    }
-
     /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut)
     pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self {
         self.options.array_pointers_in_arguments = doit;
@@ -1651,15 +1600,6 @@
         self.options.translate_enum_integer_types = doit;
         self
     }
-
-    /// Generate types with C style naming.
-    ///
-    /// This will add prefixes to the generated type names. For example instead of a struct `A` we
-    /// will generate struct `struct_A`. Currently applies to structs, unions, and enums.
-    pub fn c_naming(mut self, doit: bool) -> Self {
-        self.options.c_naming = doit;
-        self
-    }
 }
 
 /// Configuration options for generated bindings.
@@ -1677,10 +1617,6 @@
     /// blocklisted and should not appear in the generated code.
     blocklisted_items: RegexSet,
 
-    /// The set of files whose contents should be blocklisted and should not
-    /// appear in the generated code.
-    blocklisted_files: RegexSet,
-
     /// The set of types that should be treated as opaque structures in the
     /// generated code.
     opaque_types: RegexSet,
@@ -1688,9 +1624,6 @@
     /// The explicit rustfmt path.
     rustfmt_path: Option<PathBuf>,
 
-    /// The path to which we should write a Makefile-syntax depfile (if any).
-    depfile: Option<deps::DepfileSpec>,
-
     /// The set of types that we should have bindings for in the generated
     /// code.
     ///
@@ -1852,9 +1785,6 @@
     /// The input header file.
     input_header: Option<String>,
 
-    /// Any additional input header files.
-    extra_input_headers: Vec<String>,
-
     /// Unsaved files for input.
     input_unsaved_files: Vec<clang::UnsavedFile>,
 
@@ -1948,9 +1878,6 @@
     /// The set of types that we should not derive `Hash` for.
     no_hash_types: RegexSet,
 
-    /// The set of types that we should be annotated with `#[must_use]`.
-    must_use_types: RegexSet,
-
     /// Decide if C arrays should be regular pointers in rust or array pointers
     array_pointers_in_arguments: bool,
 
@@ -1972,12 +1899,6 @@
 
     /// Always translate enum integer types to native Rust integer types.
     translate_enum_integer_types: bool,
-
-    /// Generate types with C style naming.
-    c_naming: bool,
-
-    /// Always output explicit padding fields
-    force_explicit_padding: bool,
 }
 
 /// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1994,7 +1915,6 @@
             &mut self.blocklisted_types,
             &mut self.blocklisted_functions,
             &mut self.blocklisted_items,
-            &mut self.blocklisted_files,
             &mut self.opaque_types,
             &mut self.bitfield_enums,
             &mut self.constified_enums,
@@ -2010,7 +1930,6 @@
             &mut self.no_debug_types,
             &mut self.no_default_types,
             &mut self.no_hash_types,
-            &mut self.must_use_types,
         ];
         let record_matches = self.record_matches;
         for regex_set in &mut regex_sets {
@@ -2042,10 +1961,8 @@
             blocklisted_types: Default::default(),
             blocklisted_functions: Default::default(),
             blocklisted_items: Default::default(),
-            blocklisted_files: Default::default(),
             opaque_types: Default::default(),
             rustfmt_path: Default::default(),
-            depfile: Default::default(),
             allowlisted_types: Default::default(),
             allowlisted_functions: Default::default(),
             allowlisted_vars: Default::default(),
@@ -2091,7 +2008,6 @@
             module_lines: HashMap::default(),
             clang_args: vec![],
             input_header: None,
-            extra_input_headers: vec![],
             input_unsaved_files: vec![],
             parse_callbacks: None,
             codegen_config: CodegenConfig::all(),
@@ -2116,15 +2032,12 @@
             no_debug_types: Default::default(),
             no_default_types: Default::default(),
             no_hash_types: Default::default(),
-            must_use_types: Default::default(),
             array_pointers_in_arguments: false,
             wasm_import_module_name: None,
             dynamic_library_name: None,
             dynamic_link_require_all: false,
             respect_cxx_access_specs: false,
             translate_enum_integer_types: false,
-            c_naming: false,
-            force_explicit_padding: false,
         }
     }
 }
@@ -2162,7 +2075,7 @@
     module: proc_macro2::TokenStream,
 }
 
-pub(crate) const HOST_TARGET: &str =
+pub(crate) const HOST_TARGET: &'static str =
     include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
 
 // Some architecture triplets are different between rust and libclang, see #1211
@@ -2170,8 +2083,7 @@
 fn rust_to_clang_target(rust_target: &str) -> String {
     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());
+        clang_target.push_str(&rust_target["aarch64-apple-".len()..]);
         return clang_target;
     }
     rust_target.to_owned()
@@ -2293,7 +2205,10 @@
 
             // Whether we are working with C or C++ inputs.
             let is_cpp = args_are_cpp(&options.clang_args) ||
-                options.input_header.as_deref().map_or(false, file_is_cpp);
+                options
+                    .input_header
+                    .as_ref()
+                    .map_or(false, |i| file_is_cpp(&i));
 
             let search_paths = if is_cpp {
                 clang.cpp_search_paths
@@ -2381,6 +2296,15 @@
         })
     }
 
+    /// Convert these bindings into source text (with raw lines prepended).
+    pub fn to_string(&self) -> String {
+        let mut bytes = vec![];
+        self.write(Box::new(&mut bytes) as Box<dyn Write>)
+            .expect("writing to a vec cannot fail");
+        String::from_utf8(bytes)
+            .expect("we should only write bindings that are valid utf-8")
+    }
+
     /// Write these bindings as source text to a file.
     pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
         let file = OpenOptions::new()
@@ -2395,7 +2319,7 @@
     /// Write these bindings as source text to the given `Write`able.
     pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> {
         if !self.options.disable_header_comment {
-            let version = Some("0.59.2");
+            let version = Some("0.58.1");
             let header = format!(
                 "/* automatically generated by rust-bindgen {} */\n\n",
                 version.unwrap_or("(unknown version)")
@@ -2430,7 +2354,7 @@
     }
 
     /// Gets the rustfmt path to rustfmt the generated bindings.
-    fn rustfmt_path(&self) -> io::Result<Cow<PathBuf>> {
+    fn rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>> {
         debug_assert!(self.options.rustfmt_bindings);
         if let Some(ref p) = self.options.rustfmt_path {
             return Ok(Cow::Borrowed(p));
@@ -2521,18 +2445,6 @@
     }
 }
 
-impl std::fmt::Display for Bindings {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        let mut bytes = vec![];
-        self.write(Box::new(&mut bytes) as Box<dyn Write>)
-            .expect("writing to a vec cannot fail");
-        f.write_str(
-            std::str::from_utf8(&bytes)
-                .expect("we should only write bindings that are valid utf-8"),
-        )
-    }
-}
-
 /// Determines whether the given cursor is in any of the files matched by the
 /// options.
 fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
@@ -2581,7 +2493,7 @@
     if context.options().emit_ast {
         fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
             if !cur.is_builtin() {
-                clang::ast_dump(cur, 0)
+                clang::ast_dump(&cur, 0)
             } else {
                 CXChildVisit_Continue
             }
@@ -2618,19 +2530,26 @@
     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()))
+        .filter(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
+        .next()
         .map(|v| v.split('.').collect());
-    if let Some(v) = split_v {
-        if v.len() >= 2 {
-            let maybe_major = v[0].parse::<u32>();
-            let maybe_minor = v[1].parse::<u32>();
-            if let (Ok(major), Ok(minor)) = (maybe_major, maybe_minor) {
-                return ClangVersion {
-                    parsed: Some((major, minor)),
-                    full: raw_v.clone(),
-                };
+    match split_v {
+        Some(v) => {
+            if v.len() >= 2 {
+                let maybe_major = v[0].parse::<u32>();
+                let maybe_minor = v[1].parse::<u32>();
+                match (maybe_major, maybe_minor) {
+                    (Ok(major), Ok(minor)) => {
+                        return ClangVersion {
+                            parsed: Some((major, minor)),
+                            full: raw_v.clone(),
+                        }
+                    }
+                    _ => {}
+                }
             }
         }
+        None => {}
     };
     ClangVersion {
         parsed: None,
@@ -2638,25 +2557,10 @@
     }
 }
 
-/// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found.
-fn get_target_dependent_env_var(var: &str) -> Option<String> {
-    if let Ok(target) = env::var("TARGET") {
-        if let Ok(v) = env::var(&format!("{}_{}", var, target)) {
-            return Some(v);
-        }
-        if let Ok(v) =
-            env::var(&format!("{}_{}", var, target.replace("-", "_")))
-        {
-            return Some(v);
-        }
-    }
-    env::var(var).ok()
-}
-
 /// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed
 /// line
 ///
-/// When running inside a `build.rs` script, this can be used to make cargo invalidate the
+/// When running in side a `build.rs` script, this can be used to make cargo invalidate the
 /// generated bindings whenever any of the files included from the header change:
 /// ```
 /// use bindgen::builder;
diff --git a/src/log_stubs.rs b/src/log_stubs.rs
index 8315983..4af496c 100644
--- a/src/log_stubs.rs
+++ b/src/log_stubs.rs
@@ -1,32 +1,32 @@
 #![allow(unused)]
 
 macro_rules! log {
-    (target: $target:expr, $lvl:expr, $($arg:tt)+) => {{
+    (target: $target:expr, $lvl:expr, $($arg:tt)+) => {
         let _ = $target;
         let _ = log!($lvl, $($arg)+);
-    }};
+    };
     ($lvl:expr, $($arg:tt)+) => {{
         let _ = $lvl;
         let _ = format_args!($($arg)+);
     }};
 }
 macro_rules! error {
-    (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
-    ($($arg:tt)+) => { log!("", $($arg)+) };
+    (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); };
+    ($($arg:tt)*) => { log!("", $($arg)*); };
 }
 macro_rules! warn {
-    (target: $target:expr, $($arg:tt)*) => { log!(target: $target, "", $($arg)*) };
-    ($($arg:tt)*) => { log!("", $($arg)*) };
+    (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); };
+    ($($arg:tt)*) => { log!("", $($arg)*); };
 }
 macro_rules! info {
-    (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
-    ($($arg:tt)+) => { log!("", $($arg)+) };
+    (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); };
+    ($($arg:tt)*) => { log!("", $($arg)*); };
 }
 macro_rules! debug {
-    (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
-    ($($arg:tt)+) => { log!("", $($arg)+) };
+    (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); };
+    ($($arg:tt)*) => { log!("", $($arg)*); };
 }
 macro_rules! trace {
-    (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) };
-    ($($arg:tt)+) => { log!("", $($arg)+) };
+    (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); };
+    ($($arg:tt)*) => { log!("", $($arg)*); };
 }
diff --git a/src/main.rs b/src/main.rs
index f3398db..1768ed8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -37,7 +37,7 @@
     );
 
     if expected_version.is_some() {
-        // assert_eq!(version.parsed, version.parsed);
+        assert_eq!(version.parsed, version.parsed);
     }
 }
 
@@ -45,7 +45,9 @@
     #[cfg(feature = "logging")]
     env_logger::init();
 
-    match builder_from_flags(env::args()) {
+    let bind_args: Vec<_> = env::args().collect();
+
+    match builder_from_flags(bind_args.into_iter()) {
         Ok((builder, output, verbose)) => {
             clang_version_check();
             let builder_result = panic::catch_unwind(|| {
diff --git a/src/options.rs b/src/options.rs
index 94f3047..70b7990 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -23,17 +23,13 @@
     );
 
     let matches = App::new("bindgen")
-        .version(Some("0.59.2").unwrap_or("unknown"))
+        .version(Some("0.58.1").unwrap_or("unknown"))
         .about("Generates Rust bindings from C/C++ headers.")
         .usage("bindgen [FLAGS] [OPTIONS] <header> -- <clang-args>...")
         .args(&[
             Arg::with_name("header")
                 .help("C or C++ header file")
                 .required(true),
-            Arg::with_name("depfile")
-                .long("depfile")
-                .takes_value(true)
-                .help("Path to write depfile to"),
             Arg::with_name("default-enum-style")
                 .long("default-enum-style")
                 .help("The default style of code used to generate enums.")
@@ -164,14 +160,6 @@
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
-            Arg::with_name("blocklist-file")
-                .alias("blacklist-file")
-                .long("blocklist-file")
-                .help("Mark all contents of <path> as hidden.")
-                .value_name("path")
-                .takes_value(true)
-                .multiple(true)
-                .number_of_values(1),
             Arg::with_name("no-layout-tests")
                 .long("no-layout-tests")
                 .help("Avoid generating layout tests for any type."),
@@ -494,13 +482,6 @@
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
-            Arg::with_name("must-use-type")
-                .long("must-use-type")
-                .help("Add #[must_use] annotation to types matching <regex>.")
-                .value_name("regex")
-                .takes_value(true)
-                .multiple(true)
-                .number_of_values(1),
             Arg::with_name("enable-function-attribute-detection")
                 .long("enable-function-attribute-detection")
                 .help(
@@ -528,12 +509,6 @@
             Arg::with_name("translate-enum-integer-types")
                 .long("translate-enum-integer-types")
                 .help("Always translate enum integer types to native Rust integer types."),
-            Arg::with_name("c-naming")
-                .long("c-naming")
-                .help("Generate types with C style naming."),
-            Arg::with_name("explicit-padding")
-                .long("explicit-padding")
-                .help("Always output explicit padding fields."),
         ]) // .args()
         .get_matches_from(args);
 
@@ -638,12 +613,6 @@
         }
     }
 
-    if let Some(hidden_files) = matches.values_of("blocklist-file") {
-        for file in hidden_files {
-            builder = builder.blocklist_file(file);
-        }
-    }
-
     if matches.is_present("builtins") {
         builder = builder.emit_builtins();
     }
@@ -731,7 +700,7 @@
 
     if let Some(what_to_generate) = matches.value_of("generate") {
         let mut config = CodegenConfig::empty();
-        for what in what_to_generate.split(',') {
+        for what in what_to_generate.split(",") {
             match what {
                 "functions" => config.insert(CodegenConfig::FUNCTIONS),
                 "types" => config.insert(CodegenConfig::TYPES),
@@ -879,14 +848,8 @@
 
     let output = if let Some(path) = matches.value_of("output") {
         let file = File::create(path)?;
-        if let Some(depfile) = matches.value_of("depfile") {
-            builder = builder.depfile(path, depfile);
-        }
         Box::new(io::BufWriter::new(file)) as Box<dyn io::Write>
     } else {
-        if let Some(depfile) = matches.value_of("depfile") {
-            builder = builder.depfile("-", depfile);
-        }
         Box::new(io::BufWriter::new(io::stdout())) as Box<dyn io::Write>
     };
 
@@ -964,12 +927,6 @@
         }
     }
 
-    if let Some(must_use_type) = matches.values_of("must-use-type") {
-        for regex in must_use_type {
-            builder = builder.must_use_type(regex);
-        }
-    }
-
     if let Some(dynamic_library_name) = matches.value_of("dynamic-loading") {
         builder = builder.dynamic_library_name(dynamic_library_name);
     }
@@ -986,14 +943,6 @@
         builder = builder.translate_enum_integer_types(true);
     }
 
-    if matches.is_present("c-naming") {
-        builder = builder.c_naming(true);
-    }
-
-    if matches.is_present("explicit-padding") {
-        builder = builder.explicit_padding(true);
-    }
-
     let verbose = matches.is_present("verbose");
 
     Ok((builder, output, verbose))