Key impls by an enum rather than by Type
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 6b89178..8242b2e 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1336,11 +1336,15 @@
     out.set_namespace(Default::default());
     out.begin_block(Block::ExternC);
     for ty in out.types {
+        let impl_key = match ty.impl_key() {
+            Some(impl_key) => impl_key,
+            None => continue,
+        };
         if let Type::RustBox(ptr) = ty {
             if let Type::Ident(inner) = &ptr.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     out.next_section();
                     write_rust_box_extern(out, &out.types.resolve(&inner));
@@ -1350,7 +1354,7 @@
             if let Type::Ident(inner) = &vec.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     out.next_section();
                     write_rust_vec_extern(out, inner);
@@ -1360,7 +1364,7 @@
             if let Type::Ident(inner) = &ptr.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     out.next_section();
                     write_unique_ptr(out, inner);
@@ -1370,7 +1374,7 @@
             if let Type::Ident(inner) = &ptr.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     out.next_section();
                     write_shared_ptr(out, inner);
@@ -1380,7 +1384,7 @@
             if let Type::Ident(inner) = &ptr.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     out.next_section();
                     write_weak_ptr(out, inner);
@@ -1390,7 +1394,7 @@
             if let Type::Ident(inner) = &vector.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     out.next_section();
                     write_cxx_vector(out, inner);
@@ -1403,11 +1407,15 @@
     out.begin_block(Block::Namespace("rust"));
     out.begin_block(Block::InlineNamespace("cxxbridge1"));
     for ty in out.types {
+        let impl_key = match ty.impl_key() {
+            Some(impl_key) => impl_key,
+            None => continue,
+        };
         if let Type::RustBox(ptr) = ty {
             if let Type::Ident(inner) = &ptr.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     write_rust_box_impl(out, &out.types.resolve(&inner));
                 }
@@ -1416,7 +1424,7 @@
             if let Type::Ident(inner) = &vec.inner {
                 if Atom::from(&inner.rust).is_none()
                     && (!out.types.aliases.contains_key(&inner.rust)
-                        || out.types.explicit_impls.contains(ty))
+                        || out.types.explicit_impls.contains_key(&impl_key))
                 {
                     write_rust_vec_impl(out, inner);
                 }
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 82cfed3..85f834d 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -80,7 +80,11 @@
     }
 
     for ty in types {
-        let explicit_impl = types.explicit_impls.get(ty);
+        let impl_key = match ty.impl_key() {
+            Some(impl_key) => impl_key,
+            None => continue,
+        };
+        let explicit_impl = types.explicit_impls.get(&impl_key).copied();
         if let Type::RustBox(ty) = ty {
             if let Type::Ident(ident) = &ty.inner {
                 if Atom::from(&ident.rust).is_none()
@@ -1366,7 +1370,6 @@
 }
 
 fn expand_cxx_vector(elem: &RustName, explicit_impl: Option<&Impl>, types: &Types) -> TokenStream {
-    let _ = explicit_impl;
     let name = elem.rust.to_string();
     let prefix = format!("cxxbridge1$std$vector${}$", elem.to_symbol(types));
     let link_size = format!("{}size", prefix);
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 8c16f2d..4fa0335 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -1,7 +1,6 @@
 use crate::syntax::{
     Array, ExternFn, Impl, Include, Lifetimes, Receiver, Ref, Signature, SliceRef, Ty1, Type, Var,
 };
-use std::borrow::Borrow;
 use std::hash::{Hash, Hasher};
 use std::mem;
 use std::ops::{Deref, DerefMut};
@@ -447,9 +446,3 @@
         negative == negative2 && ty == ty2
     }
 }
-
-impl Borrow<Type> for &Impl {
-    fn borrow(&self) -> &Type {
-        &self.ty
-    }
-}
diff --git a/syntax/instantiate.rs b/syntax/instantiate.rs
new file mode 100644
index 0000000..2891485
--- /dev/null
+++ b/syntax/instantiate.rs
@@ -0,0 +1,43 @@
+use crate::syntax::Type;
+use proc_macro2::Ident;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub enum ImplKey<'a> {
+    RustBox(&'a Ident),
+    RustVec(&'a Ident),
+    UniquePtr(&'a Ident),
+    SharedPtr(&'a Ident),
+    WeakPtr(&'a Ident),
+    CxxVector(&'a Ident),
+}
+
+impl Type {
+    pub(crate) fn impl_key(&self) -> Option<ImplKey> {
+        if let Type::RustBox(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::RustBox(&ident.rust));
+            }
+        } else if let Type::RustVec(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::RustVec(&ident.rust));
+            }
+        } else if let Type::UniquePtr(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::UniquePtr(&ident.rust));
+            }
+        } else if let Type::SharedPtr(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::SharedPtr(&ident.rust));
+            }
+        } else if let Type::WeakPtr(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::WeakPtr(&ident.rust));
+            }
+        } else if let Type::CxxVector(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::CxxVector(&ident.rust));
+            }
+        }
+        None
+    }
+}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 6fe45d3..9a21087 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -11,6 +11,7 @@
 pub mod ident;
 mod impls;
 mod improper;
+pub mod instantiate;
 pub mod mangle;
 mod names;
 pub mod namespace;
diff --git a/syntax/types.rs b/syntax/types.rs
index 58a3086..4c1fef0 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -1,4 +1,5 @@
 use crate::syntax::improper::ImproperCtype;
+use crate::syntax::instantiate::ImplKey;
 use crate::syntax::report::Errors;
 use crate::syntax::set::{OrderedSet as Set, UnorderedSet};
 use crate::syntax::trivial::{self, TrivialReason};
@@ -18,7 +19,7 @@
     pub aliases: Map<&'a Ident, &'a TypeAlias>,
     pub untrusted: Map<&'a Ident, &'a ExternType>,
     pub required_trivial: Map<&'a Ident, Vec<TrivialReason<'a>>>,
-    pub explicit_impls: Set<&'a Impl>,
+    pub explicit_impls: Map<ImplKey<'a>, &'a Impl>,
     pub resolutions: Map<&'a Ident, &'a Pair>,
     pub struct_improper_ctypes: UnorderedSet<&'a Ident>,
     pub toposorted_structs: Vec<&'a Struct>,
@@ -33,7 +34,7 @@
         let mut rust = Set::new();
         let mut aliases = Map::new();
         let mut untrusted = Map::new();
-        let mut explicit_impls = Set::new();
+        let mut explicit_impls = Map::new();
         let mut resolutions = Map::new();
         let struct_improper_ctypes = UnorderedSet::new();
         let toposorted_structs = Vec::new();
@@ -160,7 +161,9 @@
                 }
                 Api::Impl(imp) => {
                     visit(&mut all, &imp.ty);
-                    explicit_impls.insert(imp);
+                    if let Some(key) = imp.ty.impl_key() {
+                        explicit_impls.insert(key, imp);
+                    }
                 }
             }
         }