Move primitive Vec C++ shims into cxx crate
diff --git a/gen/write.rs b/gen/write.rs
index c21cda1..94de4fb 100644
--- a/gen/write.rs
+++ b/gen/write.rs
@@ -934,9 +934,11 @@
                 write_rust_box_extern(out, inner);
             }
         } else if let Type::RustVec(ty) = ty {
-            if let Type::Ident(_) = &ty.inner {
-                out.next_section();
-                write_rust_vec_extern(out, &ty.inner);
+            if let Type::Ident(inner) = &ty.inner {
+                if Atom::from(inner).is_none() {
+                    out.next_section();
+                    write_rust_vec_extern(out, inner);
+                }
             }
         } else if let Type::UniquePtr(ptr) = ty {
             if let Type::Ident(inner) = &ptr.inner {
@@ -964,8 +966,10 @@
                 write_rust_box_impl(out, inner);
             }
         } else if let Type::RustVec(ty) = ty {
-            if let Type::Ident(_) = &ty.inner {
-                write_rust_vec_impl(out, &ty.inner);
+            if let Type::Ident(inner) = &ty.inner {
+                if Atom::from(inner).is_none() {
+                    write_rust_vec_impl(out, inner);
+                }
             }
         }
     }
@@ -997,9 +1001,10 @@
     writeln!(out, "#endif // CXXBRIDGE02_RUST_BOX_{}", instance);
 }
 
-fn write_rust_vec_extern(out: &mut OutFile, ty: &Type) {
-    let inner = to_typename(&out.namespace, ty);
-    let instance = to_mangled(&out.namespace, ty);
+fn write_rust_vec_extern(out: &mut OutFile, element: &Ident) {
+    let element = Type::Ident(element.clone());
+    let inner = to_typename(&out.namespace, &element);
+    let instance = to_mangled(&out.namespace, &element);
 
     writeln!(out, "#ifndef CXXBRIDGE02_RUST_VEC_{}", instance);
     writeln!(out, "#define CXXBRIDGE02_RUST_VEC_{}", instance);
@@ -1046,9 +1051,10 @@
     writeln!(out, "}}");
 }
 
-fn write_rust_vec_impl(out: &mut OutFile, ty: &Type) {
-    let inner = to_typename(&out.namespace, ty);
-    let instance = to_mangled(&out.namespace, ty);
+fn write_rust_vec_impl(out: &mut OutFile, element: &Ident) {
+    let element = Type::Ident(element.clone());
+    let inner = to_typename(&out.namespace, &element);
+    let instance = to_mangled(&out.namespace, &element);
 
     writeln!(out, "template <>");
     writeln!(out, "void Vec<{}>::drop() noexcept {{", inner);
diff --git a/src/cxx.cc b/src/cxx.cc
index 4351eda..63b2166 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -236,17 +236,54 @@
     ptr->~unique_ptr();                                                        \
   }
 
+#define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE)                                  \
+  void cxxbridge02$rust_vec$##RUST_TYPE##$drop(                                \
+      rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
+  size_t cxxbridge02$rust_vec$##RUST_TYPE##$len(                               \
+      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
+  const CXX_TYPE *cxxbridge02$rust_vec$##RUST_TYPE##$data(                     \
+      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
+  size_t cxxbridge02$rust_vec$##RUST_TYPE##$stride() noexcept;
+
+#define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE)                                      \
+  template <>                                                                  \
+  void rust::Vec<CXX_TYPE>::drop() noexcept {                                  \
+    return cxxbridge02$rust_vec$##RUST_TYPE##$drop(this);                      \
+  }                                                                            \
+  template <>                                                                  \
+  size_t rust::Vec<CXX_TYPE>::size() const noexcept {                          \
+    return cxxbridge02$rust_vec$##RUST_TYPE##$len(this);                       \
+  }                                                                            \
+  template <>                                                                  \
+  const CXX_TYPE *rust::Vec<CXX_TYPE>::data() const noexcept {                 \
+    return cxxbridge02$rust_vec$##RUST_TYPE##$data(this);                      \
+  }                                                                            \
+  template <>                                                                  \
+  size_t rust::Vec<CXX_TYPE>::stride() noexcept {                              \
+    return cxxbridge02$rust_vec$##RUST_TYPE##$stride();                        \
+  }
+
+// Usize and isize are the same type as one of the below.
+#define FOR_EACH_SIZED_PRIMITIVE(MACRO)                                        \
+  MACRO(u8, uint8_t)                                                           \
+  MACRO(u16, uint16_t)                                                         \
+  MACRO(u32, uint32_t)                                                         \
+  MACRO(u64, uint64_t)                                                         \
+  MACRO(i8, int8_t)                                                            \
+  MACRO(i16, int16_t)                                                          \
+  MACRO(i32, int32_t)                                                          \
+  MACRO(i64, int64_t)                                                          \
+  MACRO(f32, float)                                                            \
+  MACRO(f64, double)
+
+#define FOR_EACH_PRIMITIVE(MACRO)                                              \
+  FOR_EACH_SIZED_PRIMITIVE(MACRO)                                              \
+  MACRO(usize, size_t)                                                         \
+  MACRO(isize, rust::isize)
+
 extern "C" {
-STD_VECTOR_OPS(u8, uint8_t)
-STD_VECTOR_OPS(u16, uint16_t)
-STD_VECTOR_OPS(u32, uint32_t)
-STD_VECTOR_OPS(u64, uint64_t)
-STD_VECTOR_OPS(usize, size_t)
-STD_VECTOR_OPS(i8, int8_t)
-STD_VECTOR_OPS(i16, int16_t)
-STD_VECTOR_OPS(i32, int32_t)
-STD_VECTOR_OPS(i64, int64_t)
-STD_VECTOR_OPS(isize, rust::isize)
-STD_VECTOR_OPS(f32, float)
-STD_VECTOR_OPS(f64, double)
+FOR_EACH_PRIMITIVE(STD_VECTOR_OPS)
+FOR_EACH_SIZED_PRIMITIVE(RUST_VEC_EXTERNS)
 } // extern "C"
+
+FOR_EACH_SIZED_PRIMITIVE(RUST_VEC_OPS)