Snap for 8730993 from 44796ba17fff8dca24585e68db7b9cd47789f07c to mainline-tzdata3-release

Change-Id: I19b918a1bb82f9a5c22075288ca2d3f156580e94
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0b82cd9..3fafd9b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -54,7 +54,6 @@
   buck:
     name: Buck
     runs-on: ubuntu-latest
-    if: github.event_name != 'pull_request'
     steps:
       - uses: actions/checkout@v2
       - uses: dtolnay/rust-toolchain@stable
@@ -81,7 +80,6 @@
   bazel:
     name: Bazel
     runs-on: ubuntu-latest
-    if: github.event_name != 'pull_request'
     steps:
       - uses: actions/checkout@v2
       - name: Install Bazel
diff --git a/Android.bp b/Android.bp
index 05ef387..014c937 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,13 +51,6 @@
     ],
     shared_libs: ["libc++"],
     host_supported: true,
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.bluetooth",
-        "com.android.compos",
-        "com.android.virt",
-    ],
-    min_sdk_version: "29",
 }
 
 cc_library_static {
@@ -67,11 +60,8 @@
     srcs: ["src/cxx.cc"],
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth",
-        "com.android.compos",
-        "com.android.virt",
+        "com.android.bluetooth.updatable",
     ],
-    min_sdk_version: "29",
 }
 
 cc_library_static {
diff --git a/BUCK b/BUCK
index 86174e9..da6fcb2 100644
--- a/BUCK
+++ b/BUCK
@@ -25,19 +25,19 @@
 cxx_library(
     name = "core",
     srcs = ["src/cxx.cc"],
+    visibility = ["PUBLIC"],
+    header_namespace = "rust",
     exported_headers = {
         "cxx.h": "include/cxx.h",
     },
     exported_linker_flags = ["-lstdc++"],
-    header_namespace = "rust",
-    visibility = ["PUBLIC"],
 )
 
 rust_library(
     name = "macro",
     srcs = glob(["macro/src/**"]),
-    crate = "cxxbridge_macro",
     proc_macro = True,
+    crate = "cxxbridge_macro",
     deps = [
         "//third-party:proc-macro2",
         "//third-party:quote",
diff --git a/BUILD b/BUILD
index c2c2edf..24a1c8b 100644
--- a/BUILD
+++ b/BUILD
@@ -1,5 +1,5 @@
 load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_binary", "rust_library")
+load("//tools/bazel:rust.bzl", "rust_binary", "rust_library")
 
 rust_library(
     name = "cxx",
diff --git a/Cargo.toml b/Cargo.toml
index 0414c72..e2b189e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cxx"
-version = "1.0.54" # remember to update html_root_url
+version = "1.0.42" # remember to update html_root_url
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 edition = "2018"
 links = "cxxbridge1"
@@ -21,15 +21,15 @@
 "c++20" = ["cxxbridge-flags/c++20"]
 
 [dependencies]
-cxxbridge-macro = { version = "=1.0.54", path = "macro" }
+cxxbridge-macro = { version = "=1.0.42", path = "macro" }
 link-cplusplus = "1.0"
 
 [build-dependencies]
 cc = "1.0.49"
-cxxbridge-flags = { version = "=1.0.54", path = "flags", default-features = false }
+cxxbridge-flags = { version = "=1.0.42", path = "flags", default-features = false }
 
 [dev-dependencies]
-cxx-build = { version = "=1.0.54", path = "gen/build" }
+cxx-build = { version = "=1.0.42", path = "gen/build" }
 cxx-gen = { version = "0.7", path = "gen/lib" }
 cxx-test-suite = { version = "0", path = "tests/ffi" }
 rustversion = "1.0"
diff --git a/METADATA b/METADATA
index 85611d6..2b3490c 100644
--- a/METADATA
+++ b/METADATA
@@ -1,5 +1,7 @@
 name: "cxx"
-description: "Safe interop between Rust and C++"
+description:
+    "Safe interop between Rust and C++"
+
 third_party {
   url {
     type: HOMEPAGE
@@ -9,11 +11,7 @@
     type: GIT
     value: "https://github.com/dtolnay/cxx.git"
   }
-  version: "36d9ac1fab726e14305ce1919ebf8a3d64949d30"
+  version: "4ab117115718908768df8366ac130bbbb3478331"
+  last_upgrade_date { year: 2021 month: 2 day: 17 }
   license_type: NOTICE
-  last_upgrade_date {
-    year: 2021
-    month: 9
-    day: 23
-  }
 }
diff --git a/WORKSPACE b/WORKSPACE
index 08aacf2..17a0af5 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,30 +1,26 @@
 workspace(name = "cxx.rs")
 
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("//tools/bazel:vendor.bzl", "vendor")
 
 http_archive(
     name = "rules_rust",
-    sha256 = "697a6f4f2adbd1b00f792346d6eca4cd45f691be63069c7d7ebf4fcf82a377a8",
-    strip_prefix = "rules_rust-8bad4c5e4e53d9f6f8d4d5228e26a44d92f37ab2",
+    sha256 = "e6d835ee673f388aa5b62dc23d82db8fc76497e93fa47d8a4afe97abaf09b10d",
+    strip_prefix = "rules_rust-f37b9d6a552e9412285e627f30cb124e709f4f7a",
     urls = [
-        # Master branch as of 2021-04-11
-        "https://github.com/bazelbuild/rules_rust/archive/8bad4c5e4e53d9f6f8d4d5228e26a44d92f37ab2.tar.gz",
+        # Master branch as of 2021-01-27
+        "https://github.com/bazelbuild/rules_rust/archive/f37b9d6a552e9412285e627f30cb124e709f4f7a.tar.gz",
     ],
 )
 
 load("@rules_rust//rust:repositories.bzl", "rust_repositories")
 
-RUST_VERSION = "1.54.0"
-
 rust_repositories(
     edition = "2018",
-    version = RUST_VERSION,
+    version = "1.50.0",
 )
 
-load("//tools/bazel:vendor.bzl", "vendor")
-
 vendor(
     name = "third-party",
     lockfile = "//third-party:Cargo.lock",
-    cargo_version = RUST_VERSION,
 )
diff --git a/book/src/binding/str.md b/book/src/binding/str.md
index 9c1e0a7..a4820aa 100644
--- a/book/src/binding/str.md
+++ b/book/src/binding/str.md
@@ -30,7 +30,6 @@
   const char *data() const noexcept;
   size_t size() const noexcept;
   size_t length() const noexcept;
-  bool empty() const noexcept;
 
   using iterator = const char *;
   using const_iterator = const char *;
diff --git a/book/src/binding/string.md b/book/src/binding/string.md
index d564e00..a7d0790 100644
--- a/book/src/binding/string.md
+++ b/book/src/binding/string.md
@@ -23,10 +23,6 @@
   String(const char *);
   String(const char *, size_t);
 
-  // Throws std::invalid_argument if not utf-16.
-  String(const char16_t *);
-  String(const char16_t *, size_t);
-
   String &operator=(const String &) noexcept;
   String &operator=(String &&) noexcept;
 
@@ -36,13 +32,9 @@
   const char *data() const noexcept;
   size_t size() const noexcept;
   size_t length() const noexcept;
-  bool empty() const noexcept;
 
   const char *c_str() noexcept;
 
-  size_t capacity() const noexcept;
-  void reserve(size_t new_cap) noexcept;
-
   using iterator = char *;
   iterator begin() noexcept;
   iterator end() noexcept;
diff --git a/book/src/build/bazel.md b/book/src/build/bazel.md
index 8f91055..08edb19 100644
--- a/book/src/build/bazel.md
+++ b/book/src/build/bazel.md
@@ -70,7 +70,7 @@
 # demo/BUILD
 
 load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_binary")
+load("//tools/bazel:rust.bzl", "rust_binary")
 load("//tools/bazel:rust_cxx_bridge.bzl", "rust_cxx_bridge")
 
 rust_binary(
diff --git a/book/src/build/cmake.md b/book/src/build/cmake.md
index 4b50746..ed3cb61 100644
--- a/book/src/build/cmake.md
+++ b/book/src/build/cmake.md
@@ -22,10 +22,3 @@
   - Tested on Windows 10 with MSVC, and on Linux
 
 ---
-
-- **<https://github.com/trondhe/rusty_cmake>**
-
-  - Alias target that can be linked into a C++ project
-  - Tested on Windows 10 with GNU target, and on Linux
-
----
diff --git a/build.rs b/build.rs
index a953639..f799441 100644
--- a/build.rs
+++ b/build.rs
@@ -28,12 +28,6 @@
                 rustc.version,
             );
         }
-
-        if rustc.minor < 52 {
-            // #![deny(unsafe_op_in_unsafe_fn)].
-            // https://github.com/rust-lang/rust/issues/71668
-            println!("cargo:rustc-cfg=no_unsafe_op_in_unsafe_fn_lint");
-        }
     }
 }
 
diff --git a/demo/BUILD b/demo/BUILD
index 4ab5ecb..cce8119 100644
--- a/demo/BUILD
+++ b/demo/BUILD
@@ -1,5 +1,5 @@
 load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_binary")
+load("//tools/bazel:rust.bzl", "rust_binary")
 load("//tools/bazel:rust_cxx_bridge.bzl", "rust_cxx_bridge")
 
 rust_binary(
diff --git a/flags/Cargo.toml b/flags/Cargo.toml
index baf1157..87c796c 100644
--- a/flags/Cargo.toml
+++ b/flags/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cxxbridge-flags"
-version = "1.0.54"
+version = "1.0.42"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
diff --git a/gen/build/Cargo.toml b/gen/build/Cargo.toml
index 393fc1c..33f17df 100644
--- a/gen/build/Cargo.toml
+++ b/gen/build/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cxx-build"
-version = "1.0.54"
+version = "1.0.42"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -21,7 +21,7 @@
 proc-macro2 = { version = "1.0.26", default-features = false, features = ["span-locations"] }
 quote = { version = "1.0", default-features = false }
 scratch = "1.0"
-syn = { version = "1.0.70", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
+syn = { version = "1.0.68", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
 
 [dev-dependencies]
 cxx-gen = { version = "0.7", path = "../lib" }
diff --git a/gen/build/src/lib.rs b/gen/build/src/lib.rs
index b8a463c..63b2cf6 100644
--- a/gen/build/src/lib.rs
+++ b/gen/build/src/lib.rs
@@ -51,7 +51,6 @@
     clippy::doc_markdown,
     clippy::drop_copy,
     clippy::enum_glob_use,
-    clippy::if_same_then_else,
     clippy::inherent_to_string,
     clippy::items_after_statements,
     clippy::let_underscore_drop,
diff --git a/gen/cmd/Cargo.toml b/gen/cmd/Cargo.toml
index 4b3a299..7db0206 100644
--- a/gen/cmd/Cargo.toml
+++ b/gen/cmd/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cxxbridge-cmd"
-version = "1.0.54"
+version = "1.0.42"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -20,7 +20,7 @@
 codespan-reporting = "0.11"
 proc-macro2 = { version = "1.0.26", default-features = false, features = ["span-locations"] }
 quote = { version = "1.0", default-features = false }
-syn = { version = "1.0.70", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
+syn = { version = "1.0.68", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
 
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
diff --git a/gen/cmd/src/main.rs b/gen/cmd/src/main.rs
index 1c15db6..f419dad 100644
--- a/gen/cmd/src/main.rs
+++ b/gen/cmd/src/main.rs
@@ -3,7 +3,6 @@
     clippy::cognitive_complexity,
     clippy::default_trait_access,
     clippy::enum_glob_use,
-    clippy::if_same_then_else,
     clippy::inherent_to_string,
     clippy::items_after_statements,
     clippy::large_enum_variant,
diff --git a/gen/lib/Cargo.toml b/gen/lib/Cargo.toml
index 37d8168..ff33d97 100644
--- a/gen/lib/Cargo.toml
+++ b/gen/lib/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cxx-gen"
-version = "0.7.54"
+version = "0.7.42"
 authors = ["Adrian Taylor <adetaylor@chromium.org>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -15,7 +15,7 @@
 codespan-reporting = "0.11"
 proc-macro2 = { version = "1.0.26", default-features = false, features = ["span-locations"] }
 quote = { version = "1.0", default-features = false }
-syn = { version = "1.0.70", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
+syn = { version = "1.0.68", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
 
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
diff --git a/gen/lib/src/lib.rs b/gen/lib/src/lib.rs
index 411953b..e3eca5e 100644
--- a/gen/lib/src/lib.rs
+++ b/gen/lib/src/lib.rs
@@ -12,7 +12,6 @@
     clippy::cast_sign_loss,
     clippy::default_trait_access,
     clippy::enum_glob_use,
-    clippy::if_same_then_else,
     clippy::inherent_to_string,
     clippy::items_after_statements,
     clippy::match_bool,
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index 7ac9209..eaaa08d 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -30,7 +30,6 @@
     pub relocatable: bool,
     pub friend_impl: bool,
     pub is_complete: bool,
-    pub destroy: bool,
     pub deleter_if: bool,
     pub content: Content<'a>,
 }
@@ -335,14 +334,6 @@
         writeln!(out, "}};");
     }
 
-    if builtin.destroy {
-        out.next_section();
-        writeln!(out, "template <typename T>");
-        writeln!(out, "void destroy(T *ptr) {{");
-        writeln!(out, "  ptr->~T();");
-        writeln!(out, "}}");
-    }
-
     if builtin.deleter_if {
         out.next_section();
         writeln!(out, "template <bool> struct deleter_if {{");
diff --git a/gen/src/check.rs b/gen/src/check.rs
index 15add20..35929ad 100644
--- a/gen/src/check.rs
+++ b/gen/src/check.rs
@@ -4,7 +4,7 @@
 use quote::{quote, quote_spanned};
 use std::path::{Component, Path};
 
-pub(super) use crate::syntax::check::{typecheck, Generator};
+pub(super) use crate::syntax::check::typecheck;
 
 pub(super) fn precheck(cx: &mut Errors, apis: &[Api], opt: &Opt) {
     if !opt.allow_dot_includes {
diff --git a/gen/src/error.rs b/gen/src/error.rs
index 3672e26..2c8287f 100644
--- a/gen/src/error.rs
+++ b/gen/src/error.rs
@@ -87,11 +87,12 @@
 
     impl<E: StdError> Display for Report<E> {
         fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-            write!(formatter, "{}", self.0)?;
+            Display::fmt(&self.0, formatter)?;
             let mut error: &dyn StdError = &self.0;
 
             while let Some(cause) = error.source() {
-                write!(formatter, "\n\nCaused by:\n    {}", cause)?;
+                formatter.write_str("\n\nCaused by:\n    ")?;
+                Display::fmt(cause, formatter)?;
                 error = cause;
             }
 
diff --git a/gen/src/mod.rs b/gen/src/mod.rs
index d8b90d0..3d12c71 100644
--- a/gen/src/mod.rs
+++ b/gen/src/mod.rs
@@ -130,8 +130,7 @@
     let ref types = Types::collect(errors, apis);
     check::precheck(errors, apis, opt);
     errors.propagate()?;
-    let generator = check::Generator::Build;
-    check::typecheck(errors, apis, types, generator);
+    check::typecheck(errors, apis, types);
     errors.propagate()?;
 
     // Some callers may wish to generate both header and implementation from the
diff --git a/gen/src/write.rs b/gen/src/write.rs
index a3b9c9f..9f9c039 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -9,8 +9,8 @@
 use crate::syntax::symbol::Symbol;
 use crate::syntax::trivial::{self, TrivialReason};
 use crate::syntax::{
-    derive, mangle, Api, Doc, Enum, EnumRepr, ExternFn, ExternType, Pair, Signature, Struct, Trait,
-    Type, TypeAlias, Types, Var,
+    derive, mangle, Api, Enum, ExternFn, ExternType, Pair, Signature, Struct, Trait, Type,
+    TypeAlias, Types, Var,
 };
 use proc_macro2::Ident;
 
@@ -101,10 +101,10 @@
             }
             Api::Enum(enm) => {
                 out.next_section();
-                if !out.types.cxx.contains(&enm.name.rust) {
-                    write_enum(out, enm);
-                } else if !enm.variants_from_header {
+                if out.types.cxx.contains(&enm.name.rust) {
                     check_enum(out, enm);
+                } else {
+                    write_enum(out, enm);
                 }
             }
             Api::RustType(ety) => {
@@ -249,24 +249,14 @@
         writeln!(out, "{};", field.name.cxx);
     }
 
-    out.next_section();
+    writeln!(out);
 
     for method in methods {
-        if !method.doc.is_empty() {
-            out.next_section();
-        }
-        for line in method.doc.to_string().lines() {
-            writeln!(out, "  //{}", line);
-        }
         write!(out, "  ");
         let sig = &method.sig;
         let local_name = method.name.cxx.to_string();
-        let indirect_call = false;
-        write_rust_function_shim_decl(out, &local_name, sig, indirect_call);
+        write_rust_function_shim_decl(out, &local_name, sig, false);
         writeln!(out, ";");
-        if !method.doc.is_empty() {
-            out.next_section();
-        }
     }
 
     if operator_eq {
@@ -317,12 +307,8 @@
 }
 
 fn write_enum_decl(out: &mut OutFile, enm: &Enum) {
-    let repr = match &enm.repr {
-        EnumRepr::Foreign { .. } => return,
-        EnumRepr::Native { atom, .. } => *atom,
-    };
     write!(out, "enum class {} : ", enm.name.cxx);
-    write_atom(out, repr);
+    write_atom(out, enm.repr);
     writeln!(out, ";");
 }
 
@@ -346,22 +332,12 @@
         ety.name.cxx,
     );
 
-    for (i, method) in methods.iter().enumerate() {
-        if i > 0 && !method.doc.is_empty() {
-            out.next_section();
-        }
-        for line in method.doc.to_string().lines() {
-            writeln!(out, "  //{}", line);
-        }
+    for method in methods {
         write!(out, "  ");
         let sig = &method.sig;
         let local_name = method.name.cxx.to_string();
-        let indirect_call = false;
-        write_rust_function_shim_decl(out, &local_name, sig, indirect_call);
+        write_rust_function_shim_decl(out, &local_name, sig, false);
         writeln!(out, ";");
-        if !method.doc.is_empty() {
-            out.next_section();
-        }
     }
 
     writeln!(out, "  ~{}() = delete;", ety.name.cxx);
@@ -380,10 +356,6 @@
 }
 
 fn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
-    let repr = match &enm.repr {
-        EnumRepr::Foreign { .. } => return,
-        EnumRepr::Native { atom, .. } => *atom,
-    };
     out.set_namespace(&enm.name.namespace);
     let guard = format!("CXXBRIDGE1_ENUM_{}", enm.name.to_symbol());
     writeln!(out, "#ifndef {}", guard);
@@ -392,7 +364,7 @@
         writeln!(out, "//{}", line);
     }
     write!(out, "enum class {} : ", enm.name.cxx);
-    write_atom(out, repr);
+    write_atom(out, enm.repr);
     writeln!(out, " {{");
     for variant in &enm.variants {
         for line in variant.doc.to_string().lines() {
@@ -405,10 +377,6 @@
 }
 
 fn check_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
-    let repr = match &enm.repr {
-        EnumRepr::Foreign { .. } => return,
-        EnumRepr::Native { atom, .. } => *atom,
-    };
     out.set_namespace(&enm.name.namespace);
     out.include.type_traits = true;
     writeln!(
@@ -417,11 +385,11 @@
         enm.name.cxx,
     );
     write!(out, "static_assert(sizeof({}) == sizeof(", enm.name.cxx);
-    write_atom(out, repr);
+    write_atom(out, enm.repr);
     writeln!(out, "), \"incorrect size\");");
     for variant in &enm.variants {
         write!(out, "static_assert(static_cast<");
-        write_atom(out, repr);
+        write_atom(out, enm.repr);
         writeln!(
             out,
             ">({}::{}) == {}, \"disagrees with the value in #[cxx::bridge]\");",
@@ -856,8 +824,7 @@
 
     out.next_section();
     let c_trampoline = mangle::c_trampoline(efn, var, out.types).to_string();
-    let doc = Doc::new();
-    write_rust_function_shim_impl(out, &c_trampoline, f, &doc, &r_trampoline, indirect_call);
+    write_rust_function_shim_impl(out, &c_trampoline, f, &r_trampoline, indirect_call);
 }
 
 fn write_rust_function_decl<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
@@ -927,6 +894,9 @@
 
 fn write_rust_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
     out.set_namespace(&efn.name.namespace);
+    for line in efn.doc.to_string().lines() {
+        writeln!(out, "//{}", line);
+    }
     let local_name = match &efn.sig.receiver {
         None => efn.name.cxx.to_string(),
         Some(receiver) => format!(
@@ -935,10 +905,9 @@
             efn.name.cxx,
         ),
     };
-    let doc = &efn.doc;
     let invoke = mangle::extern_fn(efn, out.types);
     let indirect_call = false;
-    write_rust_function_shim_impl(out, &local_name, efn, doc, &invoke, indirect_call);
+    write_rust_function_shim_impl(out, &local_name, efn, &invoke, indirect_call);
 }
 
 fn write_rust_function_shim_decl(
@@ -978,7 +947,6 @@
     out: &mut OutFile,
     local_name: &str,
     sig: &Signature,
-    doc: &Doc,
     invoke: &Symbol,
     indirect_call: bool,
 ) {
@@ -986,12 +954,6 @@
         // We've already defined this inside the struct.
         return;
     }
-    if sig.receiver.is_none() {
-        // Member functions already documented at their declaration.
-        for line in doc.to_string().lines() {
-            writeln!(out, "//{}", line);
-        }
-    }
     write_rust_function_shim_decl(out, local_name, sig, indirect_call);
     if out.header {
         writeln!(out, ";");
@@ -1467,7 +1429,7 @@
     );
     writeln!(
         out,
-        "void cxxbridge1$rust_vec${}$reserve_total(::rust::Vec<{}> *ptr, ::std::size_t new_cap) noexcept;",
+        "void cxxbridge1$rust_vec${}$reserve_total(::rust::Vec<{}> *ptr, ::std::size_t cap) noexcept;",
         instance, inner,
     );
     writeln!(
@@ -1562,12 +1524,12 @@
     begin_function_definition(out);
     writeln!(
         out,
-        "void Vec<{}>::reserve_total(::std::size_t new_cap) noexcept {{",
+        "void Vec<{}>::reserve_total(::std::size_t cap) noexcept {{",
         inner,
     );
     writeln!(
         out,
-        "  return cxxbridge1$rust_vec${}$reserve_total(this, new_cap);",
+        "  return cxxbridge1$rust_vec${}$reserve_total(this, cap);",
         instance,
     );
     writeln!(out, "}}");
@@ -1604,7 +1566,11 @@
         // know at code generation time, so we generate both C++ and Rust side
         // bindings for a "new" method anyway. But the Rust code can't be called
         // for Opaque types because the 'new' method is not implemented.
-        UniquePtr::Ident(ident) => out.types.is_maybe_trivial(ident),
+        UniquePtr::Ident(ident) => {
+            out.types.structs.contains_key(ident)
+                || out.types.enums.contains_key(ident)
+                || out.types.aliases.contains_key(ident)
+        }
         UniquePtr::CxxVector(_) => false,
     };
 
@@ -1712,7 +1678,9 @@
     // know at code generation time, so we generate both C++ and Rust side
     // bindings for a "new" method anyway. But the Rust code can't be called for
     // Opaque types because the 'new' method is not implemented.
-    let can_construct_from_value = out.types.is_maybe_trivial(ident);
+    let can_construct_from_value = out.types.structs.contains_key(ident)
+        || out.types.enums.contains_key(ident)
+        || out.types.aliases.contains_key(ident);
 
     writeln!(
         out,
@@ -1835,8 +1803,6 @@
     let instance = element.to_mangled(out.types);
 
     out.include.cstddef = true;
-    out.include.utility = true;
-    out.builtin.destroy = true;
 
     writeln!(
         out,
@@ -1845,7 +1811,6 @@
     );
     writeln!(out, "  return s.size();");
     writeln!(out, "}}");
-
     writeln!(
         out,
         "{} *cxxbridge1$std$vector${}$get_unchecked(::std::vector<{}> *s, ::std::size_t pos) noexcept {{",
@@ -1854,26 +1819,6 @@
     writeln!(out, "  return &(*s)[pos];");
     writeln!(out, "}}");
 
-    if out.types.is_maybe_trivial(element) {
-        writeln!(
-            out,
-            "void cxxbridge1$std$vector${}$push_back(::std::vector<{}> *v, {} *value) noexcept {{",
-            instance, inner, inner,
-        );
-        writeln!(out, "  v->push_back(::std::move(*value));");
-        writeln!(out, "  ::rust::destroy(value);");
-        writeln!(out, "}}");
-
-        writeln!(
-            out,
-            "void cxxbridge1$std$vector${}$pop_back(::std::vector<{}> *v, {} *out) noexcept {{",
-            instance, inner, inner,
-        );
-        writeln!(out, "  ::new (out) {}(::std::move(v->back()));", inner);
-        writeln!(out, "  v->pop_back();");
-        writeln!(out, "}}");
-    }
-
     out.include.memory = true;
     write_unique_ptr_common(out, UniquePtr::CxxVector(element));
 }
diff --git a/include/cxx.h b/include/cxx.h
index dffcb01..cdc63fb 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -43,8 +43,6 @@
   String(const std::string &);
   String(const char *);
   String(const char *, std::size_t);
-  String(const char16_t *);
-  String(const char16_t *, std::size_t);
 
   String &operator=(const String &) &noexcept;
   String &operator=(String &&) &noexcept;
@@ -55,13 +53,9 @@
   const char *data() const noexcept;
   std::size_t size() const noexcept;
   std::size_t length() const noexcept;
-  bool empty() const noexcept;
 
   const char *c_str() noexcept;
 
-  std::size_t capacity() const noexcept;
-  void reserve(size_t new_cap) noexcept;
-
   using iterator = char *;
   iterator begin() noexcept;
   iterator end() noexcept;
@@ -111,7 +105,6 @@
   const char *data() const noexcept;
   std::size_t size() const noexcept;
   std::size_t length() const noexcept;
-  bool empty() const noexcept;
 
   // Important in order for System V ABI to pass in registers.
   Str(const Str &) noexcept = default;
@@ -341,7 +334,7 @@
   Vec(unsafe_bitcopy_t, const Vec &) noexcept;
 
 private:
-  void reserve_total(std::size_t new_cap) noexcept;
+  void reserve_total(std::size_t cap) noexcept;
   void set_len(std::size_t len) noexcept;
   void drop() noexcept;
 
@@ -482,7 +475,7 @@
 #define CXXBRIDGE1_RUST_FN
 template <typename Ret, typename... Args>
 Ret Fn<Ret(Args...)>::operator()(Args... args) const noexcept {
-  return (*this->trampoline)(std::forward<Args>(args)..., this->fn);
+  return (*this->trampoline)(std::move(args)..., this->fn);
 }
 
 template <typename Ret, typename... Args>
@@ -543,8 +536,8 @@
 template <typename T>
 T &Slice<T>::operator[](std::size_t n) const noexcept {
   assert(n < this->size());
-  auto ptr = static_cast<char *>(slicePtr(this)) + size_of<T>() * n;
-  return *reinterpret_cast<T *>(ptr);
+  auto pos = static_cast<char *>(slicePtr(this)) + size_of<T>() * n;
+  return *reinterpret_cast<T *>(pos);
 }
 
 template <typename T>
@@ -582,8 +575,8 @@
 template <typename T>
 typename Slice<T>::iterator::reference Slice<T>::iterator::operator[](
     typename Slice<T>::iterator::difference_type n) const noexcept {
-  auto ptr = static_cast<char *>(this->pos) + this->stride * n;
-  return *reinterpret_cast<T *>(ptr);
+  auto pos = static_cast<char *>(this->pos) + this->stride * n;
+  return *reinterpret_cast<T *>(pos);
 }
 
 template <typename T>
diff --git a/macro/Cargo.toml b/macro/Cargo.toml
index 65f15c3..a3df101 100644
--- a/macro/Cargo.toml
+++ b/macro/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cxxbridge-macro"
-version = "1.0.54"
+version = "1.0.42"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -14,20 +14,10 @@
 [lib]
 proc-macro = true
 
-[features]
-experimental = ["clang-ast", "flate2", "memmap", "serde", "serde_json"]
-
 [dependencies]
 proc-macro2 = "1.0"
 quote = "1.0.4"
-syn = { version = "1.0.70", features = ["full"] }
-
-# optional dependencies
-clang-ast = { version = "0.1", optional = true }
-flate2 = { version = "1.0", optional = true }
-memmap = { version = "0.7", optional = true }
-serde = { version = "1.0", optional = true, features = ["derive"] }
-serde_json = { version = "1.0", optional = true }
+syn = { version = "1.0.68", features = ["full"] }
 
 [dev-dependencies]
 cxx = { version = "1.0", path = ".." }
diff --git a/macro/src/clang.rs b/macro/src/clang.rs
deleted file mode 100644
index 099d5a6..0000000
--- a/macro/src/clang.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use serde::{Deserialize, Serialize};
-
-pub type Node = clang_ast::Node<Clang>;
-
-#[derive(Deserialize, Serialize)]
-pub enum Clang {
-    NamespaceDecl(NamespaceDecl),
-    EnumDecl(EnumDecl),
-    EnumConstantDecl(EnumConstantDecl),
-    ImplicitCastExpr,
-    ConstantExpr(ConstantExpr),
-    Unknown,
-}
-
-#[derive(Deserialize, Serialize)]
-pub struct NamespaceDecl {
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub name: Option<Box<str>>,
-}
-
-#[derive(Deserialize, Serialize)]
-pub struct EnumDecl {
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub name: Option<Box<str>>,
-    #[serde(
-        rename = "fixedUnderlyingType",
-        skip_serializing_if = "Option::is_none"
-    )]
-    pub fixed_underlying_type: Option<Type>,
-}
-
-#[derive(Deserialize, Serialize)]
-pub struct EnumConstantDecl {
-    pub name: Box<str>,
-}
-
-#[derive(Deserialize, Serialize)]
-pub struct ConstantExpr {
-    pub value: Box<str>,
-}
-
-#[derive(Deserialize, Serialize)]
-pub struct Type {
-    #[serde(rename = "qualType")]
-    pub qual_type: Box<str>,
-    #[serde(rename = "desugaredQualType", skip_serializing_if = "Option::is_none")]
-    pub desugared_qual_type: Option<Box<str>>,
-}
-
-#[cfg(all(test, target_pointer_width = "64"))]
-const _: [(); std::mem::size_of::<Node>()] = [(); 88];
diff --git a/macro/src/derive.rs b/macro/src/derive.rs
index ea36e3e..2f77095 100644
--- a/macro/src/derive.rs
+++ b/macro/src/derive.rs
@@ -151,7 +151,6 @@
     let fields = strct.fields.iter().map(|field| &field.name.rust);
 
     quote_spanned! {span=>
-        #[allow(clippy::derivable_impls)] // different spans than the derived impl
         impl #generics ::std::default::Default for #ident #generics {
             fn default() -> Self {
                 #ident {
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 5a879cb..7c194ad 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -14,7 +14,7 @@
 use proc_macro2::{Ident, Span, TokenStream};
 use quote::{format_ident, quote, quote_spanned, ToTokens};
 use std::mem;
-use syn::{parse_quote, punctuated, Generics, Lifetime, Result, Token};
+use syn::{parse_quote, punctuated, Lifetime, Result, Token};
 
 pub fn bridge(mut ffi: Module) -> Result<TokenStream> {
     let ref mut errors = Errors::new();
@@ -32,14 +32,10 @@
     let content = mem::take(&mut ffi.content);
     let trusted = ffi.unsafety.is_some();
     let namespace = &ffi.namespace;
-    let ref mut apis = syntax::parse_items(errors, content, trusted, namespace);
-    #[cfg(feature = "experimental")]
-    crate::load::load(errors, apis);
+    let ref apis = syntax::parse_items(errors, content, trusted, namespace);
     let ref types = Types::collect(errors, apis);
     errors.propagate()?;
-
-    let generator = check::Generator::Macro;
-    check::typecheck(errors, apis, types, generator);
+    check::typecheck(errors, apis, types);
     errors.propagate()?;
 
     Ok(expand(ffi, doc, attrs, apis, types))
@@ -134,9 +130,8 @@
     quote! {
         #doc
         #attrs
-        #[deny(improper_ctypes, improper_ctypes_definitions)]
-        #[allow(clippy::unknown_clippy_lints)]
-        #[allow(non_camel_case_types, non_snake_case, clippy::upper_case_acronyms)]
+        #[deny(improper_ctypes)]
+        #[allow(non_camel_case_types, non_snake_case, clippy::upper_case_acronyms, clippy::unknown_clippy_lints)]
         #vis #mod_token #ident #expanded
     }
 }
@@ -293,7 +288,7 @@
     let ident = &enm.name.rust;
     let doc = &enm.doc;
     let attrs = &enm.attrs;
-    let repr = &enm.repr;
+    let repr = enm.repr;
     let type_id = type_id(&enm.name);
     let variants = enm.variants.iter().map(|variant| {
         let doc = &variant.doc;
@@ -424,19 +419,18 @@
         quote!(_: #receiver_type)
     });
     let args = efn.args.iter().map(|arg| {
-        let var = &arg.name.rust;
-        let colon = arg.colon_token;
+        let ident = &arg.name.rust;
         let ty = expand_extern_type(&arg.ty, types, true);
         if arg.ty == RustString {
-            quote!(#var #colon *const #ty)
+            quote!(#ident: *const #ty)
         } else if let Type::RustVec(_) = arg.ty {
-            quote!(#var #colon *const #ty)
+            quote!(#ident: *const #ty)
         } else if let Type::Fn(_) = arg.ty {
-            quote!(#var #colon ::cxx::private::FatFunction)
+            quote!(#ident: ::cxx::private::FatFunction)
         } else if types.needs_indirect_abi(&arg.ty) {
-            quote!(#var #colon *mut #ty)
+            quote!(#ident: *mut #ty)
         } else {
-            quote!(#var #colon #ty)
+            quote!(#ident: #ty)
         }
     });
     let all_args = receiver.chain(args);
@@ -465,9 +459,8 @@
     let receiver = efn.receiver.iter().map(|receiver| {
         let var = receiver.var;
         if receiver.pinned {
-            let colon = receiver.colon_token;
             let ty = receiver.ty_self();
-            quote!(#var #colon #ty)
+            quote!(#var: #ty)
         } else {
             let ampersand = receiver.ampersand;
             let lifetime = &receiver.lifetime;
@@ -493,66 +486,53 @@
         .map(|receiver| receiver.var.to_token_stream());
     let arg_vars = efn.args.iter().map(|arg| {
         let var = &arg.name.rust;
-        let span = var.span();
         match &arg.ty {
             Type::Ident(ident) if ident.rust == RustString => {
-                quote_spanned!(span=> #var.as_mut_ptr() as *const ::cxx::private::RustString)
+                quote!(#var.as_mut_ptr() as *const ::cxx::private::RustString)
             }
-            Type::RustBox(ty) => {
-                if types.is_considered_improper_ctype(&ty.inner) {
-                    quote_spanned!(span=> ::std::boxed::Box::into_raw(#var).cast())
-                } else {
-                    quote_spanned!(span=> ::std::boxed::Box::into_raw(#var))
-                }
-            }
-            Type::UniquePtr(ty) => {
-                if types.is_considered_improper_ctype(&ty.inner) {
-                    quote_spanned!(span=> ::cxx::UniquePtr::into_raw(#var).cast())
-                } else {
-                    quote_spanned!(span=> ::cxx::UniquePtr::into_raw(#var))
-                }
-            }
-            Type::RustVec(_) => quote_spanned!(span=> #var.as_mut_ptr() as *const ::cxx::private::RustVec<_>),
+            Type::RustBox(_) => quote!(::std::boxed::Box::into_raw(#var)),
+            Type::UniquePtr(_) => quote!(::cxx::UniquePtr::into_raw(#var)),
+            Type::RustVec(_) => quote!(#var.as_mut_ptr() as *const ::cxx::private::RustVec<_>),
             Type::Ref(ty) => match &ty.inner {
                 Type::Ident(ident) if ident.rust == RustString => match ty.mutable {
-                    false => quote_spanned!(span=> ::cxx::private::RustString::from_ref(#var)),
-                    true => quote_spanned!(span=> ::cxx::private::RustString::from_mut(#var)),
+                    false => quote!(::cxx::private::RustString::from_ref(#var)),
+                    true => quote!(::cxx::private::RustString::from_mut(#var)),
                 },
                 Type::RustVec(vec) if vec.inner == RustString => match ty.mutable {
-                    false => quote_spanned!(span=> ::cxx::private::RustVec::from_ref_vec_string(#var)),
-                    true => quote_spanned!(span=> ::cxx::private::RustVec::from_mut_vec_string(#var)),
+                    false => quote!(::cxx::private::RustVec::from_ref_vec_string(#var)),
+                    true => quote!(::cxx::private::RustVec::from_mut_vec_string(#var)),
                 },
                 Type::RustVec(_) => match ty.mutable {
-                    false => quote_spanned!(span=> ::cxx::private::RustVec::from_ref(#var)),
-                    true => quote_spanned!(span=> ::cxx::private::RustVec::from_mut(#var)),
+                    false => quote!(::cxx::private::RustVec::from_ref(#var)),
+                    true => quote!(::cxx::private::RustVec::from_mut(#var)),
                 },
                 inner if types.is_considered_improper_ctype(inner) => {
                     let var = match ty.pinned {
                         false => quote!(#var),
-                        true => quote_spanned!(span=> ::std::pin::Pin::into_inner_unchecked(#var)),
+                        true => quote!(::std::pin::Pin::into_inner_unchecked(#var)),
                     };
                     match ty.mutable {
                         false => {
-                            quote_spanned!(span=> #var as *const #inner as *const ::std::ffi::c_void)
+                            quote!(#var as *const #inner as *const ::std::ffi::c_void)
                         }
-                        true => quote_spanned!(span=> #var as *mut #inner as *mut ::std::ffi::c_void),
+                        true => quote!(#var as *mut #inner as *mut ::std::ffi::c_void),
                     }
                 }
                 _ => quote!(#var),
             },
             Type::Ptr(ty) => {
                 if types.is_considered_improper_ctype(&ty.inner) {
-                    quote_spanned!(span=> #var.cast())
+                    quote!(#var.cast())
                 } else {
                     quote!(#var)
                 }
             }
-            Type::Str(_) => quote_spanned!(span=> ::cxx::private::RustStr::from(#var)),
+            Type::Str(_) => quote!(::cxx::private::RustStr::from(#var)),
             Type::SliceRef(ty) => match ty.mutable {
-                false => quote_spanned!(span=> ::cxx::private::RustSlice::from_ref(#var)),
-                true => quote_spanned!(span=> ::cxx::private::RustSlice::from_mut(#var)),
+                false => quote!(::cxx::private::RustSlice::from_ref(#var)),
+                true => quote!(::cxx::private::RustSlice::from_mut(#var)),
             },
-            ty if types.needs_indirect_abi(ty) => quote_spanned!(span=> #var.as_mut_ptr()),
+            ty if types.needs_indirect_abi(ty) => quote!(#var.as_mut_ptr()),
             _ => quote!(#var),
         }
     });
@@ -575,37 +555,35 @@
         .filter(|arg| types.needs_indirect_abi(&arg.ty))
         .map(|arg| {
             let var = &arg.name.rust;
-            let span = var.span();
             // These are arguments for which C++ has taken ownership of the data
             // behind the mut reference it received.
-            quote_spanned! {span=>
+            quote! {
                 let mut #var = ::std::mem::MaybeUninit::new(#var);
             }
         })
         .collect::<TokenStream>();
     let local_name = format_ident!("__{}", efn.name.rust);
-    let span = efn.semi_token.span;
     let call = if indirect_return {
         let ret = expand_extern_type(efn.ret.as_ref().unwrap(), types, true);
-        setup.extend(quote_spanned! {span=>
+        setup.extend(quote! {
             let mut __return = ::std::mem::MaybeUninit::<#ret>::uninit();
         });
         setup.extend(if efn.throws {
-            quote_spanned! {span=>
+            quote! {
                 #local_name(#(#vars,)* __return.as_mut_ptr()).exception()?;
             }
         } else {
-            quote_spanned! {span=>
+            quote! {
                 #local_name(#(#vars,)* __return.as_mut_ptr());
             }
         });
-        quote_spanned!(span=> __return.assume_init())
+        quote!(__return.assume_init())
     } else if efn.throws {
-        quote_spanned! {span=>
+        quote! {
             #local_name(#(#vars),*).exception()
         }
     } else {
-        quote_spanned! {span=>
+        quote! {
             #local_name(#(#vars),*)
         }
     };
@@ -616,88 +594,72 @@
         expr = match &efn.ret {
             None => call,
             Some(ret) => match ret {
-                Type::Ident(ident) if ident.rust == RustString => {
-                    quote_spanned!(span=> #call.into_string())
-                }
-                Type::RustBox(ty) => {
-                    if types.is_considered_improper_ctype(&ty.inner) {
-                        quote_spanned!(span=> ::std::boxed::Box::from_raw(#call.cast()))
-                    } else {
-                        quote_spanned!(span=> ::std::boxed::Box::from_raw(#call))
-                    }
-                }
+                Type::Ident(ident) if ident.rust == RustString => quote!(#call.into_string()),
+                Type::RustBox(_) => quote!(::std::boxed::Box::from_raw(#call)),
                 Type::RustVec(vec) => {
                     if vec.inner == RustString {
-                        quote_spanned!(span=> #call.into_vec_string())
+                        quote!(#call.into_vec_string())
                     } else {
-                        quote_spanned!(span=> #call.into_vec())
+                        quote!(#call.into_vec())
                     }
                 }
-                Type::UniquePtr(ty) => {
-                    if types.is_considered_improper_ctype(&ty.inner) {
-                        quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#call.cast()))
-                    } else {
-                        quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#call))
-                    }
-                }
+                Type::UniquePtr(_) => quote!(::cxx::UniquePtr::from_raw(#call)),
                 Type::Ref(ty) => match &ty.inner {
                     Type::Ident(ident) if ident.rust == RustString => match ty.mutable {
-                        false => quote_spanned!(span=> #call.as_string()),
-                        true => quote_spanned!(span=> #call.as_mut_string()),
+                        false => quote!(#call.as_string()),
+                        true => quote!(#call.as_mut_string()),
                     },
                     Type::RustVec(vec) if vec.inner == RustString => match ty.mutable {
-                        false => quote_spanned!(span=> #call.as_vec_string()),
-                        true => quote_spanned!(span=> #call.as_mut_vec_string()),
+                        false => quote!(#call.as_vec_string()),
+                        true => quote!(#call.as_mut_vec_string()),
                     },
                     Type::RustVec(_) => match ty.mutable {
-                        false => quote_spanned!(span=> #call.as_vec()),
-                        true => quote_spanned!(span=> #call.as_mut_vec()),
+                        false => quote!(#call.as_vec()),
+                        true => quote!(#call.as_mut_vec()),
                     },
                     inner if types.is_considered_improper_ctype(inner) => {
                         let mutability = ty.mutability;
-                        let deref_mut = quote_spanned!(span=> &#mutability *#call.cast());
+                        let deref_mut = quote!(&#mutability *#call.cast());
                         match ty.pinned {
                             false => deref_mut,
-                            true => {
-                                quote_spanned!(span=> ::std::pin::Pin::new_unchecked(#deref_mut))
-                            }
+                            true => quote!(::std::pin::Pin::new_unchecked(#deref_mut)),
                         }
                     }
                     _ => call,
                 },
                 Type::Ptr(ty) => {
                     if types.is_considered_improper_ctype(&ty.inner) {
-                        quote_spanned!(span=> #call.cast())
+                        quote!(#call.cast())
                     } else {
                         call
                     }
                 }
-                Type::Str(_) => quote_spanned!(span=> #call.as_str()),
+                Type::Str(_) => quote!(#call.as_str()),
                 Type::SliceRef(slice) => {
                     let inner = &slice.inner;
                     match slice.mutable {
-                        false => quote_spanned!(span=> #call.as_slice::<#inner>()),
-                        true => quote_spanned!(span=> #call.as_mut_slice::<#inner>()),
+                        false => quote!(#call.as_slice::<#inner>()),
+                        true => quote!(#call.as_mut_slice::<#inner>()),
                     }
                 }
                 _ => call,
             },
         };
         if efn.throws {
-            expr = quote_spanned!(span=> ::std::result::Result::Ok(#expr));
+            expr = quote!(::std::result::Result::Ok(#expr));
         }
     };
     let mut dispatch = quote!(#setup #expr);
     let visibility = efn.visibility;
     let unsafety = &efn.sig.unsafety;
     if unsafety.is_none() {
-        dispatch = quote_spanned!(span=> unsafe { #dispatch });
+        dispatch = quote!(unsafe { #dispatch });
     }
     let fn_token = efn.sig.fn_token;
     let ident = &efn.name.rust;
     let generics = &efn.generics;
     let arg_list = quote_spanned!(efn.sig.paren_token.span=> (#(#all_args,)*));
-    let fn_body = quote_spanned!(span=> {
+    let fn_body = quote_spanned!(efn.semi_token.span=> {
         extern "C" {
             #decl
         }
@@ -735,7 +697,7 @@
                 };
                 &elided_generics
             };
-            quote_spanned! {ident.span()=>
+            quote! {
                 impl #generics #receiver_ident #receiver_generics {
                     #doc
                     #attrs
@@ -756,7 +718,6 @@
     let r_trampoline = mangle::r_trampoline(efn, var, types);
     let local_name = parse_quote!(__);
     let catch_unwind_label = format!("::{}::{}", efn.name.rust, var.rust);
-    let body_span = efn.semi_token.span;
     let shim = expand_rust_function_shim_impl(
         sig,
         types,
@@ -764,8 +725,6 @@
         local_name,
         catch_unwind_label,
         None,
-        Some(&efn.generics),
-        body_span,
     );
     let var = &var.rust;
 
@@ -777,9 +736,9 @@
                     fn trampoline();
                 }
                 #shim
-                trampoline as usize as *const ::std::ffi::c_void
+                trampoline as usize as *const ()
             },
-            ptr: #var as usize as *const ::std::ffi::c_void,
+            ptr: #var as usize as *const (),
         };
     }
 }
@@ -898,7 +857,6 @@
         Some(receiver) => format!("::{}::{}", receiver.ty.rust, efn.name.rust),
     };
     let invoke = Some(&efn.name.rust);
-    let body_span = efn.semi_token.span;
     expand_rust_function_shim_impl(
         efn,
         types,
@@ -906,8 +864,6 @@
         local_name,
         catch_unwind_label,
         invoke,
-        None,
-        body_span,
     )
 }
 
@@ -918,166 +874,138 @@
     local_name: Ident,
     catch_unwind_label: String,
     invoke: Option<&Ident>,
-    outer_generics: Option<&Generics>,
-    body_span: Span,
 ) -> TokenStream {
-    let generics = outer_generics.unwrap_or(&sig.generics);
+    let generics = &sig.generics;
     let receiver_var = sig
         .receiver
         .as_ref()
         .map(|receiver| quote_spanned!(receiver.var.span=> __self));
     let receiver = sig.receiver.as_ref().map(|receiver| {
-        let colon = receiver.colon_token;
         let receiver_type = receiver.ty();
-        quote!(#receiver_var #colon #receiver_type)
+        quote!(#receiver_var: #receiver_type)
     });
     let args = sig.args.iter().map(|arg| {
-        let var = &arg.name.rust;
-        let colon = arg.colon_token;
+        let ident = &arg.name.rust;
         let ty = expand_extern_type(&arg.ty, types, false);
         if types.needs_indirect_abi(&arg.ty) {
-            quote!(#var #colon *mut #ty)
+            quote!(#ident: *mut #ty)
         } else {
-            quote!(#var #colon #ty)
+            quote!(#ident: #ty)
         }
     });
     let all_args = receiver.into_iter().chain(args);
 
     let arg_vars = sig.args.iter().map(|arg| {
-        let var = &arg.name.rust;
-        let span = var.span();
+        let ident = &arg.name.rust;
         match &arg.ty {
             Type::Ident(i) if i.rust == RustString => {
-                quote_spanned!(span=> ::std::mem::take((*#var).as_mut_string()))
+                quote!(::std::mem::take((*#ident).as_mut_string()))
             }
-            Type::RustBox(_) => quote_spanned!(span=> ::std::boxed::Box::from_raw(#var)),
+            Type::RustBox(_) => quote!(::std::boxed::Box::from_raw(#ident)),
             Type::RustVec(vec) => {
                 if vec.inner == RustString {
-                    quote_spanned!(span=> ::std::mem::take((*#var).as_mut_vec_string()))
+                    quote!(::std::mem::take((*#ident).as_mut_vec_string()))
                 } else {
-                    quote_spanned!(span=> ::std::mem::take((*#var).as_mut_vec()))
+                    quote!(::std::mem::take((*#ident).as_mut_vec()))
                 }
             }
-            Type::UniquePtr(_) => quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#var)),
+            Type::UniquePtr(_) => quote!(::cxx::UniquePtr::from_raw(#ident)),
             Type::Ref(ty) => match &ty.inner {
                 Type::Ident(i) if i.rust == RustString => match ty.mutable {
-                    false => quote_spanned!(span=> #var.as_string()),
-                    true => quote_spanned!(span=> #var.as_mut_string()),
+                    false => quote!(#ident.as_string()),
+                    true => quote!(#ident.as_mut_string()),
                 },
                 Type::RustVec(vec) if vec.inner == RustString => match ty.mutable {
-                    false => quote_spanned!(span=> #var.as_vec_string()),
-                    true => quote_spanned!(span=> #var.as_mut_vec_string()),
+                    false => quote!(#ident.as_vec_string()),
+                    true => quote!(#ident.as_mut_vec_string()),
                 },
                 Type::RustVec(_) => match ty.mutable {
-                    false => quote_spanned!(span=> #var.as_vec()),
-                    true => quote_spanned!(span=> #var.as_mut_vec()),
+                    false => quote!(#ident.as_vec()),
+                    true => quote!(#ident.as_mut_vec()),
                 },
-                _ => quote!(#var),
+                _ => quote!(#ident),
             },
-            Type::Str(_) => quote_spanned!(span=> #var.as_str()),
+            Type::Str(_) => quote!(#ident.as_str()),
             Type::SliceRef(slice) => {
                 let inner = &slice.inner;
                 match slice.mutable {
-                    false => quote_spanned!(span=> #var.as_slice::<#inner>()),
-                    true => quote_spanned!(span=> #var.as_mut_slice::<#inner>()),
+                    false => quote!(#ident.as_slice::<#inner>()),
+                    true => quote!(#ident.as_mut_slice::<#inner>()),
                 }
             }
-            ty if types.needs_indirect_abi(ty) => quote_spanned!(span=> ::std::ptr::read(#var)),
-            _ => quote!(#var),
+            ty if types.needs_indirect_abi(ty) => quote!(::std::ptr::read(#ident)),
+            _ => quote!(#ident),
         }
     });
-    let vars: Vec<_> = receiver_var.into_iter().chain(arg_vars).collect();
+    let vars = receiver_var.into_iter().chain(arg_vars);
 
     let wrap_super = invoke.map(|invoke| expand_rust_function_shim_super(sig, &local_name, invoke));
 
-    let mut requires_closure;
     let mut call = match invoke {
-        Some(_) => {
-            requires_closure = false;
-            quote!(#local_name)
-        }
-        None => {
-            requires_closure = true;
-            quote!(::std::mem::transmute::<*const (), #sig>(__extern))
-        }
+        Some(_) => quote!(#local_name),
+        None => quote!(::std::mem::transmute::<*const (), #sig>(__extern)),
     };
-    requires_closure |= !vars.is_empty();
     call.extend(quote! { (#(#vars),*) });
 
-    let span = body_span;
     let conversion = sig.ret.as_ref().and_then(|ret| match ret {
         Type::Ident(ident) if ident.rust == RustString => {
-            Some(quote_spanned!(span=> ::cxx::private::RustString::from))
+            Some(quote!(::cxx::private::RustString::from))
         }
-        Type::RustBox(_) => Some(quote_spanned!(span=> ::std::boxed::Box::into_raw)),
+        Type::RustBox(_) => Some(quote!(::std::boxed::Box::into_raw)),
         Type::RustVec(vec) => {
             if vec.inner == RustString {
-                Some(quote_spanned!(span=> ::cxx::private::RustVec::from_vec_string))
+                Some(quote!(::cxx::private::RustVec::from_vec_string))
             } else {
-                Some(quote_spanned!(span=> ::cxx::private::RustVec::from))
+                Some(quote!(::cxx::private::RustVec::from))
             }
         }
-        Type::UniquePtr(_) => Some(quote_spanned!(span=> ::cxx::UniquePtr::into_raw)),
+        Type::UniquePtr(_) => Some(quote!(::cxx::UniquePtr::into_raw)),
         Type::Ref(ty) => match &ty.inner {
             Type::Ident(ident) if ident.rust == RustString => match ty.mutable {
-                false => Some(quote_spanned!(span=> ::cxx::private::RustString::from_ref)),
-                true => Some(quote_spanned!(span=> ::cxx::private::RustString::from_mut)),
+                false => Some(quote!(::cxx::private::RustString::from_ref)),
+                true => Some(quote!(::cxx::private::RustString::from_mut)),
             },
             Type::RustVec(vec) if vec.inner == RustString => match ty.mutable {
-                false => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_ref_vec_string)),
-                true => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_mut_vec_string)),
+                false => Some(quote!(::cxx::private::RustVec::from_ref_vec_string)),
+                true => Some(quote!(::cxx::private::RustVec::from_mut_vec_string)),
             },
             Type::RustVec(_) => match ty.mutable {
-                false => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_ref)),
-                true => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_mut)),
+                false => Some(quote!(::cxx::private::RustVec::from_ref)),
+                true => Some(quote!(::cxx::private::RustVec::from_mut)),
             },
             _ => None,
         },
-        Type::Str(_) => Some(quote_spanned!(span=> ::cxx::private::RustStr::from)),
+        Type::Str(_) => Some(quote!(::cxx::private::RustStr::from)),
         Type::SliceRef(ty) => match ty.mutable {
-            false => Some(quote_spanned!(span=> ::cxx::private::RustSlice::from_ref)),
-            true => Some(quote_spanned!(span=> ::cxx::private::RustSlice::from_mut)),
+            false => Some(quote!(::cxx::private::RustSlice::from_ref)),
+            true => Some(quote!(::cxx::private::RustSlice::from_mut)),
         },
         _ => None,
     });
 
     let mut expr = match conversion {
         None => call,
-        Some(conversion) if !sig.throws => {
-            requires_closure = true;
-            quote_spanned!(span=> #conversion(#call))
-        }
-        Some(conversion) => {
-            requires_closure = true;
-            quote_spanned!(span=> ::std::result::Result::map(#call, #conversion))
-        }
+        Some(conversion) if !sig.throws => quote!(#conversion(#call)),
+        Some(conversion) => quote!(::std::result::Result::map(#call, #conversion)),
     };
 
     let mut outparam = None;
     let indirect_return = indirect_return(sig, types);
     if indirect_return {
         let ret = expand_extern_type(sig.ret.as_ref().unwrap(), types, false);
-        outparam = Some(quote_spanned!(span=> __return: *mut #ret,));
+        outparam = Some(quote!(__return: *mut #ret,));
     }
     if sig.throws {
         let out = match sig.ret {
-            Some(_) => quote_spanned!(span=> __return),
-            None => quote_spanned!(span=> &mut ()),
+            Some(_) => quote!(__return),
+            None => quote!(&mut ()),
         };
-        requires_closure = true;
-        expr = quote_spanned!(span=> ::cxx::private::r#try(#out, #expr));
+        expr = quote!(::cxx::private::r#try(#out, #expr));
     } else if indirect_return {
-        requires_closure = true;
-        expr = quote_spanned!(span=> ::std::ptr::write(__return, #expr));
+        expr = quote!(::std::ptr::write(__return, #expr));
     }
 
-    let closure = if requires_closure {
-        quote_spanned!(span=> move || #expr)
-    } else {
-        quote!(#local_name)
-    };
-
-    expr = quote_spanned!(span=> ::cxx::private::catch_unwind(__fn, #closure));
+    expr = quote!(::cxx::private::catch_unwind(__fn, move || #expr));
 
     let ret = if sig.throws {
         quote!(-> ::cxx::private::Result)
@@ -1086,11 +1014,11 @@
     };
 
     let pointer = match invoke {
-        None => Some(quote_spanned!(span=> __extern: *const ())),
+        None => Some(quote!(__extern: *const ())),
         Some(_) => None,
     };
 
-    quote_spanned! {span=>
+    quote! {
         #[doc(hidden)]
         #[export_name = #link_name]
         unsafe extern "C" fn #local_name #generics(#(#all_args,)* #outparam #pointer) #ret {
@@ -1127,11 +1055,9 @@
             Some(ret) => quote!(#ret),
             None => quote!(()),
         };
-        // Set spans that result in the `Result<...>` written by the user being
-        // highlighted as the cause if their error type has no Display impl.
-        let result_begin = quote_spanned!(result.span=> ::std::result::Result<#ok, impl);
-        let result_end = quote_spanned!(rangle.span=> ::std::fmt::Display>);
-        quote!(-> #result_begin #result_end)
+        let impl_trait = quote_spanned!(result.span=> impl);
+        let display = quote_spanned!(rangle.span=> ::std::fmt::Display);
+        quote!(-> ::std::result::Result<#ok, #impl_trait #display>)
     } else {
         expand_return_type(&sig.ret)
     };
@@ -1301,8 +1227,8 @@
         }
         #[doc(hidden)]
         #[export_name = #link_reserve_total]
-        unsafe extern "C" fn #local_reserve_total #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, new_cap: usize) {
-            (*this).reserve_total(new_cap);
+        unsafe extern "C" fn #local_reserve_total #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, cap: usize) {
+            (*this).reserve_total(cap);
         }
         #[doc(hidden)]
         #[export_name = #link_set_len]
@@ -1330,16 +1256,18 @@
 
     let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve);
 
-    let can_construct_from_value = types.is_maybe_trivial(ident);
+    let can_construct_from_value = types.structs.contains_key(ident)
+        || types.enums.contains_key(ident)
+        || types.aliases.contains_key(ident);
     let new_method = if can_construct_from_value {
         Some(quote! {
             #[doc(hidden)]
-            fn __new(value: Self) -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+            fn __new(value: Self) -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_uninit]
-                    fn __uninit(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::std::ffi::c_void;
+                    fn __uninit(this: *mut *mut ::std::ffi::c_void) -> *mut ::std::ffi::c_void;
                 }
-                let mut repr = ::std::mem::MaybeUninit::uninit();
+                let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
                 unsafe { __uninit(&mut repr).cast::<#ident #ty_generics>().write(value) }
                 repr
             }
@@ -1359,47 +1287,47 @@
                 f.write_str(#name)
             }
             #[doc(hidden)]
-            fn __null() -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+            fn __null() -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_null]
-                    fn __null(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+                    fn __null(this: *mut *mut ::std::ffi::c_void);
                 }
-                let mut repr = ::std::mem::MaybeUninit::uninit();
+                let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
                 unsafe { __null(&mut repr) }
                 repr
             }
             #new_method
             #[doc(hidden)]
-            unsafe fn __raw(raw: *mut Self) -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+            unsafe fn __raw(raw: *mut Self) -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_raw]
-                    fn __raw(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>, raw: *mut ::std::ffi::c_void);
+                    fn __raw(this: *mut *mut ::std::ffi::c_void, raw: *mut ::std::ffi::c_void);
                 }
-                let mut repr = ::std::mem::MaybeUninit::uninit();
+                let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
                 __raw(&mut repr, raw.cast());
                 repr
             }
             #[doc(hidden)]
-            unsafe fn __get(repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const Self {
+            unsafe fn __get(repr: *mut ::std::ffi::c_void) -> *const Self {
                 extern "C" {
                     #[link_name = #link_get]
-                    fn __get(this: *const ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const ::std::ffi::c_void;
+                    fn __get(this: *const *mut ::std::ffi::c_void) -> *const ::std::ffi::c_void;
                 }
                 __get(&repr).cast()
             }
             #[doc(hidden)]
-            unsafe fn __release(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut Self {
+            unsafe fn __release(mut repr: *mut ::std::ffi::c_void) -> *mut Self {
                 extern "C" {
                     #[link_name = #link_release]
-                    fn __release(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::std::ffi::c_void;
+                    fn __release(this: *mut *mut ::std::ffi::c_void) -> *mut ::std::ffi::c_void;
                 }
                 __release(&mut repr).cast()
             }
             #[doc(hidden)]
-            unsafe fn __drop(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) {
+            unsafe fn __drop(mut repr: *mut ::std::ffi::c_void) {
                 extern "C" {
                     #[link_name = #link_drop]
-                    fn __drop(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+                    fn __drop(this: *mut *mut ::std::ffi::c_void);
                 }
                 __drop(&mut repr);
             }
@@ -1424,7 +1352,9 @@
 
     let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve);
 
-    let can_construct_from_value = types.is_maybe_trivial(ident);
+    let can_construct_from_value = types.structs.contains_key(ident)
+        || types.enums.contains_key(ident)
+        || types.aliases.contains_key(ident);
     let new_method = if can_construct_from_value {
         Some(quote! {
             #[doc(hidden)]
@@ -1565,8 +1495,6 @@
     let prefix = format!("cxxbridge1$std$vector${}$", resolve.name.to_symbol());
     let link_size = format!("{}size", prefix);
     let link_get_unchecked = format!("{}get_unchecked", prefix);
-    let link_push_back = format!("{}push_back", prefix);
-    let link_pop_back = format!("{}pop_back", prefix);
     let unique_ptr_prefix = format!(
         "cxxbridge1$unique_ptr$std$vector${}$",
         resolve.name.to_symbol(),
@@ -1583,42 +1511,6 @@
     let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span);
     let unsafe_token = format_ident!("unsafe", span = begin_span);
 
-    let can_pass_element_by_value = types.is_maybe_trivial(elem);
-    let by_value_methods = if can_pass_element_by_value {
-        Some(quote_spanned! {end_span=>
-            #[doc(hidden)]
-            unsafe fn __push_back(
-                this: ::std::pin::Pin<&mut ::cxx::CxxVector<Self>>,
-                value: &mut ::std::mem::ManuallyDrop<Self>,
-            ) {
-                extern "C" {
-                    #[link_name = #link_push_back]
-                    fn __push_back #impl_generics(
-                        this: ::std::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
-                        value: *mut ::std::ffi::c_void,
-                    );
-                }
-                __push_back(this, value as *mut ::std::mem::ManuallyDrop<Self> as *mut ::std::ffi::c_void);
-            }
-            #[doc(hidden)]
-            unsafe fn __pop_back(
-                this: ::std::pin::Pin<&mut ::cxx::CxxVector<Self>>,
-                out: &mut ::std::mem::MaybeUninit<Self>,
-            ) {
-                extern "C" {
-                    #[link_name = #link_pop_back]
-                    fn __pop_back #impl_generics(
-                        this: ::std::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
-                        out: *mut ::std::ffi::c_void,
-                    );
-                }
-                __pop_back(this, out as *mut ::std::mem::MaybeUninit<Self> as *mut ::std::ffi::c_void);
-            }
-        })
-    } else {
-        None
-    };
-
     quote_spanned! {end_span=>
         #unsafe_token impl #impl_generics ::cxx::private::VectorElement for #elem #ty_generics {
             #[doc(hidden)]
@@ -1637,55 +1529,51 @@
             unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<Self>, pos: usize) -> *mut Self {
                 extern "C" {
                     #[link_name = #link_get_unchecked]
-                    fn __get_unchecked #impl_generics(
-                        v: *mut ::cxx::CxxVector<#elem #ty_generics>,
-                        pos: usize,
-                    ) -> *mut ::std::ffi::c_void;
+                    fn __get_unchecked #impl_generics(_: *mut ::cxx::CxxVector<#elem #ty_generics>, _: usize) -> *mut #elem #ty_generics;
                 }
-                __get_unchecked(v, pos) as *mut Self
+                __get_unchecked(v, pos)
             }
-            #by_value_methods
             #[doc(hidden)]
-            fn __unique_ptr_null() -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+            fn __unique_ptr_null() -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_unique_ptr_null]
-                    fn __unique_ptr_null(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+                    fn __unique_ptr_null(this: *mut *mut ::std::ffi::c_void);
                 }
-                let mut repr = ::std::mem::MaybeUninit::uninit();
+                let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
                 unsafe { __unique_ptr_null(&mut repr) }
                 repr
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+            unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_unique_ptr_raw]
-                    fn __unique_ptr_raw #impl_generics(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>, raw: *mut ::cxx::CxxVector<#elem #ty_generics>);
+                    fn __unique_ptr_raw #impl_generics(this: *mut *mut ::std::ffi::c_void, raw: *mut ::cxx::CxxVector<#elem #ty_generics>);
                 }
-                let mut repr = ::std::mem::MaybeUninit::uninit();
+                let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
                 __unique_ptr_raw(&mut repr, raw);
                 repr
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_get(repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const ::cxx::CxxVector<Self> {
+            unsafe fn __unique_ptr_get(repr: *mut ::std::ffi::c_void) -> *const ::cxx::CxxVector<Self> {
                 extern "C" {
                     #[link_name = #link_unique_ptr_get]
-                    fn __unique_ptr_get #impl_generics(this: *const ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const ::cxx::CxxVector<#elem #ty_generics>;
+                    fn __unique_ptr_get #impl_generics(this: *const *mut ::std::ffi::c_void) -> *const ::cxx::CxxVector<#elem #ty_generics>;
                 }
                 __unique_ptr_get(&repr)
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_release(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::cxx::CxxVector<Self> {
+            unsafe fn __unique_ptr_release(mut repr: *mut ::std::ffi::c_void) -> *mut ::cxx::CxxVector<Self> {
                 extern "C" {
                     #[link_name = #link_unique_ptr_release]
-                    fn __unique_ptr_release #impl_generics(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::cxx::CxxVector<#elem #ty_generics>;
+                    fn __unique_ptr_release #impl_generics(this: *mut *mut ::std::ffi::c_void) -> *mut ::cxx::CxxVector<#elem #ty_generics>;
                 }
                 __unique_ptr_release(&mut repr)
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_drop(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) {
+            unsafe fn __unique_ptr_drop(mut repr: *mut ::std::ffi::c_void) {
                 extern "C" {
                     #[link_name = #link_unique_ptr_drop]
-                    fn __unique_ptr_drop(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+                    fn __unique_ptr_drop(this: *mut *mut ::std::ffi::c_void);
                 }
                 __unique_ptr_drop(&mut repr);
             }
@@ -1708,72 +1596,43 @@
 
 fn expand_extern_type(ty: &Type, types: &Types, proper: bool) -> TokenStream {
     match ty {
-        Type::Ident(ident) if ident.rust == RustString => {
-            let span = ident.rust.span();
-            quote_spanned!(span=> ::cxx::private::RustString)
-        }
+        Type::Ident(ident) if ident.rust == RustString => quote!(::cxx::private::RustString),
         Type::RustBox(ty) | Type::UniquePtr(ty) => {
-            let span = ty.name.span();
-            if proper && types.is_considered_improper_ctype(&ty.inner) {
-                quote_spanned!(span=> *mut ::std::ffi::c_void)
-            } else {
-                let inner = expand_extern_type(&ty.inner, types, proper);
-                quote_spanned!(span=> *mut #inner)
-            }
+            let inner = expand_extern_type(&ty.inner, types, proper);
+            quote!(*mut #inner)
         }
         Type::RustVec(ty) => {
-            let span = ty.name.span();
-            let langle = ty.langle;
             let elem = expand_extern_type(&ty.inner, types, proper);
-            let rangle = ty.rangle;
-            quote_spanned!(span=> ::cxx::private::RustVec #langle #elem #rangle)
+            quote!(::cxx::private::RustVec<#elem>)
         }
         Type::Ref(ty) => {
-            let ampersand = ty.ampersand;
-            let lifetime = &ty.lifetime;
             let mutability = ty.mutability;
             match &ty.inner {
                 Type::Ident(ident) if ident.rust == RustString => {
-                    let span = ident.rust.span();
-                    quote_spanned!(span=> #ampersand #lifetime #mutability ::cxx::private::RustString)
+                    quote!(&#mutability ::cxx::private::RustString)
                 }
                 Type::RustVec(ty) => {
-                    let span = ty.name.span();
-                    let langle = ty.langle;
                     let inner = expand_extern_type(&ty.inner, types, proper);
-                    let rangle = ty.rangle;
-                    quote_spanned!(span=> #ampersand #lifetime #mutability ::cxx::private::RustVec #langle #inner #rangle)
+                    quote!(&#mutability ::cxx::private::RustVec<#inner>)
                 }
-                inner if proper && types.is_considered_improper_ctype(inner) => {
-                    let star = Token![*](ampersand.span);
-                    match ty.mutable {
-                        false => quote!(#star const ::std::ffi::c_void),
-                        true => quote!(#star #mutability ::std::ffi::c_void),
-                    }
-                }
+                inner if proper && types.is_considered_improper_ctype(inner) => match ty.mutable {
+                    false => quote!(*const ::std::ffi::c_void),
+                    true => quote!(*#mutability ::std::ffi::c_void),
+                },
                 _ => quote!(#ty),
             }
         }
         Type::Ptr(ty) => {
             if proper && types.is_considered_improper_ctype(&ty.inner) {
-                let star = ty.star;
                 let mutability = ty.mutability;
                 let constness = ty.constness;
-                quote!(#star #mutability #constness ::std::ffi::c_void)
+                quote!(*#mutability #constness ::std::ffi::c_void)
             } else {
                 quote!(#ty)
             }
         }
-        Type::Str(ty) => {
-            let span = ty.ampersand.span;
-            let rust_str = Ident::new("RustStr", syn::spanned::Spanned::span(&ty.inner));
-            quote_spanned!(span=> ::cxx::private::#rust_str)
-        }
-        Type::SliceRef(ty) => {
-            let span = ty.ampersand.span;
-            let rust_slice = Ident::new("RustSlice", ty.bracket.span);
-            quote_spanned!(span=> ::cxx::private::#rust_slice)
-        }
+        Type::Str(_) => quote!(::cxx::private::RustStr),
+        Type::SliceRef(_) => quote!(::cxx::private::RustSlice),
         _ => quote!(#ty),
     }
 }
diff --git a/macro/src/lib.rs b/macro/src/lib.rs
index 324881d..f8e7903 100644
--- a/macro/src/lib.rs
+++ b/macro/src/lib.rs
@@ -3,7 +3,7 @@
     clippy::default_trait_access,
     clippy::doc_markdown,
     clippy::enum_glob_use,
-    clippy::if_same_then_else,
+    clippy::filter_map,
     clippy::inherent_to_string,
     clippy::items_after_statements,
     clippy::large_enum_variant,
@@ -36,11 +36,6 @@
 mod syntax;
 mod type_id;
 
-#[cfg(feature = "experimental")]
-mod clang;
-#[cfg(feature = "experimental")]
-mod load;
-
 use crate::syntax::file::Module;
 use crate::syntax::namespace::Namespace;
 use crate::syntax::qualified::QualifiedName;
diff --git a/macro/src/load.rs b/macro/src/load.rs
deleted file mode 100644
index d769ebf..0000000
--- a/macro/src/load.rs
+++ /dev/null
@@ -1,315 +0,0 @@
-use crate::clang::{Clang, Node};
-use crate::syntax::attrs::OtherAttrs;
-use crate::syntax::namespace::Namespace;
-use crate::syntax::report::Errors;
-use crate::syntax::{Api, Discriminant, Doc, Enum, EnumRepr, ForeignName, Pair, Variant};
-use flate2::write::GzDecoder;
-use memmap::Mmap;
-use proc_macro2::{Delimiter, Group, Ident, TokenStream};
-use quote::{format_ident, quote, quote_spanned};
-use std::env;
-use std::fmt::{self, Display};
-use std::fs::File;
-use std::io::Write;
-use std::path::PathBuf;
-use std::str::FromStr;
-use syn::{parse_quote, Path};
-
-const CXX_CLANG_AST: &str = "CXX_CLANG_AST";
-
-pub fn load(cx: &mut Errors, apis: &mut [Api]) {
-    let ref mut variants_from_header = Vec::new();
-    for api in apis {
-        if let Api::Enum(enm) = api {
-            if enm.variants_from_header {
-                if enm.variants.is_empty() {
-                    variants_from_header.push(enm);
-                } else {
-                    let span = span_for_enum_error(enm);
-                    cx.error(
-                        span,
-                        "enum with #![variants_from_header] must be written with no explicit variants",
-                    );
-                }
-            }
-        }
-    }
-
-    let span = match variants_from_header.get(0) {
-        None => return,
-        Some(enm) => enm.variants_from_header_attr.clone().unwrap(),
-    };
-
-    let ast_dump_path = match env::var_os(CXX_CLANG_AST) {
-        Some(ast_dump_path) => PathBuf::from(ast_dump_path),
-        None => {
-            let msg = format!(
-                "environment variable ${} has not been provided",
-                CXX_CLANG_AST,
-            );
-            return cx.error(span, msg);
-        }
-    };
-
-    let memmap = File::open(&ast_dump_path).and_then(|file| unsafe { Mmap::map(&file) });
-    let mut gunzipped;
-    let ast_dump_bytes = match match memmap {
-        Ok(ref memmap) => {
-            let is_gzipped = memmap.get(..2) == Some(b"\x1f\x8b");
-            if is_gzipped {
-                gunzipped = Vec::new();
-                let decode_result = GzDecoder::new(&mut gunzipped).write_all(&memmap);
-                decode_result.map(|_| gunzipped.as_slice())
-            } else {
-                Ok(&memmap as &[u8])
-            }
-        }
-        Err(error) => Err(error),
-    } {
-        Ok(bytes) => bytes,
-        Err(error) => {
-            let msg = format!("failed to read {}: {}", ast_dump_path.display(), error);
-            return cx.error(span, msg);
-        }
-    };
-
-    let ref root: Node = match serde_json::from_slice(ast_dump_bytes) {
-        Ok(root) => root,
-        Err(error) => {
-            let msg = format!("failed to read {}: {}", ast_dump_path.display(), error);
-            return cx.error(span, msg);
-        }
-    };
-
-    let ref mut namespace = Vec::new();
-    traverse(cx, root, namespace, variants_from_header, None);
-
-    for enm in variants_from_header {
-        if enm.variants.is_empty() {
-            let span = &enm.variants_from_header_attr;
-            let name = CxxName(&enm.name);
-            let msg = format!("failed to find any C++ definition of enum {}", name);
-            cx.error(span, msg);
-        }
-    }
-}
-
-fn traverse<'a>(
-    cx: &mut Errors,
-    node: &'a Node,
-    namespace: &mut Vec<&'a str>,
-    variants_from_header: &mut [&mut Enum],
-    mut idx: Option<usize>,
-) {
-    match &node.kind {
-        Clang::NamespaceDecl(decl) => {
-            let name = match &decl.name {
-                Some(name) => name,
-                // Can ignore enums inside an anonymous namespace.
-                None => return,
-            };
-            namespace.push(name);
-            idx = None;
-        }
-        Clang::EnumDecl(decl) => {
-            let name = match &decl.name {
-                Some(name) => name,
-                None => return,
-            };
-            idx = None;
-            for (i, enm) in variants_from_header.iter_mut().enumerate() {
-                if enm.name.cxx == **name && enm.name.namespace.iter().eq(&*namespace) {
-                    if !enm.variants.is_empty() {
-                        let span = &enm.variants_from_header_attr;
-                        let qual_name = CxxName(&enm.name);
-                        let msg = format!("found multiple C++ definitions of enum {}", qual_name);
-                        cx.error(span, msg);
-                        return;
-                    }
-                    let fixed_underlying_type = match &decl.fixed_underlying_type {
-                        Some(fixed_underlying_type) => fixed_underlying_type,
-                        None => {
-                            let span = &enm.variants_from_header_attr;
-                            let name = &enm.name.cxx;
-                            let qual_name = CxxName(&enm.name);
-                            let msg = format!(
-                                "implicit implementation-defined repr for enum {} is not supported yet; consider changing its C++ definition to `enum {}: int {{...}}",
-                                qual_name, name,
-                            );
-                            cx.error(span, msg);
-                            return;
-                        }
-                    };
-                    let repr = translate_qual_type(
-                        cx,
-                        &enm,
-                        fixed_underlying_type
-                            .desugared_qual_type
-                            .as_ref()
-                            .unwrap_or(&fixed_underlying_type.qual_type),
-                    );
-                    enm.repr = EnumRepr::Foreign { rust_type: repr };
-                    idx = Some(i);
-                    break;
-                }
-            }
-            if idx.is_none() {
-                return;
-            }
-        }
-        Clang::EnumConstantDecl(decl) => {
-            if let Some(idx) = idx {
-                let enm = &mut *variants_from_header[idx];
-                let span = enm
-                    .variants_from_header_attr
-                    .as_ref()
-                    .unwrap()
-                    .path
-                    .get_ident()
-                    .unwrap()
-                    .span();
-                let cxx_name = match ForeignName::parse(&decl.name, span) {
-                    Ok(foreign_name) => foreign_name,
-                    Err(_) => {
-                        let span = &enm.variants_from_header_attr;
-                        let msg = format!("unsupported C++ variant name: {}", decl.name);
-                        return cx.error(span, msg);
-                    }
-                };
-                let rust_name: Ident = match syn::parse_str(&decl.name) {
-                    Ok(ident) => ident,
-                    Err(_) => format_ident!("__Variant{}", enm.variants.len()),
-                };
-                let discriminant = match discriminant_value(&node.inner) {
-                    ParsedDiscriminant::Constant(discriminant) => discriminant,
-                    ParsedDiscriminant::Successor => match enm.variants.last() {
-                        None => Discriminant::zero(),
-                        Some(last) => match last.discriminant.checked_succ() {
-                            Some(discriminant) => discriminant,
-                            None => {
-                                let span = &enm.variants_from_header_attr;
-                                let msg = format!(
-                                    "overflow processing discriminant value for variant: {}",
-                                    decl.name,
-                                );
-                                return cx.error(span, msg);
-                            }
-                        },
-                    },
-                    ParsedDiscriminant::Fail => {
-                        let span = &enm.variants_from_header_attr;
-                        let msg = format!(
-                            "failed to obtain discriminant value for variant: {}",
-                            decl.name,
-                        );
-                        cx.error(span, msg);
-                        Discriminant::zero()
-                    }
-                };
-                enm.variants.push(Variant {
-                    doc: Doc::new(),
-                    attrs: OtherAttrs::none(),
-                    name: Pair {
-                        namespace: Namespace::ROOT,
-                        cxx: cxx_name,
-                        rust: rust_name,
-                    },
-                    discriminant,
-                    expr: None,
-                });
-            }
-        }
-        _ => {}
-    }
-    for inner in &node.inner {
-        traverse(cx, inner, namespace, variants_from_header, idx);
-    }
-    if let Clang::NamespaceDecl(_) = &node.kind {
-        let _ = namespace.pop().unwrap();
-    }
-}
-
-fn translate_qual_type(cx: &mut Errors, enm: &Enum, qual_type: &str) -> Path {
-    let rust_std_name = match qual_type {
-        "char" => "c_char",
-        "int" => "c_int",
-        "long" => "c_long",
-        "long long" => "c_longlong",
-        "signed char" => "c_schar",
-        "short" => "c_short",
-        "unsigned char" => "c_uchar",
-        "unsigned int" => "c_uint",
-        "unsigned long" => "c_ulong",
-        "unsigned long long" => "c_ulonglong",
-        "unsigned short" => "c_ushort",
-        unsupported => {
-            let span = &enm.variants_from_header_attr;
-            let qual_name = CxxName(&enm.name);
-            let msg = format!(
-                "unsupported underlying type for {}: {}",
-                qual_name, unsupported,
-            );
-            cx.error(span, msg);
-            "c_int"
-        }
-    };
-    let span = enm
-        .variants_from_header_attr
-        .as_ref()
-        .unwrap()
-        .path
-        .get_ident()
-        .unwrap()
-        .span();
-    let ident = Ident::new(rust_std_name, span);
-    let path = quote_spanned!(span=> ::std::os::raw::#ident);
-    parse_quote!(#path)
-}
-
-enum ParsedDiscriminant {
-    Constant(Discriminant),
-    Successor,
-    Fail,
-}
-
-fn discriminant_value(mut clang: &[Node]) -> ParsedDiscriminant {
-    if clang.is_empty() {
-        // No discriminant expression provided; use successor of previous
-        // descriminant.
-        return ParsedDiscriminant::Successor;
-    }
-
-    loop {
-        if clang.len() != 1 {
-            return ParsedDiscriminant::Fail;
-        }
-
-        let node = &clang[0];
-        match &node.kind {
-            Clang::ImplicitCastExpr => clang = &node.inner,
-            Clang::ConstantExpr(expr) => match Discriminant::from_str(&expr.value) {
-                Ok(discriminant) => return ParsedDiscriminant::Constant(discriminant),
-                Err(_) => return ParsedDiscriminant::Fail,
-            },
-            _ => return ParsedDiscriminant::Fail,
-        }
-    }
-}
-
-fn span_for_enum_error(enm: &Enum) -> TokenStream {
-    let enum_token = enm.enum_token;
-    let mut brace_token = Group::new(Delimiter::Brace, TokenStream::new());
-    brace_token.set_span(enm.brace_token.span);
-    quote!(#enum_token #brace_token)
-}
-
-struct CxxName<'a>(&'a Pair);
-
-impl<'a> Display for CxxName<'a> {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        for namespace in &self.0.namespace {
-            write!(formatter, "{}::", namespace)?;
-        }
-        write!(formatter, "{}", self.0.cxx)
-    }
-}
diff --git a/src/cxx.cc b/src/cxx.cc
index 5dca531..c0ef738 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -22,13 +22,6 @@
   return s.length();
 }
 
-void cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); }
-
-void cxxbridge1$cxx_string$reserve_total(std::string &s,
-                                         size_t new_cap) noexcept {
-  s.reserve(new_cap);
-}
-
 void cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr,
                                 std::size_t len) noexcept {
   s.append(reinterpret_cast<const char *>(ptr), len);
@@ -38,18 +31,12 @@
 void cxxbridge1$string$new(rust::String *self) noexcept;
 void cxxbridge1$string$clone(rust::String *self,
                              const rust::String &other) noexcept;
-bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr,
-                                 std::size_t len) noexcept;
-bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr,
-                                  std::size_t len) noexcept;
+bool cxxbridge1$string$from(rust::String *self, const char *ptr,
+                            std::size_t len) noexcept;
 void cxxbridge1$string$drop(rust::String *self) noexcept;
 const char *cxxbridge1$string$ptr(const rust::String *self) noexcept;
 std::size_t cxxbridge1$string$len(const rust::String *self) noexcept;
-std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept;
-void cxxbridge1$string$reserve_additional(rust::String *self,
-                                          size_t additional) noexcept;
-void cxxbridge1$string$reserve_total(rust::String *self,
-                                     size_t new_cap) noexcept;
+void cxxbridge1$string$reserve_total(rust::String *self, size_t cap) noexcept;
 
 // rust::Str
 void cxxbridge1$str$new(rust::Str *self) noexcept;
@@ -94,17 +81,11 @@
 String::~String() noexcept { cxxbridge1$string$drop(this); }
 
 static void initString(String *self, const char *s, std::size_t len) {
-  if (!cxxbridge1$string$from_utf8(self, s, len)) {
+  if (!cxxbridge1$string$from(self, s, len)) {
     panic<std::invalid_argument>("data for rust::String is not utf-8");
   }
 }
 
-static void initString(String *self, const char16_t *s, std::size_t len) {
-  if (!cxxbridge1$string$from_utf16(self, s, len)) {
-    panic<std::invalid_argument>("data for rust::String is not utf-16");
-  }
-}
-
 String::String(const std::string &s) { initString(this, s.data(), s.length()); }
 
 String::String(const char *s) {
@@ -119,19 +100,6 @@
              len);
 }
 
-String::String(const char16_t *s) {
-  assert(s != nullptr);
-  initString(this, s, std::char_traits<char16_t>::length(s));
-}
-
-String::String(const char16_t *s, std::size_t len) {
-  assert(s != nullptr || len == 0);
-  initString(this,
-             s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2)
-                                      : s,
-             len);
-}
-
 String &String::operator=(const String &other) &noexcept {
   if (this != &other) {
     cxxbridge1$string$drop(this);
@@ -163,24 +131,14 @@
   return cxxbridge1$string$len(this);
 }
 
-bool String::empty() const noexcept { return this->size() == 0; }
-
 const char *String::c_str() noexcept {
   auto len = this->length();
-  cxxbridge1$string$reserve_additional(this, 1);
+  cxxbridge1$string$reserve_total(this, len + 1);
   auto ptr = this->data();
   const_cast<char *>(ptr)[len] = '\0';
   return ptr;
 }
 
-std::size_t String::capacity() const noexcept {
-  return cxxbridge1$string$capacity(this);
-}
-
-void String::reserve(std::size_t new_cap) noexcept {
-  cxxbridge1$string$reserve_total(this, new_cap);
-}
-
 String::iterator String::begin() noexcept {
   return const_cast<char *>(this->data());
 }
@@ -270,8 +228,6 @@
 
 std::size_t Str::length() const noexcept { return this->size(); }
 
-bool Str::empty() const noexcept { return this->size() == 0; }
-
 Str::const_iterator Str::begin() const noexcept { return this->cbegin(); }
 
 Str::const_iterator Str::end() const noexcept { return this->cend(); }
@@ -471,13 +427,6 @@
 } // namespace cxxbridge1
 } // namespace rust
 
-namespace {
-template <typename T>
-void destroy(T *ptr) {
-  ptr->~T();
-}
-} // namespace
-
 extern "C" {
 void cxxbridge1$unique_ptr$std$string$null(
     std::unique_ptr<std::string> *ptr) noexcept {
@@ -542,18 +491,6 @@
     ptr->~unique_ptr();                                                        \
   }
 
-#define STD_VECTOR_TRIVIAL_OPS(RUST_TYPE, CXX_TYPE)                            \
-  void cxxbridge1$std$vector$##RUST_TYPE##$push_back(                          \
-      std::vector<CXX_TYPE> *v, CXX_TYPE *value) noexcept {                    \
-    v->push_back(std::move(*value));                                           \
-    destroy(value);                                                            \
-  }                                                                            \
-  void cxxbridge1$std$vector$##RUST_TYPE##$pop_back(std::vector<CXX_TYPE> *v,  \
-                                                    CXX_TYPE *out) noexcept {  \
-    new (out) CXX_TYPE(std::move(v->back()));                                  \
-    v->pop_back();                                                             \
-  }
-
 #define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE)                                  \
   void cxxbridge1$rust_vec$##RUST_TYPE##$new(                                  \
       rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
@@ -566,7 +503,7 @@
   const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data(                      \
       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
   void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(                        \
-      rust::Vec<CXX_TYPE> *ptr, std::size_t new_cap) noexcept;                 \
+      rust::Vec<CXX_TYPE> *ptr, std::size_t cap) noexcept;                     \
   void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr,     \
                                                  std::size_t len) noexcept;
 
@@ -592,8 +529,8 @@
     return cxxbridge1$rust_vec$##RUST_TYPE##$data(this);                       \
   }                                                                            \
   template <>                                                                  \
-  void Vec<CXX_TYPE>::reserve_total(std::size_t new_cap) noexcept {            \
-    cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, new_cap);            \
+  void Vec<CXX_TYPE>::reserve_total(std::size_t cap) noexcept {                \
+    cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, cap);                \
   }                                                                            \
   template <>                                                                  \
   void Vec<CXX_TYPE>::set_len(std::size_t len) noexcept {                      \
@@ -666,13 +603,10 @@
   MACRO(f32, float)                                                            \
   MACRO(f64, double)
 
-#define FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                     \
+#define FOR_EACH_STD_VECTOR(MACRO)                                             \
   FOR_EACH_NUMERIC(MACRO)                                                      \
   MACRO(usize, std::size_t)                                                    \
-  MACRO(isize, rust::isize)
-
-#define FOR_EACH_STD_VECTOR(MACRO)                                             \
-  FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                           \
+  MACRO(isize, rust::isize)                                                    \
   MACRO(string, std::string)
 
 #define FOR_EACH_RUST_VEC(MACRO)                                               \
@@ -693,7 +627,6 @@
 
 extern "C" {
 FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
-FOR_EACH_TRIVIAL_STD_VECTOR(STD_VECTOR_TRIVIAL_OPS)
 FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
 FOR_EACH_SHARED_PTR(SHARED_PTR_OPS)
 } // extern "C"
diff --git a/src/cxx_string.rs b/src/cxx_string.rs
index 626c2c8..dce7053 100644
--- a/src/cxx_string.rs
+++ b/src/cxx_string.rs
@@ -19,10 +19,6 @@
     fn string_data(this: &CxxString) -> *const u8;
     #[link_name = "cxxbridge1$cxx_string$length"]
     fn string_length(this: &CxxString) -> usize;
-    #[link_name = "cxxbridge1$cxx_string$clear"]
-    fn string_clear(this: Pin<&mut CxxString>);
-    #[link_name = "cxxbridge1$cxx_string$reserve_total"]
-    fn string_reserve_total(this: Pin<&mut CxxString>, new_cap: usize);
     #[link_name = "cxxbridge1$cxx_string$push"]
     fn string_push(this: Pin<&mut CxxString>, ptr: *const u8, len: usize);
 }
@@ -148,49 +144,6 @@
         String::from_utf8_lossy(self.as_bytes())
     }
 
-    /// Removes all characters from the string.
-    ///
-    /// Matches the behavior of C++ [std::string::clear][clear].
-    ///
-    /// Note: **unlike** the guarantee of Rust's `std::string::String::clear`,
-    /// the C++ standard does not require that capacity is unchanged by this
-    /// operation. In practice existing implementations do not change the
-    /// capacity but all pointers, references, and iterators into the string
-    /// contents are nevertheless invalidated.
-    ///
-    /// [clear]: https://en.cppreference.com/w/cpp/string/basic_string/clear
-    pub fn clear(self: Pin<&mut Self>) {
-        unsafe { string_clear(self) }
-    }
-
-    /// Ensures that this string's capacity is at least `additional` bytes
-    /// larger than its length.
-    ///
-    /// The capacity may be increased by more than `additional` bytes if it
-    /// chooses, to amortize the cost of frequent reallocations.
-    ///
-    /// **The meaning of the argument is not the same as
-    /// [std::string::reserve][reserve] in C++.** The C++ standard library and
-    /// Rust standard library both have a `reserve` method on strings, but in
-    /// C++ code the argument always refers to total capacity, whereas in Rust
-    /// code it always refers to additional capacity. This API on `CxxString`
-    /// follows the Rust convention, the same way that for the length accessor
-    /// we use the Rust conventional `len()` naming and not C++ `size()` or
-    /// `length()`.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the new capacity overflows usize.
-    ///
-    /// [reserve]: https://en.cppreference.com/w/cpp/string/basic_string/reserve
-    pub fn reserve(self: Pin<&mut Self>, additional: usize) {
-        let new_cap = self
-            .len()
-            .checked_add(additional)
-            .expect("CxxString capacity overflow");
-        unsafe { string_reserve_total(self, new_cap) }
-    }
-
     /// Appends a given string slice onto the end of this C++ string.
     pub fn push_str(self: Pin<&mut Self>, s: &str) {
         self.push_bytes(s.as_bytes());
@@ -260,7 +213,6 @@
     space: MaybeUninit<[usize; 8]>,
 }
 
-#[allow(missing_docs)]
 impl StackString {
     pub fn new() -> Self {
         StackString {
@@ -270,11 +222,9 @@
 
     pub unsafe fn init(&mut self, value: impl AsRef<[u8]>) -> Pin<&mut CxxString> {
         let value = value.as_ref();
-        unsafe {
-            let this = &mut *self.space.as_mut_ptr().cast::<MaybeUninit<CxxString>>();
-            string_init(this, value.as_ptr(), value.len());
-            Pin::new_unchecked(&mut *this.as_mut_ptr())
-        }
+        let this = &mut *self.space.as_mut_ptr().cast::<MaybeUninit<CxxString>>();
+        string_init(this, value.as_ptr(), value.len());
+        Pin::new_unchecked(&mut *this.as_mut_ptr())
     }
 }
 
diff --git a/src/cxx_vector.rs b/src/cxx_vector.rs
index d1fa23a..1643341 100644
--- a/src/cxx_vector.rs
+++ b/src/cxx_vector.rs
@@ -8,8 +8,9 @@
 use core::fmt::{self, Debug};
 use core::iter::FusedIterator;
 use core::marker::{PhantomData, PhantomPinned};
-use core::mem::{self, ManuallyDrop, MaybeUninit};
+use core::mem;
 use core::pin::Pin;
+use core::ptr;
 use core::slice;
 
 /// Binding to C++ `std::vector<T, std::allocator<T>>`.
@@ -22,13 +23,7 @@
 /// pointer, as in `&CxxVector<T>` or `UniquePtr<CxxVector<T>>`.
 #[repr(C, packed)]
 pub struct CxxVector<T> {
-    // A thing, because repr(C) structs are not allowed to consist exclusively
-    // of PhantomData fields.
-    _void: [c_void; 0],
-    // The conceptual vector elements to ensure that autotraits are propagated
-    // correctly, e.g. CxxVector is UnwindSafe iff T is.
-    _elements: PhantomData<[T]>,
-    // Prevent unpin operation from Pin<&mut CxxVector<T>> to &mut CxxVector<T>.
+    _private: [T; 0],
     _pinned: PhantomData<PhantomPinned>,
 }
 
@@ -86,10 +81,8 @@
     /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at
     pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
         let this = self as *const CxxVector<T> as *mut CxxVector<T>;
-        unsafe {
-            let ptr = T::__get_unchecked(this, pos) as *const T;
-            &*ptr
-        }
+        let ptr = T::__get_unchecked(this, pos) as *const T;
+        &*ptr
     }
 
     /// Returns a pinned mutable reference to an element without doing bounds
@@ -104,10 +97,8 @@
     ///
     /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at
     pub unsafe fn index_unchecked_mut(self: Pin<&mut Self>, pos: usize) -> Pin<&mut T> {
-        unsafe {
-            let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);
-            Pin::new_unchecked(&mut *ptr)
-        }
+        let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);
+        Pin::new_unchecked(&mut *ptr)
     }
 
     /// Returns a slice to the underlying contiguous array of elements.
@@ -155,39 +146,6 @@
     pub fn iter_mut(self: Pin<&mut Self>) -> IterMut<T> {
         IterMut { v: self, index: 0 }
     }
-
-    /// Appends an element to the back of the vector.
-    ///
-    /// Matches the behavior of C++ [std::vector\<T\>::push_back][push_back].
-    ///
-    /// [push_back]: https://en.cppreference.com/w/cpp/container/vector/push_back
-    pub fn push(self: Pin<&mut Self>, value: T)
-    where
-        T: ExternType<Kind = Trivial>,
-    {
-        let mut value = ManuallyDrop::new(value);
-        unsafe {
-            // C++ calls move constructor followed by destructor on `value`.
-            T::__push_back(self, &mut value);
-        }
-    }
-
-    /// Removes the last element from a vector and returns it, or `None` if the
-    /// vector is empty.
-    pub fn pop(self: Pin<&mut Self>) -> Option<T>
-    where
-        T: ExternType<Kind = Trivial>,
-    {
-        if self.is_empty() {
-            None
-        } else {
-            let mut value = MaybeUninit::uninit();
-            Some(unsafe {
-                T::__pop_back(self, &mut value);
-                value.assume_init()
-            })
-        }
-    }
 }
 
 /// Iterator over elements of a `CxxVector` by shared reference.
@@ -338,62 +296,19 @@
     #[doc(hidden)]
     unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
     #[doc(hidden)]
-    unsafe fn __push_back(v: Pin<&mut CxxVector<Self>>, value: &mut ManuallyDrop<Self>) {
-        // Opaque C type vector elements do not get this method because they can
-        // never exist by value on the Rust side of the bridge.
-        let _ = v;
-        let _ = value;
-        unreachable!()
-    }
+    fn __unique_ptr_null() -> *mut c_void;
     #[doc(hidden)]
-    unsafe fn __pop_back(v: Pin<&mut CxxVector<Self>>, out: &mut MaybeUninit<Self>) {
-        // Opaque C type vector elements do not get this method because they can
-        // never exist by value on the Rust side of the bridge.
-        let _ = v;
-        let _ = out;
-        unreachable!()
-    }
+    unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void;
     #[doc(hidden)]
-    fn __unique_ptr_null() -> MaybeUninit<*mut c_void>;
+    unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self>;
     #[doc(hidden)]
-    unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void>;
+    unsafe fn __unique_ptr_release(repr: *mut c_void) -> *mut CxxVector<Self>;
     #[doc(hidden)]
-    unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self>;
-    #[doc(hidden)]
-    unsafe fn __unique_ptr_release(repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self>;
-    #[doc(hidden)]
-    unsafe fn __unique_ptr_drop(repr: MaybeUninit<*mut c_void>);
-}
-
-macro_rules! vector_element_by_value_methods {
-    (opaque, $segment:expr, $ty:ty) => {};
-    (trivial, $segment:expr, $ty:ty) => {
-        #[doc(hidden)]
-        unsafe fn __push_back(v: Pin<&mut CxxVector<$ty>>, value: &mut ManuallyDrop<$ty>) {
-            extern "C" {
-                attr! {
-                    #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$push_back")]
-                    fn __push_back(_: Pin<&mut CxxVector<$ty>>, _: &mut ManuallyDrop<$ty>);
-                }
-            }
-            unsafe { __push_back(v, value) }
-        }
-        #[doc(hidden)]
-        unsafe fn __pop_back(v: Pin<&mut CxxVector<$ty>>, out: &mut MaybeUninit<$ty>) {
-            extern "C" {
-                attr! {
-                    #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$pop_back")]
-                    fn __pop_back(_: Pin<&mut CxxVector<$ty>>, _: &mut MaybeUninit<$ty>);
-                }
-            }
-            unsafe { __pop_back(v, out) }
-        }
-    };
+    unsafe fn __unique_ptr_drop(repr: *mut c_void);
 }
 
 macro_rules! impl_vector_element {
-    ($kind:ident, $segment:expr, $name:expr, $ty:ty) => {
-        const_assert_eq!(0, mem::size_of::<CxxVector<$ty>>());
+    ($segment:expr, $name:expr, $ty:ty) => {
         const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());
 
         unsafe impl VectorElement for $ty {
@@ -419,62 +334,61 @@
                         fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;
                     }
                 }
-                unsafe { __get_unchecked(v, pos) }
+                __get_unchecked(v, pos)
             }
-            vector_element_by_value_methods!($kind, $segment, $ty);
             #[doc(hidden)]
-            fn __unique_ptr_null() -> MaybeUninit<*mut c_void> {
+            fn __unique_ptr_null() -> *mut c_void {
                 extern "C" {
                     attr! {
                         #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$null")]
-                        fn __unique_ptr_null(this: *mut MaybeUninit<*mut c_void>);
+                        fn __unique_ptr_null(this: *mut *mut c_void);
                     }
                 }
-                let mut repr = MaybeUninit::uninit();
+                let mut repr = ptr::null_mut::<c_void>();
                 unsafe { __unique_ptr_null(&mut repr) }
                 repr
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void> {
+            unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void {
                 extern "C" {
                     attr! {
                         #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$raw")]
-                        fn __unique_ptr_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxVector<$ty>);
+                        fn __unique_ptr_raw(this: *mut *mut c_void, raw: *mut CxxVector<$ty>);
                     }
                 }
-                let mut repr = MaybeUninit::uninit();
-                unsafe { __unique_ptr_raw(&mut repr, raw) }
+                let mut repr = ptr::null_mut::<c_void>();
+                __unique_ptr_raw(&mut repr, raw);
                 repr
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self> {
+            unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self> {
                 extern "C" {
                     attr! {
                         #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$get")]
-                        fn __unique_ptr_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxVector<$ty>;
+                        fn __unique_ptr_get(this: *const *mut c_void) -> *const CxxVector<$ty>;
                     }
                 }
-                unsafe { __unique_ptr_get(&repr) }
+                __unique_ptr_get(&repr)
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_release(mut repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self> {
+            unsafe fn __unique_ptr_release(mut repr: *mut c_void) -> *mut CxxVector<Self> {
                 extern "C" {
                     attr! {
                         #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$release")]
-                        fn __unique_ptr_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxVector<$ty>;
+                        fn __unique_ptr_release(this: *mut *mut c_void) -> *mut CxxVector<$ty>;
                     }
                 }
-                unsafe { __unique_ptr_release(&mut repr) }
+                __unique_ptr_release(&mut repr)
             }
             #[doc(hidden)]
-            unsafe fn __unique_ptr_drop(mut repr: MaybeUninit<*mut c_void>) {
+            unsafe fn __unique_ptr_drop(mut repr: *mut c_void) {
                 extern "C" {
                     attr! {
                         #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$drop")]
-                        fn __unique_ptr_drop(this: *mut MaybeUninit<*mut c_void>);
+                        fn __unique_ptr_drop(this: *mut *mut c_void);
                     }
                 }
-                unsafe { __unique_ptr_drop(&mut repr) }
+                __unique_ptr_drop(&mut repr);
             }
         }
     };
@@ -482,7 +396,7 @@
 
 macro_rules! impl_vector_element_for_primitive {
     ($ty:ident) => {
-        impl_vector_element!(trivial, stringify!($ty), stringify!($ty), $ty);
+        impl_vector_element!(stringify!($ty), stringify!($ty), $ty);
     };
 }
 
@@ -499,4 +413,4 @@
 impl_vector_element_for_primitive!(f32);
 impl_vector_element_for_primitive!(f64);
 
-impl_vector_element!(opaque, "string", "CxxString", CxxString);
+impl_vector_element!("string", "CxxString", CxxString);
diff --git a/src/exception.rs b/src/exception.rs
index 2ae470e..f61e8fa 100644
--- a/src/exception.rs
+++ b/src/exception.rs
@@ -1,5 +1,5 @@
 use alloc::boxed::Box;
-use core::fmt::{self, Display};
+use core::fmt::{self, Debug, Display};
 
 /// Exception thrown from an `extern "C++"` function.
 #[derive(Debug)]
@@ -16,7 +16,6 @@
 impl std::error::Error for Exception {}
 
 impl Exception {
-    #[allow(missing_docs)]
     pub fn what(&self) -> &str {
         &self.what
     }
diff --git a/src/extern_type.rs b/src/extern_type.rs
index 8c9c286..35057ac 100644
--- a/src/extern_type.rs
+++ b/src/extern_type.rs
@@ -167,7 +167,6 @@
     /// indirection.
     pub enum Trivial {}
 
-    #[allow(missing_docs)]
     pub trait Kind: private::Sealed {}
     impl Kind for Opaque {}
     impl Kind for Trivial {}
diff --git a/src/function.rs b/src/function.rs
index f0a2010..1166b3d 100644
--- a/src/function.rs
+++ b/src/function.rs
@@ -1,9 +1,5 @@
-#![allow(missing_docs)]
-
-use core::ffi::c_void;
-
 #[repr(C)]
 pub struct FatFunction {
-    pub trampoline: *const c_void,
-    pub ptr: *const c_void,
+    pub trampoline: *const (),
+    pub ptr: *const (),
 }
diff --git a/src/lib.rs b/src/lib.rs
index 9880e71..19a708c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -364,10 +364,8 @@
 //! </table>
 
 #![no_std]
-#![doc(html_root_url = "https://docs.rs/cxx/1.0.54")]
-#![deny(improper_ctypes, improper_ctypes_definitions, missing_docs)]
-#![cfg_attr(not(no_unsafe_op_in_unsafe_fn_lint), deny(unsafe_op_in_unsafe_fn))]
-#![cfg_attr(no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))]
+#![doc(html_root_url = "https://docs.rs/cxx/1.0.42")]
+#![deny(improper_ctypes)]
 #![allow(non_camel_case_types)]
 #![allow(
     clippy::cognitive_complexity,
@@ -488,6 +486,3 @@
     a b c d e f g h i j k l m n o p q r s t u v w x y z
     __ // underscore
 }
-
-#[repr(transparent)]
-struct void(core::ffi::c_void);
diff --git a/src/memory.rs b/src/memory.rs
index fd8df12..441d3d8 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -4,6 +4,5 @@
 
 pub use crate::shared_ptr::SharedPtrTarget;
 pub use crate::unique_ptr::UniquePtrTarget;
-pub use crate::weak_ptr::WeakPtrTarget;
 #[doc(no_inline)]
 pub use cxx::{SharedPtr, UniquePtr};
diff --git a/src/opaque.rs b/src/opaque.rs
index e0f8ce2..3c8f536 100644
--- a/src/opaque.rs
+++ b/src/opaque.rs
@@ -1,6 +1,3 @@
-#![allow(missing_docs)]
-
-use crate::void;
 use core::marker::{PhantomData, PhantomPinned};
 use core::mem;
 
@@ -12,7 +9,7 @@
 // . !Unpin
 #[repr(C, packed)]
 pub struct Opaque {
-    _private: [*const void; 0],
+    _private: [*const u8; 0],
     _pinned: PhantomData<PhantomPinned>,
 }
 
diff --git a/src/result.rs b/src/result.rs
index d7a31f0..f41639a 100644
--- a/src/result.rs
+++ b/src/result.rs
@@ -1,5 +1,3 @@
-#![allow(missing_docs)]
-
 use crate::exception::Exception;
 use alloc::boxed::Box;
 use alloc::string::{String, ToString};
@@ -28,16 +26,16 @@
 {
     match result {
         Ok(ok) => {
-            unsafe { ptr::write(ret, ok) }
+            ptr::write(ret, ok);
             Result { ok: ptr::null() }
         }
-        Err(err) => unsafe { to_c_error(err.to_string()) },
+        Err(err) => to_c_error(err.to_string()),
     }
 }
 
 unsafe fn to_c_error(msg: String) -> Result {
     let mut msg = msg;
-    unsafe { msg.as_mut_vec() }.push(b'\0');
+    msg.as_mut_vec().push(b'\0');
     let ptr = msg.as_ptr();
     let len = msg.len();
 
@@ -46,24 +44,22 @@
         fn error(ptr: *const u8, len: usize) -> NonNull<u8>;
     }
 
-    let copy = unsafe { error(ptr, len) };
+    let copy = error(ptr, len);
     let err = PtrLen { ptr: copy, len };
     Result { err }
 }
 
 impl Result {
     pub unsafe fn exception(self) -> StdResult<(), Exception> {
-        unsafe {
-            if self.ok.is_null() {
-                Ok(())
-            } else {
-                let err = self.err;
-                let slice = slice::from_raw_parts_mut(err.ptr.as_ptr(), err.len);
-                let s = str::from_utf8_unchecked_mut(slice);
-                Err(Exception {
-                    what: Box::from_raw(s),
-                })
-            }
+        if self.ok.is_null() {
+            Ok(())
+        } else {
+            let err = self.err;
+            let slice = slice::from_raw_parts_mut(err.ptr.as_ptr(), err.len);
+            let s = str::from_utf8_unchecked_mut(slice);
+            Err(Exception {
+                what: Box::from_raw(s),
+            })
         }
     }
 }
diff --git a/src/rust_slice.rs b/src/rust_slice.rs
index 0696311..b4b5f2c 100644
--- a/src/rust_slice.rs
+++ b/src/rust_slice.rs
@@ -1,66 +1,41 @@
-#![allow(missing_docs)]
-
-use core::mem::{self, MaybeUninit};
+use core::mem;
 use core::ptr::{self, NonNull};
 use core::slice;
 
-// ABI compatible with C++ rust::Slice<T> (not necessarily &[T]).
 #[repr(C)]
 pub struct RustSlice {
-    repr: [MaybeUninit<usize>; mem::size_of::<NonNull<[()]>>() / mem::size_of::<usize>()],
+    pub(crate) repr: NonNull<[()]>,
 }
 
 impl RustSlice {
     pub fn from_ref<T>(slice: &[T]) -> Self {
-        let ptr = NonNull::from(slice).cast::<T>();
-        let len = slice.len();
-        Self::from_raw_parts(ptr, len)
+        let ptr = ptr::slice_from_raw_parts::<()>(slice.as_ptr().cast(), slice.len());
+        RustSlice {
+            repr: unsafe { NonNull::new_unchecked(ptr as *mut _) },
+        }
     }
 
     pub fn from_mut<T>(slice: &mut [T]) -> Self {
-        let ptr = NonNull::from(&mut *slice).cast::<T>();
-        let len = slice.len();
-        Self::from_raw_parts(ptr, len)
+        let ptr = ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len());
+        RustSlice {
+            repr: unsafe { NonNull::new_unchecked(ptr) },
+        }
     }
 
     pub unsafe fn as_slice<'a, T>(self) -> &'a [T] {
-        let ptr = self.as_non_null_ptr().as_ptr();
-        let len = self.len();
-        unsafe { slice::from_raw_parts(ptr, len) }
+        let ptr = self.repr.as_ptr();
+        let len = self.repr.as_ref().len();
+        slice::from_raw_parts(ptr.cast(), len)
     }
 
     pub unsafe fn as_mut_slice<'a, T>(self) -> &'a mut [T] {
-        let ptr = self.as_non_null_ptr().as_ptr();
-        let len = self.len();
-        unsafe { slice::from_raw_parts_mut(ptr, len) }
-    }
-
-    pub(crate) fn from_raw_parts<T>(ptr: NonNull<T>, len: usize) -> Self {
-        // TODO: use NonNull::from_raw_parts(ptr.cast(), len) when stable.
-        // https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.from_raw_parts
-        // https://github.com/rust-lang/rust/issues/81513
-        let ptr = ptr::slice_from_raw_parts_mut(ptr.as_ptr().cast(), len);
-        unsafe { mem::transmute::<NonNull<[()]>, RustSlice>(NonNull::new_unchecked(ptr)) }
-    }
-
-    pub(crate) fn as_non_null_ptr<T>(&self) -> NonNull<T> {
-        let rust_slice = RustSlice { repr: self.repr };
-        let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) };
-        repr.cast()
-    }
-
-    pub(crate) fn len(&self) -> usize {
-        let rust_slice = RustSlice { repr: self.repr };
-        let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) };
-        // TODO: use repr.len() when stable.
-        // https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.len
-        // https://github.com/rust-lang/rust/issues/71146
-        unsafe { repr.as_ref() }.len()
+        let ptr = self.repr.as_ptr();
+        let len = self.repr.as_ref().len();
+        slice::from_raw_parts_mut(ptr.cast(), len)
     }
 }
 
-const_assert_eq!(mem::size_of::<NonNull<[()]>>(), mem::size_of::<RustSlice>());
 const_assert_eq!(
-    mem::align_of::<NonNull<[()]>>(),
-    mem::align_of::<RustSlice>(),
+    mem::size_of::<Option<RustSlice>>(),
+    mem::size_of::<RustSlice>(),
 );
diff --git a/src/rust_str.rs b/src/rust_str.rs
index b1b46e3..9bc2614 100644
--- a/src/rust_str.rs
+++ b/src/rust_str.rs
@@ -1,28 +1,21 @@
-#![allow(missing_docs)]
-
-use core::mem::{self, MaybeUninit};
+use core::mem;
 use core::ptr::NonNull;
 use core::str;
 
-// ABI compatible with C++ rust::Str (not necessarily &str).
 #[repr(C)]
 pub struct RustStr {
-    repr: [MaybeUninit<usize>; mem::size_of::<NonNull<str>>() / mem::size_of::<usize>()],
+    repr: NonNull<str>,
 }
 
 impl RustStr {
     pub fn from(repr: &str) -> Self {
         let repr = NonNull::from(repr);
-        unsafe { mem::transmute::<NonNull<str>, RustStr>(repr) }
+        RustStr { repr }
     }
 
     pub unsafe fn as_str<'a>(self) -> &'a str {
-        unsafe {
-            let repr = mem::transmute::<RustStr, NonNull<str>>(self);
-            &*repr.as_ptr()
-        }
+        &*self.repr.as_ptr()
     }
 }
 
-const_assert_eq!(mem::size_of::<NonNull<str>>(), mem::size_of::<RustStr>());
-const_assert_eq!(mem::align_of::<NonNull<str>>(), mem::align_of::<RustStr>());
+const_assert_eq!(mem::size_of::<Option<RustStr>>(), mem::size_of::<RustStr>());
diff --git a/src/rust_string.rs b/src/rust_string.rs
index 051e35c..a5fa3f4 100644
--- a/src/rust_string.rs
+++ b/src/rust_string.rs
@@ -1,18 +1,14 @@
-#![allow(missing_docs)]
-
 use alloc::string::String;
-use core::mem::{self, MaybeUninit};
-use core::ptr;
+use core::mem;
 
-// ABI compatible with C++ rust::String (not necessarily alloc::string::String).
 #[repr(C)]
 pub struct RustString {
-    repr: [MaybeUninit<usize>; mem::size_of::<String>() / mem::size_of::<usize>()],
+    repr: String,
 }
 
 impl RustString {
     pub fn from(s: String) -> Self {
-        unsafe { mem::transmute::<String, RustString>(s) }
+        RustString { repr: s }
     }
 
     pub fn from_ref(s: &String) -> &Self {
@@ -24,24 +20,17 @@
     }
 
     pub fn into_string(self) -> String {
-        unsafe { mem::transmute::<RustString, String>(self) }
+        self.repr
     }
 
     pub fn as_string(&self) -> &String {
-        unsafe { &*(self as *const RustString as *const String) }
+        &self.repr
     }
 
     pub fn as_mut_string(&mut self) -> &mut String {
-        unsafe { &mut *(self as *mut RustString as *mut String) }
+        &mut self.repr
     }
 }
 
-impl Drop for RustString {
-    fn drop(&mut self) {
-        unsafe { ptr::drop_in_place(self.as_mut_string()) }
-    }
-}
-
-const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<RustString>());
-const_assert_eq!(mem::size_of::<String>(), mem::size_of::<RustString>());
-const_assert_eq!(mem::align_of::<String>(), mem::align_of::<RustString>());
+const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<String>());
+const_assert_eq!(mem::align_of::<usize>(), mem::align_of::<String>());
diff --git a/src/rust_type.rs b/src/rust_type.rs
index eacb530..7bcf440 100644
--- a/src/rust_type.rs
+++ b/src/rust_type.rs
@@ -1,5 +1,3 @@
-#![allow(missing_docs)]
-
 pub unsafe trait RustType {}
 pub unsafe trait ImplBox {}
 pub unsafe trait ImplVec {}
diff --git a/src/rust_vec.rs b/src/rust_vec.rs
index 9f4484d..126fdbf 100644
--- a/src/rust_vec.rs
+++ b/src/rust_vec.rs
@@ -1,27 +1,20 @@
-#![allow(missing_docs)]
-
 use crate::rust_string::RustString;
 use alloc::string::String;
 use alloc::vec::Vec;
-use core::ffi::c_void;
-use core::marker::PhantomData;
-use core::mem::{self, ManuallyDrop, MaybeUninit};
-use core::ptr;
+use core::mem::ManuallyDrop;
 
-// ABI compatible with C++ rust::Vec<T> (not necessarily alloc::vec::Vec<T>).
 #[repr(C)]
 pub struct RustVec<T> {
-    repr: [MaybeUninit<usize>; mem::size_of::<Vec<c_void>>() / mem::size_of::<usize>()],
-    marker: PhantomData<Vec<T>>,
+    pub(crate) repr: Vec<T>,
 }
 
 impl<T> RustVec<T> {
     pub fn new() -> Self {
-        Self::from(Vec::new())
+        RustVec { repr: Vec::new() }
     }
 
     pub fn from(v: Vec<T>) -> Self {
-        unsafe { mem::transmute::<Vec<T>, RustVec<T>>(v) }
+        RustVec { repr: v }
     }
 
     pub fn from_ref(v: &Vec<T>) -> &Self {
@@ -33,39 +26,38 @@
     }
 
     pub fn into_vec(self) -> Vec<T> {
-        unsafe { mem::transmute::<RustVec<T>, Vec<T>>(self) }
+        self.repr
     }
 
     pub fn as_vec(&self) -> &Vec<T> {
-        unsafe { &*(self as *const RustVec<T> as *const Vec<T>) }
+        &self.repr
     }
 
     pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
-        unsafe { &mut *(self as *mut RustVec<T> as *mut Vec<T>) }
+        &mut self.repr
     }
 
     pub fn len(&self) -> usize {
-        self.as_vec().len()
+        self.repr.len()
     }
 
     pub fn capacity(&self) -> usize {
-        self.as_vec().capacity()
+        self.repr.capacity()
     }
 
     pub fn as_ptr(&self) -> *const T {
-        self.as_vec().as_ptr()
+        self.repr.as_ptr()
     }
 
-    pub fn reserve_total(&mut self, new_cap: usize) {
-        let vec = self.as_mut_vec();
-        if new_cap > vec.capacity() {
-            let additional = new_cap - vec.len();
-            vec.reserve(additional);
+    pub fn reserve_total(&mut self, cap: usize) {
+        let len = self.repr.len();
+        if cap > len {
+            self.repr.reserve(cap - len);
         }
     }
 
     pub unsafe fn set_len(&mut self, len: usize) {
-        unsafe { self.as_mut_vec().set_len(len) }
+        self.repr.set_len(len);
     }
 }
 
@@ -87,7 +79,7 @@
     }
 
     pub fn into_vec_string(self) -> Vec<String> {
-        let mut v = ManuallyDrop::new(self.into_vec());
+        let mut v = ManuallyDrop::new(self.repr);
         let ptr = v.as_mut_ptr().cast::<String>();
         let len = v.len();
         let cap = v.capacity();
@@ -95,16 +87,10 @@
     }
 
     pub fn as_vec_string(&self) -> &Vec<String> {
-        unsafe { &*(self as *const RustVec<RustString> as *const Vec<String>) }
+        unsafe { &*(&self.repr as *const Vec<RustString> as *const Vec<String>) }
     }
 
     pub fn as_mut_vec_string(&mut self) -> &mut Vec<String> {
-        unsafe { &mut *(self as *mut RustVec<RustString> as *mut Vec<String>) }
-    }
-}
-
-impl<T> Drop for RustVec<T> {
-    fn drop(&mut self) {
-        unsafe { ptr::drop_in_place(self.as_mut_vec()) }
+        unsafe { &mut *(&mut self.repr as *mut Vec<RustString> as *mut Vec<String>) }
     }
 }
diff --git a/src/shared_ptr.rs b/src/shared_ptr.rs
index 317773d..66b988b 100644
--- a/src/shared_ptr.rs
+++ b/src/shared_ptr.rs
@@ -15,7 +15,7 @@
 where
     T: SharedPtrTarget,
 {
-    repr: [MaybeUninit<*mut c_void>; 2],
+    repr: [*mut c_void; 2],
     ty: PhantomData<T>,
 }
 
@@ -216,7 +216,7 @@
                         fn __null(new: *mut c_void);
                     }
                 }
-                unsafe { __null(new) }
+                __null(new);
             }
             #[doc(hidden)]
             unsafe fn __new(value: Self, new: *mut c_void) {
@@ -226,7 +226,7 @@
                         fn __uninit(new: *mut c_void) -> *mut c_void;
                     }
                 }
-                unsafe { __uninit(new).cast::<$ty>().write(value) }
+                __uninit(new).cast::<$ty>().write(value);
             }
             #[doc(hidden)]
             unsafe fn __clone(this: *const c_void, new: *mut c_void) {
@@ -236,7 +236,7 @@
                         fn __clone(this: *const c_void, new: *mut c_void);
                     }
                 }
-                unsafe { __clone(this, new) }
+                __clone(this, new);
             }
             #[doc(hidden)]
             unsafe fn __get(this: *const c_void) -> *const Self {
@@ -246,7 +246,7 @@
                         fn __get(this: *const c_void) -> *const c_void;
                     }
                 }
-                unsafe { __get(this) }.cast()
+                __get(this).cast()
             }
             #[doc(hidden)]
             unsafe fn __drop(this: *mut c_void) {
@@ -256,7 +256,7 @@
                         fn __drop(this: *mut c_void);
                     }
                 }
-                unsafe { __drop(this) }
+                __drop(this);
             }
         }
     };
diff --git a/src/symbols/exception.rs b/src/symbols/exception.rs
index cf0701b..0c1bb87 100644
--- a/src/symbols/exception.rs
+++ b/src/symbols/exception.rs
@@ -4,7 +4,7 @@
 
 #[export_name = "cxxbridge1$exception"]
 unsafe extern "C" fn exception(ptr: *const u8, len: usize) -> *const u8 {
-    let slice = unsafe { slice::from_raw_parts(ptr, len) };
+    let slice = slice::from_raw_parts(ptr, len);
     let boxed = String::from_utf8_lossy(slice).into_owned().into_boxed_str();
     Box::leak(boxed).as_ptr()
 }
diff --git a/src/symbols/rust_slice.rs b/src/symbols/rust_slice.rs
index df215ac..055b4de 100644
--- a/src/symbols/rust_slice.rs
+++ b/src/symbols/rust_slice.rs
@@ -3,18 +3,20 @@
 use core::ptr::{self, NonNull};
 
 #[export_name = "cxxbridge1$slice$new"]
-unsafe extern "C" fn slice_new(this: &mut MaybeUninit<RustSlice>, ptr: NonNull<()>, len: usize) {
-    let this = this.as_mut_ptr();
-    let rust_slice = RustSlice::from_raw_parts(ptr, len);
-    unsafe { ptr::write(this, rust_slice) }
+unsafe extern "C" fn slice_new(this: &mut MaybeUninit<RustSlice>, ptr: *const (), len: usize) {
+    let ptr = ptr::slice_from_raw_parts(ptr, len);
+    let rust_slice = RustSlice {
+        repr: NonNull::new_unchecked(ptr as *mut _),
+    };
+    ptr::write(this.as_mut_ptr(), rust_slice);
 }
 
 #[export_name = "cxxbridge1$slice$ptr"]
-unsafe extern "C" fn slice_ptr(this: &RustSlice) -> NonNull<()> {
-    this.as_non_null_ptr()
+unsafe extern "C" fn slice_ptr(this: &RustSlice) -> *const () {
+    this.repr.as_ptr().cast()
 }
 
 #[export_name = "cxxbridge1$slice$len"]
 unsafe extern "C" fn slice_len(this: &RustSlice) -> usize {
-    this.len()
+    this.repr.as_ref().len()
 }
diff --git a/src/symbols/rust_str.rs b/src/symbols/rust_str.rs
index 3d5ec34..a9e84ef 100644
--- a/src/symbols/rust_str.rs
+++ b/src/symbols/rust_str.rs
@@ -6,24 +6,20 @@
 
 #[export_name = "cxxbridge1$str$new"]
 unsafe extern "C" fn str_new(this: &mut MaybeUninit<&str>) {
-    let this = this.as_mut_ptr();
-    unsafe { ptr::write(this, "") }
+    ptr::write(this.as_mut_ptr(), "");
 }
 
 #[export_name = "cxxbridge1$str$ref"]
 unsafe extern "C" fn str_ref<'a>(this: &mut MaybeUninit<&'a str>, string: &'a String) {
-    let this = this.as_mut_ptr();
-    let s = string.as_str();
-    unsafe { ptr::write(this, s) }
+    ptr::write(this.as_mut_ptr(), string.as_str());
 }
 
 #[export_name = "cxxbridge1$str$from"]
 unsafe extern "C" fn str_from(this: &mut MaybeUninit<&str>, ptr: *const u8, len: usize) -> bool {
-    let slice = unsafe { slice::from_raw_parts(ptr, len) };
+    let slice = slice::from_raw_parts(ptr, len);
     match str::from_utf8(slice) {
         Ok(s) => {
-            let this = this.as_mut_ptr();
-            unsafe { ptr::write(this, s) }
+            ptr::write(this.as_mut_ptr(), s);
             true
         }
         Err(_) => false,
diff --git a/src/symbols/rust_string.rs b/src/symbols/rust_string.rs
index 49d4069..91fd78a 100644
--- a/src/symbols/rust_string.rs
+++ b/src/symbols/rust_string.rs
@@ -7,47 +7,24 @@
 
 #[export_name = "cxxbridge1$string$new"]
 unsafe extern "C" fn string_new(this: &mut MaybeUninit<String>) {
-    let this = this.as_mut_ptr();
-    let new = String::new();
-    unsafe { ptr::write(this, new) }
+    ptr::write(this.as_mut_ptr(), String::new());
 }
 
 #[export_name = "cxxbridge1$string$clone"]
 unsafe extern "C" fn string_clone(this: &mut MaybeUninit<String>, other: &String) {
-    let this = this.as_mut_ptr();
-    let clone = other.clone();
-    unsafe { ptr::write(this, clone) }
+    ptr::write(this.as_mut_ptr(), other.clone());
 }
 
-#[export_name = "cxxbridge1$string$from_utf8"]
-unsafe extern "C" fn string_from_utf8(
+#[export_name = "cxxbridge1$string$from"]
+unsafe extern "C" fn string_from(
     this: &mut MaybeUninit<String>,
     ptr: *const u8,
     len: usize,
 ) -> bool {
-    let slice = unsafe { slice::from_raw_parts(ptr, len) };
+    let slice = slice::from_raw_parts(ptr, len);
     match str::from_utf8(slice) {
         Ok(s) => {
-            let this = this.as_mut_ptr();
-            let owned = s.to_owned();
-            unsafe { ptr::write(this, owned) }
-            true
-        }
-        Err(_) => false,
-    }
-}
-
-#[export_name = "cxxbridge1$string$from_utf16"]
-unsafe extern "C" fn string_from_utf16(
-    this: &mut MaybeUninit<String>,
-    ptr: *const u16,
-    len: usize,
-) -> bool {
-    let slice = unsafe { slice::from_raw_parts(ptr, len) };
-    match String::from_utf16(slice) {
-        Ok(s) => {
-            let this = this.as_mut_ptr();
-            unsafe { ptr::write(this, s) }
+            ptr::write(this.as_mut_ptr(), s.to_owned());
             true
         }
         Err(_) => false,
@@ -56,7 +33,7 @@
 
 #[export_name = "cxxbridge1$string$drop"]
 unsafe extern "C" fn string_drop(this: &mut ManuallyDrop<String>) {
-    unsafe { ManuallyDrop::drop(this) }
+    ManuallyDrop::drop(this);
 }
 
 #[export_name = "cxxbridge1$string$ptr"]
@@ -69,20 +46,7 @@
     this.len()
 }
 
-#[export_name = "cxxbridge1$string$capacity"]
-unsafe extern "C" fn string_capacity(this: &String) -> usize {
-    this.capacity()
-}
-
-#[export_name = "cxxbridge1$string$reserve_additional"]
-unsafe extern "C" fn string_reserve_additional(this: &mut String, additional: usize) {
-    this.reserve(additional);
-}
-
 #[export_name = "cxxbridge1$string$reserve_total"]
-unsafe extern "C" fn string_reserve_total(this: &mut String, new_cap: usize) {
-    if new_cap > this.capacity() {
-        let additional = new_cap - this.len();
-        this.reserve(additional);
-    }
+unsafe extern "C" fn string_reserve_total(this: &mut String, cap: usize) {
+    this.reserve(cap);
 }
diff --git a/src/symbols/rust_vec.rs b/src/symbols/rust_vec.rs
index 6f2dab9..a26a156 100644
--- a/src/symbols/rust_vec.rs
+++ b/src/symbols/rust_vec.rs
@@ -7,51 +7,50 @@
 
 macro_rules! rust_vec_shims {
     ($segment:expr, $ty:ty) => {
-        const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<RustVec<$ty>>());
-        const_assert_eq!(mem::size_of::<Vec<$ty>>(), mem::size_of::<RustVec<$ty>>());
-        const_assert_eq!(mem::align_of::<Vec<$ty>>(), mem::align_of::<RustVec<$ty>>());
+        const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<Vec<$ty>>());
+        const_assert_eq!(mem::align_of::<usize>(), mem::align_of::<Vec<$ty>>());
 
         const _: () = {
             attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$new")]
                 unsafe extern "C" fn __new(this: *mut RustVec<$ty>) {
-                    unsafe { ptr::write(this, RustVec::new()) }
+                    ptr::write(this, RustVec { repr: Vec::new() });
                 }
             }
             attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$drop")]
                 unsafe extern "C" fn __drop(this: *mut RustVec<$ty>) {
-                    unsafe { ptr::drop_in_place(this) }
+                    ptr::drop_in_place(this);
                 }
             }
             attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$len")]
                 unsafe extern "C" fn __len(this: *const RustVec<$ty>) -> usize {
-                    unsafe { &*this }.len()
+                    (*this).repr.len()
                 }
             }
             attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$capacity")]
                 unsafe extern "C" fn __capacity(this: *const RustVec<$ty>) -> usize {
-                    unsafe { &*this }.capacity()
+                    (*this).repr.capacity()
                 }
             }
             attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$data")]
                 unsafe extern "C" fn __data(this: *const RustVec<$ty>) -> *const $ty {
-                    unsafe { &*this }.as_ptr()
+                    (*this).repr.as_ptr()
                 }
             }
             attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$reserve_total")]
-                unsafe extern "C" fn __reserve_total(this: *mut RustVec<$ty>, new_cap: usize) {
-                    unsafe { &mut *this }.reserve_total(new_cap);
+                unsafe extern "C" fn __reserve_total(this: *mut RustVec<$ty>, cap: usize) {
+                    (*this).reserve_total(cap);
                 }
             }
             attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$set_len")]
                 unsafe extern "C" fn __set_len(this: *mut RustVec<$ty>, len: usize) {
-                    unsafe { (*this).set_len(len) }
+                    (*this).repr.set_len(len);
                 }
             }
         };
diff --git a/src/unique_ptr.rs b/src/unique_ptr.rs
index 63a1ca7..836f467 100644
--- a/src/unique_ptr.rs
+++ b/src/unique_ptr.rs
@@ -6,9 +6,10 @@
 use core::ffi::c_void;
 use core::fmt::{self, Debug, Display};
 use core::marker::PhantomData;
-use core::mem::{self, MaybeUninit};
+use core::mem;
 use core::ops::{Deref, DerefMut};
 use core::pin::Pin;
+use core::ptr;
 
 /// Binding to C++ `std::unique_ptr<T, std::default_delete<T>>`.
 #[repr(C)]
@@ -16,7 +17,7 @@
 where
     T: UniquePtrTarget,
 {
-    repr: MaybeUninit<*mut c_void>,
+    repr: *mut c_void,
     ty: PhantomData<T>,
 }
 
@@ -103,7 +104,7 @@
     /// twice on the same raw pointer.
     pub unsafe fn from_raw(raw: *mut T) -> Self {
         UniquePtr {
-            repr: unsafe { T::__raw(raw) },
+            repr: T::__raw(raw),
             ty: PhantomData,
         }
     }
@@ -206,9 +207,9 @@
     #[doc(hidden)]
     fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
     #[doc(hidden)]
-    fn __null() -> MaybeUninit<*mut c_void>;
+    fn __null() -> *mut c_void;
     #[doc(hidden)]
-    fn __new(value: Self) -> MaybeUninit<*mut c_void>
+    fn __new(value: Self) -> *mut c_void
     where
         Self: Sized,
     {
@@ -218,26 +219,26 @@
         unreachable!()
     }
     #[doc(hidden)]
-    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>;
+    unsafe fn __raw(raw: *mut Self) -> *mut c_void;
     #[doc(hidden)]
-    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self;
+    unsafe fn __get(repr: *mut c_void) -> *const Self;
     #[doc(hidden)]
-    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self;
+    unsafe fn __release(repr: *mut c_void) -> *mut Self;
     #[doc(hidden)]
-    unsafe fn __drop(repr: MaybeUninit<*mut c_void>);
+    unsafe fn __drop(repr: *mut c_void);
 }
 
 extern "C" {
     #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
-    fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>);
+    fn unique_ptr_std_string_null(this: *mut *mut c_void);
     #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
-    fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString);
+    fn unique_ptr_std_string_raw(this: *mut *mut c_void, raw: *mut CxxString);
     #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
-    fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString;
+    fn unique_ptr_std_string_get(this: *const *mut c_void) -> *const CxxString;
     #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
-    fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString;
+    fn unique_ptr_std_string_release(this: *mut *mut c_void) -> *mut CxxString;
     #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
-    fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>);
+    fn unique_ptr_std_string_drop(this: *mut *mut c_void);
 }
 
 unsafe impl UniquePtrTarget for CxxString {
@@ -246,30 +247,30 @@
         f.write_str("CxxString")
     }
     #[doc(hidden)]
-    fn __null() -> MaybeUninit<*mut c_void> {
-        let mut repr = MaybeUninit::uninit();
+    fn __null() -> *mut c_void {
+        let mut repr = ptr::null_mut::<c_void>();
         unsafe {
             unique_ptr_std_string_null(&mut repr);
         }
         repr
     }
     #[doc(hidden)]
-    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
-        let mut repr = MaybeUninit::uninit();
-        unsafe { unique_ptr_std_string_raw(&mut repr, raw) }
+    unsafe fn __raw(raw: *mut Self) -> *mut c_void {
+        let mut repr = ptr::null_mut::<c_void>();
+        unique_ptr_std_string_raw(&mut repr, raw);
         repr
     }
     #[doc(hidden)]
-    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
-        unsafe { unique_ptr_std_string_get(&repr) }
+    unsafe fn __get(repr: *mut c_void) -> *const Self {
+        unique_ptr_std_string_get(&repr)
     }
     #[doc(hidden)]
-    unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {
-        unsafe { unique_ptr_std_string_release(&mut repr) }
+    unsafe fn __release(mut repr: *mut c_void) -> *mut Self {
+        unique_ptr_std_string_release(&mut repr)
     }
     #[doc(hidden)]
-    unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {
-        unsafe { unique_ptr_std_string_drop(&mut repr) }
+    unsafe fn __drop(mut repr: *mut c_void) {
+        unique_ptr_std_string_drop(&mut repr);
     }
 }
 
@@ -282,23 +283,23 @@
         write!(f, "CxxVector<{}>", display(T::__typename))
     }
     #[doc(hidden)]
-    fn __null() -> MaybeUninit<*mut c_void> {
+    fn __null() -> *mut c_void {
         T::__unique_ptr_null()
     }
     #[doc(hidden)]
-    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
-        unsafe { T::__unique_ptr_raw(raw) }
+    unsafe fn __raw(raw: *mut Self) -> *mut c_void {
+        T::__unique_ptr_raw(raw)
     }
     #[doc(hidden)]
-    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
-        unsafe { T::__unique_ptr_get(repr) }
+    unsafe fn __get(repr: *mut c_void) -> *const Self {
+        T::__unique_ptr_get(repr)
     }
     #[doc(hidden)]
-    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {
-        unsafe { T::__unique_ptr_release(repr) }
+    unsafe fn __release(repr: *mut c_void) -> *mut Self {
+        T::__unique_ptr_release(repr)
     }
     #[doc(hidden)]
-    unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {
-        unsafe { T::__unique_ptr_drop(repr) }
+    unsafe fn __drop(repr: *mut c_void) {
+        T::__unique_ptr_drop(repr);
     }
 }
diff --git a/src/unwind.rs b/src/unwind.rs
index 4967a21..36f6ae3 100644
--- a/src/unwind.rs
+++ b/src/unwind.rs
@@ -1,5 +1,3 @@
-#![allow(missing_docs)]
-
 use std::io::{self, Write};
 use std::panic::{self, AssertUnwindSafe};
 use std::process;
diff --git a/src/weak_ptr.rs b/src/weak_ptr.rs
index 8a9f1a6..8291d59 100644
--- a/src/weak_ptr.rs
+++ b/src/weak_ptr.rs
@@ -16,7 +16,7 @@
 where
     T: WeakPtrTarget,
 {
-    repr: [MaybeUninit<*mut c_void>; 2],
+    repr: [*mut c_void; 2],
     ty: PhantomData<T>,
 }
 
@@ -91,11 +91,8 @@
     }
 }
 
-/// Trait bound for types which may be used as the `T` inside of a `WeakPtr<T>`
-/// in generic code.
-///
-/// This trait has no publicly callable or implementable methods. Implementing
-/// it outside of the CXX codebase is not supported.
+// Methods are private; not intended to be implemented outside of cxxbridge
+// codebase.
 pub unsafe trait WeakPtrTarget {
     #[doc(hidden)]
     fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
@@ -126,7 +123,7 @@
                         fn __null(new: *mut c_void);
                     }
                 }
-                unsafe { __null(new) }
+                __null(new);
             }
             #[doc(hidden)]
             unsafe fn __clone(this: *const c_void, new: *mut c_void) {
@@ -136,7 +133,7 @@
                         fn __clone(this: *const c_void, new: *mut c_void);
                     }
                 }
-                unsafe { __clone(this, new) }
+                __clone(this, new);
             }
             #[doc(hidden)]
             unsafe fn __downgrade(shared: *const c_void, weak: *mut c_void) {
@@ -146,7 +143,7 @@
                         fn __downgrade(shared: *const c_void, weak: *mut c_void);
                     }
                 }
-                unsafe { __downgrade(shared, weak) }
+                __downgrade(shared, weak);
             }
             #[doc(hidden)]
             unsafe fn __upgrade(weak: *const c_void, shared: *mut c_void) {
@@ -156,7 +153,7 @@
                         fn __upgrade(weak: *const c_void, shared: *mut c_void);
                     }
                 }
-                unsafe { __upgrade(weak, shared) }
+                __upgrade(weak, shared);
             }
             #[doc(hidden)]
             unsafe fn __drop(this: *mut c_void) {
@@ -166,7 +163,7 @@
                         fn __drop(this: *mut c_void);
                     }
                 }
-                unsafe { __drop(this) }
+                __drop(this);
             }
         }
     };
diff --git a/syntax/attrs.rs b/syntax/attrs.rs
index fa6c809..4808f2e 100644
--- a/syntax/attrs.rs
+++ b/syntax/attrs.rs
@@ -4,7 +4,7 @@
 use crate::syntax::{Derive, Doc, ForeignName};
 use proc_macro2::{Ident, TokenStream};
 use quote::ToTokens;
-use syn::parse::{Nothing, Parse, ParseStream, Parser as _};
+use syn::parse::{ParseStream, Parser as _};
 use syn::{Attribute, Error, LitStr, Path, Result, Token};
 
 // Intended usage:
@@ -33,7 +33,6 @@
     pub namespace: Option<&'a mut Namespace>,
     pub cxx_name: Option<&'a mut Option<ForeignName>>,
     pub rust_name: Option<&'a mut Option<Ident>>,
-    pub variants_from_header: Option<&'a mut Option<Attribute>>,
 
     // Suppress clippy needless_update lint ("struct update has no effect, all
     // the fields in the struct have already been specified") when preemptively
@@ -122,14 +121,6 @@
                     break;
                 }
             }
-        } else if attr.path.is_ident("variants_from_header") && cfg!(feature = "experimental") {
-            if let Err(err) = Nothing::parse.parse2(attr.tokens.clone()) {
-                cx.push(err);
-            }
-            if let Some(variants_from_header) = &mut parser.variants_from_header {
-                **variants_from_header = Some(attr);
-                continue;
-            }
         } else if attr.path.is_ident("allow")
             || attr.path.is_ident("warn")
             || attr.path.is_ident("deny")
@@ -233,19 +224,7 @@
 impl ToTokens for OtherAttrs {
     fn to_tokens(&self, tokens: &mut TokenStream) {
         for attr in &self.0 {
-            let Attribute {
-                pound_token,
-                style,
-                bracket_token,
-                path,
-                tokens: attr_tokens,
-            } = attr;
-            pound_token.to_tokens(tokens);
-            let _ = style; // ignore; render outer and inner attrs both as outer
-            bracket_token.surround(tokens, |tokens| {
-                path.to_tokens(tokens);
-                attr_tokens.to_tokens(tokens);
-            });
+            attr.to_tokens(tokens);
         }
     }
 }
diff --git a/syntax/check.rs b/syntax/check.rs
index 698782f..bab2dec 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -2,40 +2,24 @@
 use crate::syntax::report::Errors;
 use crate::syntax::visit::{self, Visit};
 use crate::syntax::{
-    error, ident, trivial, Api, Array, Enum, ExternFn, ExternType, Impl, Lang, Lifetimes,
-    NamedType, Ptr, Receiver, Ref, Signature, SliceRef, Struct, Trait, Ty1, Type, TypeAlias, Types,
+    error, ident, trivial, Api, Array, Enum, ExternFn, ExternType, Impl, Lang, NamedType, Ptr,
+    Receiver, Ref, Signature, SliceRef, Struct, Trait, Ty1, Type, TypeAlias, Types,
 };
 use proc_macro2::{Delimiter, Group, Ident, TokenStream};
 use quote::{quote, ToTokens};
 use std::fmt::Display;
-use syn::{GenericParam, Generics, Lifetime};
 
 pub(crate) struct Check<'a> {
     apis: &'a [Api],
     types: &'a Types<'a>,
     errors: &'a mut Errors,
-    generator: Generator,
 }
 
-pub(crate) enum Generator {
-    // cxx-build crate, cxxbridge cli, cxx-gen.
-    #[allow(dead_code)]
-    Build,
-    // cxxbridge-macro. This is relevant in that the macro output is going to
-    // get fed straight to rustc, so for errors that rustc already contains
-    // logic to catch (probably with a better diagnostic than what the proc
-    // macro API is able to produce), we avoid duplicating them in our own
-    // diagnostics.
-    #[allow(dead_code)]
-    Macro,
-}
-
-pub(crate) fn typecheck(cx: &mut Errors, apis: &[Api], types: &Types, generator: Generator) {
+pub(crate) fn typecheck(cx: &mut Errors, apis: &[Api], types: &Types) {
     do_typecheck(&mut Check {
         apis,
         types,
         errors: cx,
-        generator,
     });
 }
 
@@ -266,9 +250,7 @@
 fn check_type_slice_ref(cx: &mut Check, ty: &SliceRef) {
     let supported = !is_unsized(cx, &ty.inner)
         || match &ty.inner {
-            Type::Ident(ident) => {
-                cx.types.rust.contains(&ident.rust) || cx.types.aliases.contains_key(&ident.rust)
-            }
+            Type::Ident(ident) => cx.types.rust.contains(&ident.rust),
             _ => false,
         };
 
@@ -312,7 +294,6 @@
 fn check_api_struct(cx: &mut Check, strct: &Struct) {
     let name = &strct.name;
     check_reserved_name(cx, &name.rust);
-    check_lifetimes(cx, &strct.generics);
 
     if strct.fields.is_empty() {
         let span = span_for_struct_error(strct);
@@ -349,9 +330,8 @@
 
 fn check_api_enum(cx: &mut Check, enm: &Enum) {
     check_reserved_name(cx, &enm.name.rust);
-    check_lifetimes(cx, &enm.generics);
 
-    if enm.variants.is_empty() && !enm.explicit_repr && !enm.variants_from_header {
+    if enm.variants.is_empty() && !enm.explicit_repr {
         let span = span_for_enum_error(enm);
         cx.error(
             span,
@@ -369,7 +349,6 @@
 
 fn check_api_type(cx: &mut Check, ety: &ExternType) {
     check_reserved_name(cx, &ety.name.rust);
-    check_lifetimes(cx, &ety.generics);
 
     for derive in &ety.derives {
         if derive.what == Trait::ExternType && ety.lang == Lang::Rust {
@@ -421,8 +400,6 @@
         }
     }
 
-    check_generics(cx, &efn.sig.generics);
-
     if let Some(receiver) = &efn.receiver {
         let ref span = span_for_receiver_error(receiver);
 
@@ -495,8 +472,6 @@
 }
 
 fn check_api_type_alias(cx: &mut Check, alias: &TypeAlias) {
-    check_lifetimes(cx, &alias.generics);
-
     for derive in &alias.derives {
         let msg = format!("derive({}) on extern type alias is not supported", derive);
         cx.error(derive, msg);
@@ -506,8 +481,6 @@
 fn check_api_impl(cx: &mut Check, imp: &Impl) {
     let ty = &imp.ty;
 
-    check_lifetimes(cx, &imp.impl_generics);
-
     if let Some(negative) = imp.negative_token {
         let span = quote!(#negative #ty);
         cx.error(span, "negative impl is not supported yet");
@@ -610,31 +583,6 @@
     }
 }
 
-fn check_reserved_lifetime(cx: &mut Check, lifetime: &Lifetime) {
-    if lifetime.ident == "static" {
-        match cx.generator {
-            Generator::Macro => { /* rustc already reports this */ }
-            Generator::Build => {
-                cx.error(lifetime, error::RESERVED_LIFETIME);
-            }
-        }
-    }
-}
-
-fn check_lifetimes(cx: &mut Check, generics: &Lifetimes) {
-    for lifetime in &generics.lifetimes {
-        check_reserved_lifetime(cx, lifetime);
-    }
-}
-
-fn check_generics(cx: &mut Check, generics: &Generics) {
-    for generic_param in &generics.params {
-        if let GenericParam::Lifetime(def) = generic_param {
-            check_reserved_lifetime(cx, &def.lifetime);
-        }
-    }
-}
-
 fn is_unsized(cx: &mut Check, ty: &Type) -> bool {
     match ty {
         Type::Ident(ident) => {
diff --git a/syntax/discriminant.rs b/syntax/discriminant.rs
index fff8f75..80f7c0b 100644
--- a/syntax/discriminant.rs
+++ b/syntax/discriminant.rs
@@ -150,7 +150,7 @@
 }
 
 impl Discriminant {
-    pub const fn zero() -> Self {
+    const fn zero() -> Self {
         Discriminant {
             sign: Sign::Positive,
             magnitude: 0,
@@ -179,28 +179,6 @@
             magnitude: i.wrapping_abs() as u64,
         }
     }
-
-    pub const fn checked_succ(self) -> Option<Self> {
-        match self.sign {
-            Sign::Negative => {
-                if self.magnitude == 1 {
-                    Some(Discriminant::zero())
-                } else {
-                    Some(Discriminant {
-                        sign: Sign::Negative,
-                        magnitude: self.magnitude - 1,
-                    })
-                }
-            }
-            Sign::Positive => match self.magnitude.checked_add(1) {
-                Some(magnitude) => Some(Discriminant {
-                    sign: Sign::Positive,
-                    magnitude,
-                }),
-                None => None,
-            },
-        }
-    }
 }
 
 impl Display for Discriminant {
@@ -208,7 +186,7 @@
         if self.sign == Sign::Negative {
             f.write_str("-")?;
         }
-        write!(f, "{}", self.magnitude)
+        Display::fmt(&self.magnitude, f)
     }
 }
 
diff --git a/syntax/doc.rs b/syntax/doc.rs
index cd764fa..60bb4da 100644
--- a/syntax/doc.rs
+++ b/syntax/doc.rs
@@ -17,10 +17,6 @@
         self.fragments.push(lit);
     }
 
-    pub fn is_empty(&self) -> bool {
-        self.fragments.is_empty()
-    }
-
     pub fn to_string(&self) -> String {
         let mut doc = String::new();
         for lit in &self.fragments {
diff --git a/syntax/error.rs b/syntax/error.rs
index f40c4a8..a672329 100644
--- a/syntax/error.rs
+++ b/syntax/error.rs
@@ -21,7 +21,6 @@
     DISCRIMINANT_OVERFLOW,
     DOT_INCLUDE,
     DOUBLE_UNDERSCORE,
-    RESERVED_LIFETIME,
     RUST_TYPE_BY_VALUE,
     UNSUPPORTED_TYPE,
     USE_NOT_ALLOWED,
@@ -69,12 +68,6 @@
     note: Some("identifiers containing double underscore are reserved in C++"),
 };
 
-pub static RESERVED_LIFETIME: Error = Error {
-    msg: "invalid lifetime parameter name: `'static`",
-    label: Some("'static is a reserved lifetime name"),
-    note: None,
-};
-
 pub static RUST_TYPE_BY_VALUE: Error = Error {
     msg: "opaque Rust type by value is not supported",
     label: None,
diff --git a/syntax/file.rs b/syntax/file.rs
index 99466b8..fd6dd98 100644
--- a/syntax/file.rs
+++ b/syntax/file.rs
@@ -91,32 +91,17 @@
 
         let item = input.parse()?;
         match item {
-            RustItem::Struct(mut item) => {
-                item.attrs.splice(..0, attrs);
-                Ok(Item::Struct(item))
-            }
-            RustItem::Enum(mut item) => {
-                item.attrs.splice(..0, attrs);
-                Ok(Item::Enum(item))
-            }
-            RustItem::ForeignMod(mut item) => {
-                item.attrs.splice(..0, attrs);
-                Ok(Item::ForeignMod(ItemForeignMod {
-                    attrs: item.attrs,
-                    unsafety,
-                    abi: item.abi,
-                    brace_token: item.brace_token,
-                    items: item.items,
-                }))
-            }
-            RustItem::Impl(mut item) => {
-                item.attrs.splice(..0, attrs);
-                Ok(Item::Impl(item))
-            }
-            RustItem::Use(mut item) => {
-                item.attrs.splice(..0, attrs);
-                Ok(Item::Use(item))
-            }
+            RustItem::Struct(item) => Ok(Item::Struct(ItemStruct { attrs, ..item })),
+            RustItem::Enum(item) => Ok(Item::Enum(ItemEnum { attrs, ..item })),
+            RustItem::ForeignMod(item) => Ok(Item::ForeignMod(ItemForeignMod {
+                attrs,
+                unsafety,
+                abi: item.abi,
+                brace_token: item.brace_token,
+                items: item.items,
+            })),
+            RustItem::Impl(item) => Ok(Item::Impl(ItemImpl { attrs, ..item })),
+            RustItem::Use(item) => Ok(Item::Use(ItemUse { attrs, ..item })),
             other => Ok(Item::Other(other)),
         }
     }
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 06d68dc..8b0743b 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -339,7 +339,6 @@
                     attrs: _,
                     visibility: _,
                     name: _,
-                    colon_token: _,
                     ty,
                 } = arg;
                 let Var {
@@ -347,7 +346,6 @@
                     attrs: _,
                     visibility: _,
                     name: _,
-                    colon_token: _,
                     ty: ty2,
                 } = arg2;
                 ty == ty2
@@ -376,7 +374,6 @@
                 attrs: _,
                 visibility: _,
                 name: _,
-                colon_token: _,
                 ty,
             } = arg;
             ty.hash(state);
@@ -396,7 +393,6 @@
             lifetime,
             mutable,
             var: _,
-            colon_token: _,
             ty,
             shorthand: _,
             pin_tokens: _,
@@ -408,7 +404,6 @@
             lifetime: lifetime2,
             mutable: mutable2,
             var: _,
-            colon_token: _,
             ty: ty2,
             shorthand: _,
             pin_tokens: _,
@@ -426,7 +421,6 @@
             lifetime,
             mutable,
             var: _,
-            colon_token: _,
             ty,
             shorthand: _,
             pin_tokens: _,
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 1d98634..3d56293 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -30,17 +30,17 @@
 mod visit;
 
 use self::attrs::OtherAttrs;
+use self::discriminant::Discriminant;
 use self::namespace::Namespace;
 use self::parse::kw;
 use self::symbol::Symbol;
 use proc_macro2::{Ident, Span};
 use syn::punctuated::Punctuated;
 use syn::token::{Brace, Bracket, Paren};
-use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Path, Token, Type as RustType};
+use syn::{Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
 
 pub use self::atom::Atom;
 pub use self::derive::{Derive, Trait};
-pub use self::discriminant::Discriminant;
 pub use self::doc::Doc;
 pub use self::names::ForeignName;
 pub use self::parse::parse_items;
@@ -111,17 +111,11 @@
     pub generics: Lifetimes,
     pub brace_token: Brace,
     pub variants: Vec<Variant>,
-    pub variants_from_header: bool,
-    pub variants_from_header_attr: Option<Attribute>,
-    pub repr: EnumRepr,
+    pub repr: Atom,
+    pub repr_type: Type,
     pub explicit_repr: bool,
 }
 
-pub enum EnumRepr {
-    Native { atom: Atom, repr_type: Type },
-    Foreign { rust_type: Path },
-}
-
 pub struct ExternFn {
     pub lang: Lang,
     pub doc: Doc,
@@ -180,7 +174,6 @@
     pub attrs: OtherAttrs,
     pub visibility: Token![pub],
     pub name: Pair,
-    pub colon_token: Token![:],
     pub ty: Type,
 }
 
@@ -191,7 +184,6 @@
     pub mutable: bool,
     pub var: Token![self],
     pub ty: NamedType,
-    pub colon_token: Token![:],
     pub shorthand: bool,
     pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
     pub mutability: Option<Token![mut]>,
diff --git a/syntax/names.rs b/syntax/names.rs
index 7a125ae..cb6ace5 100644
--- a/syntax/names.rs
+++ b/syntax/names.rs
@@ -9,6 +9,7 @@
 #[derive(Clone)]
 pub struct ForeignName {
     text: String,
+    span: Span,
 }
 
 impl Pair {
@@ -55,7 +56,7 @@
         match syn::parse_str::<Ident>(text) {
             Ok(ident) => {
                 let text = ident.to_string();
-                Ok(ForeignName { text })
+                Ok(ForeignName { text, span })
             }
             Err(err) => Err(Error::new(span, err)),
         }
@@ -67,9 +68,3 @@
         formatter.write_str(&self.text)
     }
 }
-
-impl PartialEq<str> for ForeignName {
-    fn eq(&self, rhs: &str) -> bool {
-        self.text == rhs
-    }
-}
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 32d36eb..d792076 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -4,9 +4,9 @@
 use crate::syntax::report::Errors;
 use crate::syntax::Atom::*;
 use crate::syntax::{
-    attrs, error, Api, Array, Derive, Doc, Enum, EnumRepr, ExternFn, ExternType, ForeignName, Impl,
-    Include, IncludeKind, Lang, Lifetimes, NamedType, Namespace, Pair, Ptr, Receiver, Ref,
-    Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var, Variant,
+    attrs, error, Api, Array, Derive, Doc, Enum, ExternFn, ExternType, ForeignName, Impl, Include,
+    IncludeKind, Lang, Lifetimes, NamedType, Namespace, Pair, Ptr, Receiver, Ref, Signature,
+    SliceRef, Struct, Ty1, Type, TypeAlias, Var, Variant,
 };
 use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
 use quote::{format_ident, quote, quote_spanned};
@@ -146,13 +146,11 @@
         };
         let visibility = visibility_pub(&field.vis, ident.span());
         let name = pair(Namespace::default(), &ident, cxx_name, rust_name);
-        let colon_token = field.colon_token.unwrap();
         fields.push(Var {
             doc,
             attrs,
             visibility,
             name,
-            colon_token,
             ty,
         });
     }
@@ -187,7 +185,6 @@
     let mut namespace = namespace.clone();
     let mut cxx_name = None;
     let mut rust_name = None;
-    let mut variants_from_header = None;
     let attrs = attrs::parse(
         cx,
         item.attrs,
@@ -198,7 +195,6 @@
             namespace: Some(&mut namespace),
             cxx_name: Some(&mut cxx_name),
             rust_name: Some(&mut rust_name),
-            variants_from_header: Some(&mut variants_from_header),
             ..Default::default()
         },
     );
@@ -241,17 +237,11 @@
     let name = pair(namespace, &item.ident, cxx_name, rust_name);
     let repr_ident = Ident::new(repr.as_ref(), Span::call_site());
     let repr_type = Type::Ident(NamedType::new(repr_ident));
-    let repr = EnumRepr::Native {
-        atom: repr,
-        repr_type,
-    };
     let generics = Lifetimes {
         lt_token: None,
         lifetimes: Punctuated::new(),
         gt_token: None,
     };
-    let variants_from_header_attr = variants_from_header;
-    let variants_from_header = variants_from_header_attr.is_some();
 
     Api::Enum(Enum {
         doc,
@@ -263,9 +253,8 @@
         generics,
         brace_token,
         variants,
-        variants_from_header,
-        variants_from_header_attr,
         repr,
+        repr_type,
         explicit_repr,
     })
 }
@@ -571,7 +560,6 @@
                         lifetime: lifetime.clone(),
                         mutable: arg.mutability.is_some(),
                         var: arg.self_token,
-                        colon_token: Token![:](arg.self_token.span),
                         ty: NamedType::new(Ident::new("Self", arg.self_token.span)),
                         shorthand: true,
                         pin_tokens: None,
@@ -595,13 +583,11 @@
                     let attrs = OtherAttrs::none();
                     let visibility = Token![pub](ident.span());
                     let name = pair(Namespace::default(), &ident, None, None);
-                    let colon_token = arg.colon_token;
                     args.push_value(Var {
                         doc,
                         attrs,
                         visibility,
                         name,
-                        colon_token,
                         ty,
                     });
                     if let Some(comma) = comma {
@@ -617,7 +603,6 @@
                             lifetime: reference.lifetime,
                             mutable: reference.mutable,
                             var: Token![self](ident.rust.span()),
-                            colon_token: arg.colon_token,
                             ty: ident,
                             shorthand: false,
                             pin_tokens: reference.pin_tokens,
@@ -1287,16 +1272,11 @@
         .iter()
         .enumerate()
         .map(|(i, arg)| {
-            let (ident, colon_token) = match &arg.name {
-                Some((ident, colon_token)) => (ident.clone(), *colon_token),
-                None => {
-                    let fn_span = ty.paren_token.span;
-                    let ident = format_ident!("arg{}", i, span = fn_span);
-                    let colon_token = Token![:](fn_span);
-                    (ident, colon_token)
-                }
-            };
             let ty = parse_type(&arg.ty)?;
+            let ident = match &arg.name {
+                Some(ident) => ident.0.clone(),
+                None => format_ident!("arg{}", i),
+            };
             let doc = Doc::new();
             let attrs = OtherAttrs::none();
             let visibility = Token![pub](ident.span());
@@ -1306,7 +1286,6 @@
                 attrs,
                 visibility,
                 name,
-                colon_token,
                 ty,
             })
         })
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index 33f20fa..c1a06a2 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -1,7 +1,7 @@
 use crate::syntax::atom::Atom::*;
 use crate::syntax::{
-    Array, Atom, Derive, Enum, EnumRepr, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr,
-    Receiver, Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
+    Array, Atom, Derive, Enum, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr, Receiver,
+    Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
 };
 use proc_macro2::{Ident, Span, TokenStream};
 use quote::{quote_spanned, ToTokens};
@@ -43,7 +43,6 @@
             attrs: _,
             visibility: _,
             name,
-            colon_token: _,
             ty,
         } = self;
         name.rust.to_tokens(tokens);
@@ -280,15 +279,6 @@
     }
 }
 
-impl ToTokens for EnumRepr {
-    fn to_tokens(&self, tokens: &mut TokenStream) {
-        match self {
-            EnumRepr::Native { atom, repr_type: _ } => atom.to_tokens(tokens),
-            EnumRepr::Foreign { rust_type } => rust_type.to_tokens(tokens),
-        }
-    }
-}
-
 impl ToTokens for NamedType {
     fn to_tokens(&self, tokens: &mut TokenStream) {
         let NamedType { rust, generics } = self;
@@ -320,7 +310,6 @@
             lifetime,
             mutable: _,
             var: _,
-            colon_token: _,
             ty,
             shorthand: _,
             pin_tokens,
@@ -348,7 +337,6 @@
             lifetime,
             mutable: _,
             var: _,
-            colon_token: _,
             ty,
             shorthand: _,
             pin_tokens,
diff --git a/syntax/trivial.rs b/syntax/trivial.rs
index 067e2d7..fe95e2b 100644
--- a/syntax/trivial.rs
+++ b/syntax/trivial.rs
@@ -11,7 +11,6 @@
     FunctionReturn(&'a ExternFn),
     BoxTarget,
     VecElement,
-    SliceElement { mutable: bool },
     UnpinnedMut(&'a ExternFn),
 }
 
@@ -106,14 +105,6 @@
                     insist_extern_types_are_trivial(ident, reason);
                 }
             }
-            Type::SliceRef(ty) => {
-                if let Type::Ident(ident) = &ty.inner {
-                    let reason = TrivialReason::SliceElement {
-                        mutable: ty.mutable,
-                    };
-                    insist_extern_types_are_trivial(ident, reason);
-                }
-            }
             _ => {}
         }
     }
@@ -137,8 +128,6 @@
             let mut return_of = Set::new();
             let mut box_target = false;
             let mut vec_element = false;
-            let mut slice_shared_element = false;
-            let mut slice_mut_element = false;
             let mut unpinned_mut = Set::new();
 
             for reason in self.reasons {
@@ -154,13 +143,6 @@
                     }
                     TrivialReason::BoxTarget => box_target = true,
                     TrivialReason::VecElement => vec_element = true,
-                    TrivialReason::SliceElement { mutable } => {
-                        if *mutable {
-                            slice_mut_element = true;
-                        } else {
-                            slice_shared_element = true;
-                        }
-                    }
                     TrivialReason::UnpinnedMut(efn) => {
                         unpinned_mut.insert(&efn.name.rust);
                     }
@@ -203,15 +185,6 @@
                     param: self.name,
                 });
             }
-            if slice_shared_element || slice_mut_element {
-                clauses.push(Clause::Slice {
-                    article: "a",
-                    desc: "slice element in",
-                    shared: slice_shared_element,
-                    mutable: slice_mut_element,
-                    param: self.name,
-                });
-            }
             if !unpinned_mut.is_empty() {
                 clauses.push(Clause::Set {
                     article: "a",
@@ -246,21 +219,12 @@
             desc: &'a str,
             param: &'a Pair,
         },
-        Slice {
-            article: &'a str,
-            desc: &'a str,
-            shared: bool,
-            mutable: bool,
-            param: &'a Pair,
-        },
     }
 
     impl<'a> Clause<'a> {
         fn article(&self) -> &'a str {
             match self {
-                Clause::Set { article, .. }
-                | Clause::Ty1 { article, .. }
-                | Clause::Slice { article, .. } => article,
+                Clause::Set { article, .. } | Clause::Ty1 { article, .. } => article,
             }
         }
 
@@ -285,25 +249,6 @@
                     desc,
                     param,
                 } => write!(f, "{}<{}>", desc, param.rust),
-                Clause::Slice {
-                    article: _,
-                    desc,
-                    shared,
-                    mutable,
-                    param,
-                } => {
-                    write!(f, "{} ", desc)?;
-                    if *shared {
-                        write!(f, "&[{}]", param.rust)?;
-                    }
-                    if *shared && *mutable {
-                        write!(f, " and ")?;
-                    }
-                    if *mutable {
-                        write!(f, "&mut [{}]", param.rust)?;
-                    }
-                    Ok(())
-                }
             }
         }
     }
diff --git a/syntax/types.rs b/syntax/types.rs
index c54682b..af7916d 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -7,7 +7,7 @@
 use crate::syntax::trivial::{self, TrivialReason};
 use crate::syntax::visit::{self, Visit};
 use crate::syntax::{
-    toposort, Api, Atom, Enum, EnumRepr, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,
+    toposort, Api, Atom, Enum, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,
 };
 use proc_macro2::Ident;
 use quote::ToTokens;
@@ -88,12 +88,7 @@
                     add_resolution(&strct.name, &strct.generics);
                 }
                 Api::Enum(enm) => {
-                    match &enm.repr {
-                        EnumRepr::Native { atom: _, repr_type } => {
-                            all.insert(repr_type);
-                        }
-                        EnumRepr::Foreign { rust_type: _ } => {}
-                    }
+                    all.insert(&enm.repr_type);
                     let ident = &enm.name.rust;
                     if !type_names.insert(ident)
                         && (!cxx.contains(ident)
@@ -106,11 +101,6 @@
                         duplicate_name(cx, enm, ident);
                     }
                     enums.insert(ident, enm);
-                    if enm.variants_from_header {
-                        // #![variants_from_header] enums are implicitly extern
-                        // C++ type.
-                        cxx.insert(&enm.name.rust);
-                    }
                     add_resolution(&enm.name, &enm.generics);
                 }
                 Api::CxxType(ety) => {
@@ -260,14 +250,6 @@
             ImproperCtype::Depends(ident) => self.struct_improper_ctypes.contains(ident),
         }
     }
-
-    // Types which we need to assume could possibly exist by value on the Rust
-    // side.
-    pub fn is_maybe_trivial(&self, ty: &Ident) -> bool {
-        self.structs.contains_key(ty)
-            || self.enums.contains_key(ty)
-            || self.aliases.contains_key(ty)
-    }
 }
 
 impl<'t, 'a> IntoIterator for &'t Types<'a> {
diff --git a/tests/BUILD b/tests/BUILD
index d4af3af..7886e4f 100644
--- a/tests/BUILD
+++ b/tests/BUILD
@@ -1,5 +1,5 @@
 load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_library", "rust_test")
+load("//tools/bazel:rust.bzl", "rust_library", "rust_test")
 load("//tools/bazel:rust_cxx_bridge.bzl", "rust_cxx_bridge")
 
 rust_test(
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index 25b4ccd..fcbe153 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -157,10 +157,6 @@
         fn c_take_ref_rust_vec_copy(v: &Vec<u8>);
         fn c_take_ref_shared_string(s: &SharedString) -> &SharedString;
         fn c_take_callback(callback: fn(String) -> usize);
-        fn c_take_callback_ref(callback: fn(&String));
-        #[cxx_name = "c_take_callback_ref"]
-        fn c_take_callback_ref_lifetime<'a>(callback: fn(&'a String));
-        fn c_take_callback_mut(callback: fn(&mut String));
         fn c_take_enum(e: Enum);
         fn c_take_ns_enum(e: AEnum);
         fn c_take_nested_ns_enum(e: ABEnum);
@@ -326,7 +322,6 @@
     }
 
     impl Box<Shared> {}
-    impl CxxVector<SharedString> {}
 }
 
 mod other {
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index df7ded0..ba12ed4 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -336,13 +336,13 @@
 }
 
 void c_take_unique_ptr_vector_u8(std::unique_ptr<std::vector<uint8_t>> v) {
-  if (v->size() == 3) {
+  if (v->size() == 4) {
     cxx_test_suite_set_correct();
   }
 }
 
 void c_take_unique_ptr_vector_f64(std::unique_ptr<std::vector<double>> v) {
-  if (v->size() == 5) {
+  if (v->size() == 4) {
     cxx_test_suite_set_correct();
   }
 }
@@ -354,7 +354,7 @@
 }
 
 void c_take_unique_ptr_vector_shared(std::unique_ptr<std::vector<Shared>> v) {
-  if (v->size() == 3) {
+  if (v->size() == 2) {
     cxx_test_suite_set_correct();
   }
 }
@@ -494,16 +494,6 @@
   callback("2020");
 }
 
-void c_take_callback_ref(rust::Fn<void(const rust::String &)> callback) {
-  const rust::String string = "2020";
-  callback(string);
-}
-
-void c_take_callback_mut(rust::Fn<void(rust::String &)> callback) {
-  rust::String string = "2020";
-  callback(string);
-}
-
 void c_take_enum(Enum e) {
   if (e == Enum::AVal) {
     cxx_test_suite_set_correct();
@@ -835,24 +825,12 @@
   ASSERT(cstring == "foo");
   ASSERT(other_cstring == "test");
 
-  ASSERT(cstring.capacity() == 3);
-  cstring.reserve(2);
-  ASSERT(cstring.capacity() == 3);
-  cstring.reserve(5);
-  ASSERT(cstring.capacity() >= 5);
-
   rust::Str cstr = "test";
   rust::Str other_cstr = "foo";
   swap(cstr, other_cstr);
   ASSERT(cstr == "foo");
   ASSERT(other_cstr == "test");
 
-  const char *utf8_literal = u8"Test string";
-  const char16_t *utf16_literal = u"Test string";
-  rust::String utf8_rstring = utf8_literal;
-  rust::String utf16_rstring = utf16_literal;
-  ASSERT(utf8_rstring == utf16_rstring);
-
   rust::Vec<int> vec1{1, 2};
   rust::Vec<int> vec2{3, 4};
   swap(vec1, vec2);
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index b624d39..74acbf4 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -160,8 +160,6 @@
 void c_take_ref_rust_vec_copy(const rust::Vec<uint8_t> &v);
 const SharedString &c_take_ref_shared_string(const SharedString &s);
 void c_take_callback(rust::Fn<size_t(rust::String)> callback);
-void c_take_callback_ref(rust::Fn<void(const rust::String &)> callback);
-void c_take_callback_mut(rust::Fn<void(rust::String &)> callback);
 void c_take_enum(Enum e);
 void c_take_ns_enum(::A::AEnum e);
 void c_take_nested_ns_enum(::A::B::ABEnum e);
diff --git a/tests/test.rs b/tests/test.rs
index 1f0b166..32b8e83 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -150,15 +150,15 @@
     check!(ffi::c_take_unique_ptr_string(
         ffi::c_return_unique_ptr_string()
     ));
-    let mut vector = ffi::c_return_unique_ptr_vector_u8();
-    assert_eq!(vector.pin_mut().pop(), Some(9));
-    check!(ffi::c_take_unique_ptr_vector_u8(vector));
-    let mut vector = ffi::c_return_unique_ptr_vector_f64();
-    vector.pin_mut().push(9.0);
-    check!(ffi::c_take_unique_ptr_vector_f64(vector));
-    let mut vector = ffi::c_return_unique_ptr_vector_shared();
-    vector.pin_mut().push(ffi::Shared { z: 9 });
-    check!(ffi::c_take_unique_ptr_vector_shared(vector));
+    check!(ffi::c_take_unique_ptr_vector_u8(
+        ffi::c_return_unique_ptr_vector_u8()
+    ));
+    check!(ffi::c_take_unique_ptr_vector_f64(
+        ffi::c_return_unique_ptr_vector_f64()
+    ));
+    check!(ffi::c_take_unique_ptr_vector_shared(
+        ffi::c_return_unique_ptr_vector_shared()
+    ));
     check!(ffi::c_take_ref_vector(&ffi::c_return_unique_ptr_vector_u8()));
     let test_vec = [86_u8, 75_u8, 30_u8, 9_u8].to_vec();
     check!(ffi::c_take_rust_vec(test_vec.clone()));
@@ -204,23 +204,7 @@
         0
     }
 
-    #[allow(clippy::ptr_arg)]
-    fn callback_ref(s: &String) {
-        if s == "2020" {
-            cxx_test_suite_set_correct();
-        }
-    }
-
-    fn callback_mut(s: &mut String) {
-        if s == "2020" {
-            cxx_test_suite_set_correct();
-        }
-    }
-
     check!(ffi::c_take_callback(callback));
-    check!(ffi::c_take_callback_ref(callback_ref));
-    check!(ffi::c_take_callback_ref_lifetime(callback_ref));
-    check!(ffi::c_take_callback_mut(callback_mut));
 }
 
 #[test]
diff --git a/tests/ui/array_len_suffix.stderr b/tests/ui/array_len_suffix.stderr
index 143bcb0..b72fc02 100644
--- a/tests/ui/array_len_suffix.stderr
+++ b/tests/ui/array_len_suffix.stderr
@@ -7,4 +7,4 @@
 help: change the type of the numeric literal from `u16` to `usize`
   |
 4 |         fn array() -> [String; 12usize];
-  |                                  ~~~~~
+  |                                ^^^^^^^
diff --git a/tests/ui/derive_nonclone.rs b/tests/ui/derive_nonclone.rs
new file mode 100644
index 0000000..5811028
--- /dev/null
+++ b/tests/ui/derive_nonclone.rs
@@ -0,0 +1,13 @@
+#[cxx::bridge]
+mod ffi {
+    #[derive(Clone)]
+    struct TryClone {
+        other: Other,
+    }
+
+    struct Other {
+        x: usize,
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/derive_nonclone.stderr b/tests/ui/derive_nonclone.stderr
new file mode 100644
index 0000000..04eae4f
--- /dev/null
+++ b/tests/ui/derive_nonclone.stderr
@@ -0,0 +1,7 @@
+error[E0277]: the trait bound `ffi::Other: Clone` is not satisfied
+ --> $DIR/derive_nonclone.rs:5:9
+  |
+5 |         other: Other,
+  |         ^^^^^^^^^^^^ the trait `Clone` is not implemented for `ffi::Other`
+  |
+  = note: required by `clone`
diff --git a/tests/ui/expected_named.stderr b/tests/ui/expected_named.stderr
index dab3b5a..4676401 100644
--- a/tests/ui/expected_named.stderr
+++ b/tests/ui/expected_named.stderr
@@ -8,4 +8,4 @@
 help: consider using the `'static` lifetime
   |
 5 |         fn borrowed() -> UniquePtr<Borrowed<'static>>;
-  |                                    ~~~~~~~~~~~~~~~~~
+  |                                    ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/opaque_autotraits.stderr b/tests/ui/opaque_autotraits.stderr
index 15a2b64..4f469ef 100644
--- a/tests/ui/opaque_autotraits.stderr
+++ b/tests/ui/opaque_autotraits.stderr
@@ -1,59 +1,40 @@
-error[E0277]: `*const cxx::void` cannot be sent between threads safely
+error[E0277]: `*const u8` cannot be sent between threads safely
   --> $DIR/opaque_autotraits.rs:13:5
    |
-13 |     assert_send::<ffi::Opaque>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely
-   |
-   = help: within `ffi::Opaque`, the trait `Send` is not implemented for `*const cxx::void`
-   = note: required because it appears within the type `[*const cxx::void; 0]`
-   = note: required because it appears within the type `cxx::private::Opaque`
-note: required because it appears within the type `ffi::Opaque`
-  --> $DIR/opaque_autotraits.rs:4:14
-   |
-4  |         type Opaque;
-   |              ^^^^^^
-note: required by a bound in `assert_send`
-  --> $DIR/opaque_autotraits.rs:8:19
-   |
 8  | fn assert_send<T: Send>() {}
-   |                   ^^^^ required by this bound in `assert_send`
+   |                   ---- required by this bound in `assert_send`
+...
+13 |     assert_send::<ffi::Opaque>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely
+   |
+   = help: within `ffi::Opaque`, the trait `Send` is not implemented for `*const u8`
+   = note: required because it appears within the type `[*const u8; 0]`
+   = note: required because it appears within the type `cxx::private::Opaque`
+   = note: required because it appears within the type `ffi::Opaque`
 
-error[E0277]: `*const cxx::void` cannot be shared between threads safely
+error[E0277]: `*const u8` cannot be shared between threads safely
   --> $DIR/opaque_autotraits.rs:14:5
    |
-14 |     assert_sync::<ffi::Opaque>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be shared between threads safely
-   |
-   = help: within `ffi::Opaque`, the trait `Sync` is not implemented for `*const cxx::void`
-   = note: required because it appears within the type `[*const cxx::void; 0]`
-   = note: required because it appears within the type `cxx::private::Opaque`
-note: required because it appears within the type `ffi::Opaque`
-  --> $DIR/opaque_autotraits.rs:4:14
-   |
-4  |         type Opaque;
-   |              ^^^^^^
-note: required by a bound in `assert_sync`
-  --> $DIR/opaque_autotraits.rs:9:19
-   |
 9  | fn assert_sync<T: Sync>() {}
-   |                   ^^^^ required by this bound in `assert_sync`
+   |                   ---- required by this bound in `assert_sync`
+...
+14 |     assert_sync::<ffi::Opaque>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const u8` cannot be shared between threads safely
+   |
+   = help: within `ffi::Opaque`, the trait `Sync` is not implemented for `*const u8`
+   = note: required because it appears within the type `[*const u8; 0]`
+   = note: required because it appears within the type `cxx::private::Opaque`
+   = note: required because it appears within the type `ffi::Opaque`
 
 error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/opaque_autotraits.rs:15:5
    |
+10 | fn assert_unpin<T: Unpin>() {}
+   |                    ----- required by this bound in `assert_unpin`
+...
 15 |     assert_unpin::<ffi::Opaque>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ffi::Opaque`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
-   = note: consider using `Box::pin`
    = note: required because it appears within the type `PhantomData<PhantomPinned>`
    = note: required because it appears within the type `cxx::private::Opaque`
-note: required because it appears within the type `ffi::Opaque`
-  --> $DIR/opaque_autotraits.rs:4:14
-   |
-4  |         type Opaque;
-   |              ^^^^^^
-note: required by a bound in `assert_unpin`
-  --> $DIR/opaque_autotraits.rs:10:20
-   |
-10 | fn assert_unpin<T: Unpin>() {}
-   |                    ^^^^^ required by this bound in `assert_unpin`
+   = note: required because it appears within the type `ffi::Opaque`
diff --git a/tests/ui/opaque_not_sized.stderr b/tests/ui/opaque_not_sized.stderr
index b50a269..9818e44 100644
--- a/tests/ui/opaque_not_sized.stderr
+++ b/tests/ui/opaque_not_sized.stderr
@@ -2,16 +2,10 @@
  --> $DIR/opaque_not_sized.rs:4:14
   |
 4 |         type TypeR;
-  |              ^^^^^ doesn't have a size known at compile-time
+  |         -----^^^^^-
+  |         |    |
+  |         |    doesn't have a size known at compile-time
+  |         required by this bound in `__AssertSized`
   |
   = help: within `TypeR`, the trait `Sized` is not implemented for `str`
-note: required because it appears within the type `TypeR`
- --> $DIR/opaque_not_sized.rs:8:8
-  |
-8 | struct TypeR(str);
-  |        ^^^^^
-note: required by a bound in `__AssertSized`
- --> $DIR/opaque_not_sized.rs:4:9
-  |
-4 |         type TypeR;
-  |         ^^^^^^^^^^^ required by this bound in `__AssertSized`
+  = note: required because it appears within the type `TypeR`
diff --git a/tests/ui/reserved_lifetime.rs b/tests/ui/reserved_lifetime.rs
deleted file mode 100644
index 179a4db..0000000
--- a/tests/ui/reserved_lifetime.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#[cxx::bridge]
-mod ffi {
-    unsafe extern "C++" {
-        type Logger;
-
-        fn logger<'static>() -> Pin<&'static Logger>;
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/reserved_lifetime.stderr b/tests/ui/reserved_lifetime.stderr
deleted file mode 100644
index 723572d..0000000
--- a/tests/ui/reserved_lifetime.stderr
+++ /dev/null
@@ -1,5 +0,0 @@
-error[E0262]: invalid lifetime parameter name: `'static`
- --> $DIR/reserved_lifetime.rs:6:19
-  |
-6 |         fn logger<'static>() -> Pin<&'static Logger>;
-  |                   ^^^^^^^ 'static is a reserved lifetime name
diff --git a/tests/ui/rust_pinned.stderr b/tests/ui/rust_pinned.stderr
index 8857681..f16f9d5 100644
--- a/tests/ui/rust_pinned.stderr
+++ b/tests/ui/rust_pinned.stderr
@@ -1,17 +1,10 @@
 error[E0277]: `PhantomPinned` cannot be unpinned
-  --> $DIR/rust_pinned.rs:6:14
-   |
-6  |         type Pinned;
-   |              ^^^^^^ within `Pinned`, the trait `Unpin` is not implemented for `PhantomPinned`
-   |
-   = note: consider using `Box::pin`
-note: required because it appears within the type `Pinned`
-  --> $DIR/rust_pinned.rs:10:12
-   |
-10 | pub struct Pinned {
-   |            ^^^^^^
-note: required by a bound in `__AssertUnpin`
-  --> $DIR/rust_pinned.rs:6:9
-   |
-6  |         type Pinned;
-   |         ^^^^^^^^^^^^ required by this bound in `__AssertUnpin`
+ --> $DIR/rust_pinned.rs:6:14
+  |
+6 |         type Pinned;
+  |         -----^^^^^^-
+  |         |    |
+  |         |    within `Pinned`, the trait `Unpin` is not implemented for `PhantomPinned`
+  |         required by this bound in `__AssertUnpin`
+  |
+  = note: required because it appears within the type `Pinned`
diff --git a/tests/ui/slice_of_type_alias.rs b/tests/ui/slice_of_type_alias.rs
deleted file mode 100644
index a7bbc11..0000000
--- a/tests/ui/slice_of_type_alias.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use cxx::{type_id, ExternType};
-
-#[repr(C)]
-struct ElementTrivial(usize);
-
-#[repr(C)]
-struct ElementOpaque(usize);
-
-#[cxx::bridge]
-mod ffi {
-    unsafe extern "C++" {
-        type ElementTrivial = crate::ElementTrivial;
-        type ElementOpaque = crate::ElementOpaque;
-
-        fn f(slice: &mut [ElementTrivial]);
-        fn g(slice: &[ElementOpaque]);
-    }
-}
-
-unsafe impl ExternType for ElementTrivial {
-    type Id = type_id!("ElementTrivial");
-    type Kind = cxx::kind::Trivial;
-}
-
-unsafe impl ExternType for ElementOpaque {
-    type Id = type_id!("ElementOpaque");
-    type Kind = cxx::kind::Opaque;
-}
-
-fn main() {}
diff --git a/tests/ui/slice_of_type_alias.stderr b/tests/ui/slice_of_type_alias.stderr
deleted file mode 100644
index aff06f8..0000000
--- a/tests/ui/slice_of_type_alias.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0271]: type mismatch resolving `<ElementOpaque as ExternType>::Kind == Trivial`
-   --> $DIR/slice_of_type_alias.rs:13:9
-    |
-13  |         type ElementOpaque = crate::ElementOpaque;
-    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Trivial`, found enum `cxx::kind::Opaque`
-    |
-note: required by a bound in `verify_extern_kind`
-   --> $DIR/extern_type.rs:186:41
-    |
-186 | pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
-    |                                         ^^^^^^^^^^^ required by this bound in `verify_extern_kind`
diff --git a/tests/ui/slice_unsupported.stderr b/tests/ui/slice_unsupported.stderr
index 2cbd26d..787076f 100644
--- a/tests/ui/slice_unsupported.stderr
+++ b/tests/ui/slice_unsupported.stderr
@@ -3,9 +3,3 @@
   |
 6 |         fn f(_: &mut [Opaque]);
   |                 ^^^^^^^^^^^^^
-
-error: needs a cxx::ExternType impl in order to be used as a slice element in &mut [Opaque]
- --> $DIR/slice_unsupported.rs:4:9
-  |
-4 |         type Opaque;
-  |         ^^^^^^^^^^^
diff --git a/tests/ui/unique_ptr_to_opaque.stderr b/tests/ui/unique_ptr_to_opaque.stderr
index 28e45cf..19d76a3 100644
--- a/tests/ui/unique_ptr_to_opaque.stderr
+++ b/tests/ui/unique_ptr_to_opaque.stderr
@@ -4,10 +4,4 @@
 22 |     cxx::UniquePtr::new(outside::C { a: 4 });
    |     ^^^^^^^^^^^^^^^^^^^ expected enum `Trivial`, found enum `cxx::kind::Opaque`
    |
-note: required by `UniquePtr::<T>::new`
-  --> $DIR/unique_ptr.rs:38:5
-   |
-38 | /     pub fn new(value: T) -> Self
-39 | |     where
-40 | |         T: ExternType<Kind = Trivial>,
-   | |______________________________________^
+   = note: required by `UniquePtr::<T>::new`
diff --git a/tests/ui/unsupported_elided.stderr b/tests/ui/unsupported_elided.stderr
index 8e8a986..932076d 100644
--- a/tests/ui/unsupported_elided.stderr
+++ b/tests/ui/unsupported_elided.stderr
@@ -3,8 +3,6 @@
   |
 6 |         type T;
   |              ^- help: indicate the anonymous lifetime: `<'_>`
-  |
-  = note: assuming a `'static` lifetime...
 
 error[E0106]: missing lifetime specifier
  --> $DIR/unsupported_elided.rs:8:24
@@ -16,4 +14,4 @@
 help: consider introducing a named lifetime parameter
   |
 8 |         fn f<'a>(t: &'a T) -> &'a str;
-  |             ++++     ++        ++
+  |             ^^^^    ^^^^^     ^^^
diff --git a/tests/ui/vec_opaque.stderr b/tests/ui/vec_opaque.stderr
index 3f208fe..b8dad91 100644
--- a/tests/ui/vec_opaque.stderr
+++ b/tests/ui/vec_opaque.stderr
@@ -16,8 +16,7 @@
 22  |         type Job = crate::handle::Job;
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Trivial`, found enum `cxx::kind::Opaque`
     |
-note: required by a bound in `verify_extern_kind`
-   --> $DIR/extern_type.rs:186:41
+   ::: $WORKSPACE/src/extern_type.rs
     |
-186 | pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
-    |                                         ^^^^^^^^^^^ required by this bound in `verify_extern_kind`
+    | pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
+    |                                         ----------- required by this bound in `verify_extern_kind`
diff --git a/tests/ui/vector_autotraits.rs b/tests/ui/vector_autotraits.rs
deleted file mode 100644
index cc918d5..0000000
--- a/tests/ui/vector_autotraits.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use cxx::CxxVector;
-
-#[cxx::bridge]
-mod ffi {
-    extern "C++" {
-        type ThreadSafe;
-        type NotThreadSafe;
-    }
-
-    impl CxxVector<ThreadSafe> {}
-    impl CxxVector<NotThreadSafe> {}
-}
-
-unsafe impl Send for ffi::ThreadSafe {}
-
-fn assert_send<T: Send>() {}
-
-fn main() {
-    assert_send::<CxxVector<ffi::ThreadSafe>>();
-    assert_send::<CxxVector<ffi::NotThreadSafe>>();
-}
diff --git a/tests/ui/vector_autotraits.stderr b/tests/ui/vector_autotraits.stderr
deleted file mode 100644
index 52fd2a4..0000000
--- a/tests/ui/vector_autotraits.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0277]: `*const cxx::void` cannot be sent between threads safely
-  --> $DIR/vector_autotraits.rs:20:5
-   |
-20 |     assert_send::<CxxVector<ffi::NotThreadSafe>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely
-   |
-   = help: within `CxxVector<NotThreadSafe>`, the trait `Send` is not implemented for `*const cxx::void`
-   = note: required because it appears within the type `[*const cxx::void; 0]`
-   = note: required because it appears within the type `cxx::private::Opaque`
-note: required because it appears within the type `NotThreadSafe`
-  --> $DIR/vector_autotraits.rs:7:14
-   |
-7  |         type NotThreadSafe;
-   |              ^^^^^^^^^^^^^
-   = note: required because it appears within the type `[NotThreadSafe]`
-   = note: required because it appears within the type `PhantomData<[NotThreadSafe]>`
-   = note: required because it appears within the type `CxxVector<NotThreadSafe>`
-note: required by a bound in `assert_send`
-  --> $DIR/vector_autotraits.rs:16:19
-   |
-16 | fn assert_send<T: Send>() {}
-   |                   ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/wrong_type_id.stderr b/tests/ui/wrong_type_id.stderr
index b66bb26..2d8e50a 100644
--- a/tests/ui/wrong_type_id.stderr
+++ b/tests/ui/wrong_type_id.stderr
@@ -4,10 +4,10 @@
 11  |         type ByteRange = crate::here::StringPiece;
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 15 elements, found one with 17 elements
     |
+   ::: $WORKSPACE/src/extern_type.rs
+    |
+    | pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
+    |                                         ------- required by this bound in `verify_extern_type`
+    |
     = note: expected tuple `(f, o, l, l, y, (), B, y, t, e, R, a, n, g, e)`
                found tuple `(f, o, l, l, y, (), S, t, r, i, n, g, P, i, e, c, e)`
-note: required by a bound in `verify_extern_type`
-   --> $DIR/extern_type.rs:183:41
-    |
-183 | pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
-    |                                         ^^^^^^^ required by this bound in `verify_extern_type`
diff --git a/third-party/BUCK b/third-party/BUCK
index 2633da8..84a5e18 100644
--- a/third-party/BUCK
+++ b/third-party/BUCK
@@ -1,15 +1,13 @@
 # To be generated by Facebook's `reindeer` tool once that is open source.
 
-load("//tools/buck:rust_library.bzl", "rust_library")
-
 rust_library(
     name = "bitflags",
-    srcs = glob(["vendor/bitflags-1.3.2/src/**"]),
+    srcs = glob(["vendor/bitflags-1.2.1/src/**"]),
 )
 
 rust_library(
     name = "cc",
-    srcs = glob(["vendor/cc-1.0.69/src/**"]),
+    srcs = glob(["vendor/cc-1.0.67/src/**"]),
     visibility = ["PUBLIC"],
 )
 
@@ -43,21 +41,25 @@
 
 rust_library(
     name = "proc-macro2",
-    srcs = glob(["vendor/proc-macro2-1.0.28/src/**"]),
-    build_script = "vendor/proc-macro2-1.0.28/build.rs",
+    srcs = glob(["vendor/proc-macro2-1.0.26/src/**"]),
+    visibility = ["PUBLIC"],
     features = [
         "proc-macro",
         "span-locations",
     ],
-    visibility = ["PUBLIC"],
+    rustc_flags = [
+        "--cfg=span_locations",
+        "--cfg=use_proc_macro",
+        "--cfg=wrap_proc_macro",
+    ],
     deps = [":unicode-xid"],
 )
 
 rust_library(
     name = "quote",
     srcs = glob(["vendor/quote-1.0.9/src/**"]),
-    features = ["proc-macro"],
     visibility = ["PUBLIC"],
+    features = ["proc-macro"],
     deps = [":proc-macro2"],
 )
 
@@ -70,8 +72,8 @@
 
 rust_library(
     name = "syn",
-    srcs = glob(["vendor/syn-1.0.75/src/**"]),
-    build_script = "vendor/syn-1.0.75/build.rs",
+    srcs = glob(["vendor/syn-1.0.68/src/**"]),
+    visibility = ["PUBLIC"],
     features = [
         "clone-impls",
         "derive",
@@ -80,7 +82,6 @@
         "printing",
         "proc-macro",
     ],
-    visibility = ["PUBLIC"],
     deps = [
         ":proc-macro2",
         ":quote",
@@ -106,5 +107,5 @@
 
 rust_library(
     name = "unicode-xid",
-    srcs = glob(["vendor/unicode-xid-0.2.2/src/**"]),
+    srcs = glob(["vendor/unicode-xid-0.2.1/src/**"]),
 )
diff --git a/third-party/BUILD b/third-party/BUILD
index 1760b70..cf1a288 100644
--- a/third-party/BUILD
+++ b/third-party/BUILD
@@ -1,18 +1,17 @@
 load(
-    "//tools/bazel:third_party.bzl",
-    cargo_build_script = "third_party_cargo_build_script",
+    "//tools/bazel:rust.bzl",
     glob = "third_party_glob",
     rust_library = "third_party_rust_library",
 )
 
 rust_library(
     name = "bitflags",
-    srcs = glob(["vendor/bitflags-1.3.2/src/**"]),
+    srcs = glob(["vendor/bitflags-1.2.1/src/**"]),
 )
 
 rust_library(
     name = "cc",
-    srcs = glob(["vendor/cc-1.0.69/src/**"]),
+    srcs = glob(["vendor/cc-1.0.67/src/**"]),
     visibility = ["//visibility:public"],
 )
 
@@ -46,26 +45,18 @@
 
 rust_library(
     name = "proc-macro2",
-    srcs = glob(["vendor/proc-macro2-1.0.28/src/**"]),
+    srcs = glob(["vendor/proc-macro2-1.0.26/src/**"]),
     crate_features = [
         "proc-macro",
         "span-locations",
     ],
+    rustc_flags = [
+        "--cfg=span_locations",
+        "--cfg=use_proc_macro",
+        "--cfg=wrap_proc_macro",
+    ],
     visibility = ["//visibility:public"],
-    deps = [
-        ":proc-macro2@build",
-        ":unicode-xid",
-    ],
-)
-
-cargo_build_script(
-    name = "proc-macro2@build",
-    srcs = ["vendor/proc-macro2-1.0.28/build.rs"],
-    crate_features = [
-        "proc-macro",
-        "span-locations",
-    ],
-    crate_name = "build",
+    deps = [":unicode-xid"],
 )
 
 rust_library(
@@ -85,7 +76,7 @@
 
 rust_library(
     name = "syn",
-    srcs = glob(["vendor/syn-1.0.75/src/**"]),
+    srcs = glob(["vendor/syn-1.0.68/src/**"]),
     crate_features = [
         "clone-impls",
         "derive",
@@ -98,25 +89,10 @@
     deps = [
         ":proc-macro2",
         ":quote",
-        ":syn@build",
         ":unicode-xid",
     ],
 )
 
-cargo_build_script(
-    name = "syn@build",
-    srcs = ["vendor/syn-1.0.75/build.rs"],
-    crate_features = [
-        "clone-impls",
-        "derive",
-        "full",
-        "parsing",
-        "printing",
-        "proc-macro",
-    ],
-    crate_name = "build",
-)
-
 rust_library(
     name = "termcolor",
     srcs = glob(["vendor/termcolor-1.1.2/src/**"]),
@@ -135,5 +111,5 @@
 
 rust_library(
     name = "unicode-xid",
-    srcs = glob(["vendor/unicode-xid-0.2.2/src/**"]),
+    srcs = glob(["vendor/unicode-xid-0.2.1/src/**"]),
 )
diff --git a/third-party/Cargo.lock b/third-party/Cargo.lock
index 0a3d543..a95e737 100644
--- a/third-party/Cargo.lock
+++ b/third-party/Cargo.lock
@@ -3,12 +3,6 @@
 version = 3
 
 [[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
 name = "ansi_term"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -29,42 +23,21 @@
 ]
 
 [[package]]
-name = "autocfg"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
-
-[[package]]
 name = "bitflags"
-version = "1.3.2"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
 [[package]]
 name = "cc"
-version = "1.0.69"
+version = "1.0.67"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
+checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
 dependencies = [
  "jobserver",
 ]
 
 [[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "clang-ast"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eed6681036a96f9855a75b08a9f14199e212017508a967d1d1e868f575f7d8e9"
-dependencies = [
- "serde",
-]
-
-[[package]]
 name = "clap"
 version = "2.33.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -90,17 +63,8 @@
 ]
 
 [[package]]
-name = "crc32fast"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
 name = "cxx"
-version = "1.0.54"
+version = "1.0.42"
 dependencies = [
  "cc",
  "cxx-build",
@@ -115,7 +79,7 @@
 
 [[package]]
 name = "cxx-build"
-version = "1.0.54"
+version = "1.0.42"
 dependencies = [
  "cc",
  "codespan-reporting",
@@ -130,7 +94,7 @@
 
 [[package]]
 name = "cxx-gen"
-version = "0.7.54"
+version = "0.7.42"
 dependencies = [
  "cc",
  "codespan-reporting",
@@ -150,7 +114,7 @@
 
 [[package]]
 name = "cxxbridge-cmd"
-version = "1.0.54"
+version = "1.0.42"
 dependencies = [
  "clap",
  "codespan-reporting",
@@ -161,20 +125,15 @@
 
 [[package]]
 name = "cxxbridge-flags"
-version = "1.0.54"
+version = "1.0.42"
 
 [[package]]
 name = "cxxbridge-macro"
-version = "1.0.54"
+version = "1.0.42"
 dependencies = [
- "clang-ast",
  "cxx",
- "flate2",
- "memmap",
  "proc-macro2",
  "quote",
- "serde",
- "serde_json",
  "syn",
 ]
 
@@ -193,18 +152,6 @@
 checksum = "fc4b29f4b9bb94bf267d57269fd0706d343a160937108e9619fe380645428abb"
 
 [[package]]
-name = "flate2"
-version = "1.0.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
-dependencies = [
- "cfg-if",
- "crc32fast",
- "libc",
- "miniz_oxide",
-]
-
-[[package]]
 name = "glob"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -212,24 +159,24 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.19"
+version = "0.1.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
 dependencies = [
  "libc",
 ]
 
 [[package]]
 name = "itoa"
-version = "0.4.8"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
 
 [[package]]
 name = "jobserver"
-version = "0.1.24"
+version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
+checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
 dependencies = [
  "libc",
 ]
@@ -242,9 +189,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.101"
+version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21"
+checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714"
 
 [[package]]
 name = "link-cplusplus"
@@ -256,26 +203,6 @@
 ]
 
 [[package]]
-name = "memmap"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
-dependencies = [
- "adler",
- "autocfg",
-]
-
-[[package]]
 name = "pkg-config"
 version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -283,9 +210,9 @@
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.28"
+version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
+checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
 dependencies = [
  "unicode-xid",
 ]
@@ -301,9 +228,9 @@
 
 [[package]]
 name = "rustversion"
-version = "1.0.5"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
+checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
 
 [[package]]
 name = "ryu"
@@ -319,18 +246,18 @@
 
 [[package]]
 name = "serde"
-version = "1.0.129"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1"
+checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.129"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3"
+checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -339,9 +266,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.66"
+version = "1.0.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
+checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
 dependencies = [
  "itoa",
  "ryu",
@@ -356,9 +283,9 @@
 
 [[package]]
 name = "syn"
-version = "1.0.75"
+version = "1.0.68"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
+checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -394,9 +321,9 @@
 
 [[package]]
 name = "trybuild"
-version = "1.0.45"
+version = "1.0.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bdaf2a1d317f3d58b44b31c7f6436b9b9acafe7bddfeace50897c2b804d7792"
+checksum = "99471a206425fba51842a9186315f32d91c56eadc21ea4c21f847b59cf778f8b"
 dependencies = [
  "dissimilar",
  "glob",
@@ -415,9 +342,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"
diff --git a/tools/bazel/rust.bzl b/tools/bazel/rust.bzl
new file mode 100644
index 0000000..9f71923
--- /dev/null
+++ b/tools/bazel/rust.bzl
@@ -0,0 +1,29 @@
+"""A module wrapping the core rules of `rules_rust`"""
+
+load(
+    "@rules_rust//rust:rust.bzl",
+    _rust_binary = "rust_binary",
+    _rust_library = "rust_library",
+    _rust_test = "rust_test",
+)
+load("@third-party//:vendor.bzl", "vendored")
+
+def third_party_glob(include):
+    return vendored and native.glob(include)
+
+def rust_binary(edition = "2018", **kwargs):
+    _rust_binary(edition = edition, **kwargs)
+
+def third_party_rust_binary(rustc_flags = [], **kwargs):
+    rustc_flags = rustc_flags + ["--cap-lints=allow"]
+    rust_binary(rustc_flags = rustc_flags, **kwargs)
+
+def rust_library(edition = "2018", **kwargs):
+    _rust_library(edition = edition, **kwargs)
+
+def third_party_rust_library(rustc_flags = [], **kwargs):
+    rustc_flags = rustc_flags + ["--cap-lints=allow"]
+    rust_library(rustc_flags = rustc_flags, **kwargs)
+
+def rust_test(edition = "2018", **kwargs):
+    _rust_test(edition = edition, **kwargs)
diff --git a/tools/bazel/third_party.bzl b/tools/bazel/third_party.bzl
deleted file mode 100644
index 7f51c46..0000000
--- a/tools/bazel/third_party.bzl
+++ /dev/null
@@ -1,18 +0,0 @@
-load("@rules_rust//cargo:cargo_build_script.bzl", "cargo_build_script")
-load("@rules_rust//rust:rust.bzl", "rust_binary", "rust_library")
-load("@third-party//:vendor.bzl", "vendored")
-
-def third_party_glob(include):
-    return vendored and native.glob(include)
-
-def third_party_cargo_build_script(rustc_flags = [], **kwargs):
-    rustc_flags = rustc_flags + ["--cap-lints=allow"]
-    cargo_build_script(rustc_flags = rustc_flags, **kwargs)
-
-def third_party_rust_binary(rustc_flags = [], **kwargs):
-    rustc_flags = rustc_flags + ["--cap-lints=allow"]
-    rust_binary(rustc_flags = rustc_flags, **kwargs)
-
-def third_party_rust_library(rustc_flags = [], **kwargs):
-    rustc_flags = rustc_flags + ["--cap-lints=allow"]
-    rust_library(rustc_flags = rustc_flags, **kwargs)
diff --git a/tools/bazel/vendor.bzl b/tools/bazel/vendor.bzl
index e51adb7..e404ad9 100644
--- a/tools/bazel/vendor.bzl
+++ b/tools/bazel/vendor.bzl
@@ -2,8 +2,6 @@
 of a crate in the current workspace.
 """
 
-load("@rules_rust//rust:repositories.bzl", "DEFAULT_RUST_VERSION", "load_arbitrary_tool")
-
 def _impl(repository_ctx):
     # Link cxx repository into @third-party.
     lockfile = repository_ctx.path(repository_ctx.attr.lockfile)
@@ -16,27 +14,8 @@
     root_lockfile = repository_ctx.path("workspace/Cargo.lock")
     _copy_file(repository_ctx, src = vendor_lockfile, dst = root_lockfile)
 
-    # Figure out which version of cargo to use.
-    if repository_ctx.attr.target_triple:
-        target_triple = repository_ctx.attr.target_triple
-    elif "mac" in repository_ctx.os.name:
-        target_triple = "x86_64-apple-darwin"
-    elif "windows" in repository_ctx.os.name:
-        target_triple = "x86_64-pc-windows-msvc"
-    else:
-        target_triple = "x86_64-unknown-linux-gnu"
-
-    # Download cargo.
-    load_arbitrary_tool(
-        ctx = repository_ctx,
-        tool_name = "cargo",
-        tool_subdirectories = ["cargo"],
-        version = repository_ctx.attr.cargo_version,
-        iso_date = repository_ctx.attr.cargo_iso_date,
-        target_triple = target_triple,
-    )
-
-    cmd = ["{}/bin/cargo".format(repository_ctx.path(".")), "vendor", "--versioned-dirs", "third-party/vendor"]
+    # Execute cargo vendor.
+    cmd = ["cargo", "vendor", "--versioned-dirs", "third-party/vendor"]
     result = repository_ctx.execute(
         cmd,
         quiet = True,
@@ -75,16 +54,6 @@
 vendor = repository_rule(
     doc = "A rule used to vendor the dependencies of a crate in the current workspace",
     attrs = {
-        "cargo_version": attr.string(
-            doc = "The version of cargo to use",
-            default = DEFAULT_RUST_VERSION,
-        ),
-        "cargo_iso_date": attr.string(
-            doc = "The date of the tool (or None, if the version is a specific version)",
-        ),
-        "target_triple": attr.string(
-            doc = "The target triple of the cargo binary to download",
-        ),
         "lockfile": attr.label(
             doc = "A lockfile providing the set of crates to vendor",
         ),
diff --git a/tools/buck/rust_library.bzl b/tools/buck/rust_library.bzl
deleted file mode 100644
index 67ec2ac..0000000
--- a/tools/buck/rust_library.bzl
+++ /dev/null
@@ -1,34 +0,0 @@
-load("//tools/buck:genrule.bzl", "genrule")
-
-def rust_library(
-        name,
-        srcs,
-        features = [],
-        rustc_flags = [],
-        build_script = None,
-        **kwargs):
-    if build_script:
-        rust_binary(
-            name = "%s@build" % name,
-            srcs = srcs + [build_script],
-            crate = "build",
-            crate_root = build_script,
-            features = features,
-            rustc_flags = rustc_flags,
-        )
-
-        genrule(
-            name = "%s@cfg" % name,
-            out = "output",
-            cmd = "env RUSTC=rustc TARGET= $(exe :%s@build) | sed -n s/^cargo:rustc-cfg=/--cfg=/p > ${OUT}" % name,
-        )
-
-        rustc_flags = rustc_flags + ["@$(location :%s@cfg)" % name]
-
-    native.rust_library(
-        name = name,
-        srcs = srcs,
-        features = features,
-        rustc_flags = rustc_flags,
-        **kwargs
-    )