Parse pinned UniquePtr
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index eaa7928..3c9054c 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -9,6 +9,7 @@
 };
 use proc_macro2::{Ident, Span, TokenStream};
 use quote::{format_ident, quote, quote_spanned, ToTokens};
+use std::collections::BTreeSet as Set;
 use std::mem;
 use syn::{parse_quote, Result, Token};
 
@@ -59,6 +60,7 @@
         }
     }
 
+    let mut expanded_unique_ptr = Set::new();
     for ty in types {
         let explicit_impl = types.explicit_impls.get(ty);
         if let Type::RustBox(ty) = ty {
@@ -77,6 +79,7 @@
             if let Type::Ident(ident) = &ptr.inner {
                 if Atom::from(&ident.rust).is_none()
                     && (explicit_impl.is_some() || !types.aliases.contains_key(&ident.rust))
+                    && expanded_unique_ptr.insert(&ident.rust)
                 {
                     expanded.extend(expand_unique_ptr(ident, types, explicit_impl));
                 }
diff --git a/syntax/impls.rs b/syntax/impls.rs
index c345822..58d8fd3 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -81,29 +81,36 @@
 impl PartialEq for Ty1 {
     fn eq(&self, other: &Ty1) -> bool {
         let Ty1 {
+            pinned,
             name,
             langle: _,
             inner,
             rangle: _,
+            pin_tokens: _,
         } = self;
         let Ty1 {
+            pinned: pinned2,
             name: name2,
             langle: _,
             inner: inner2,
             rangle: _,
+            pin_tokens: _,
         } = other;
-        name == name2 && inner == inner2
+        pinned == pinned2 && name == name2 && inner == inner2
     }
 }
 
 impl Hash for Ty1 {
     fn hash<H: Hasher>(&self, state: &mut H) {
         let Ty1 {
+            pinned,
             name,
             langle: _,
             inner,
             rangle: _,
+            pin_tokens: _,
         } = self;
+        pinned.hash(state);
         name.hash(state);
         inner.hash(state);
     }
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 51068c9..853db90 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -165,10 +165,12 @@
 }
 
 pub struct Ty1 {
+    pub pinned: bool,
     pub name: Ident,
     pub langle: Token![<],
     pub inner: Type,
     pub rangle: Token![>],
+    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,
 }
 
 pub struct Ref {
diff --git a/syntax/parse.rs b/syntax/parse.rs
index bbddaa7..6010492 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -651,51 +651,64 @@
                     if let GenericArgument::Type(arg) = &generic.args[0] {
                         let inner = parse_type(arg, namespace)?;
                         return Ok(Type::UniquePtr(Box::new(Ty1 {
+                            pinned: false,
                             name: ident,
                             langle: generic.lt_token,
                             inner,
                             rangle: generic.gt_token,
+                            pin_tokens: None,
                         })));
                     }
                 } else if ident == "CxxVector" && generic.args.len() == 1 {
                     if let GenericArgument::Type(arg) = &generic.args[0] {
                         let inner = parse_type(arg, namespace)?;
                         return Ok(Type::CxxVector(Box::new(Ty1 {
+                            pinned: false,
                             name: ident,
                             langle: generic.lt_token,
                             inner,
                             rangle: generic.gt_token,
+                            pin_tokens: None,
                         })));
                     }
                 } else if ident == "Box" && generic.args.len() == 1 {
                     if let GenericArgument::Type(arg) = &generic.args[0] {
                         let inner = parse_type(arg, namespace)?;
                         return Ok(Type::RustBox(Box::new(Ty1 {
+                            pinned: false,
                             name: ident,
                             langle: generic.lt_token,
                             inner,
                             rangle: generic.gt_token,
+                            pin_tokens: None,
                         })));
                     }
                 } else if ident == "Vec" && generic.args.len() == 1 {
                     if let GenericArgument::Type(arg) = &generic.args[0] {
                         let inner = parse_type(arg, namespace)?;
                         return Ok(Type::RustVec(Box::new(Ty1 {
+                            pinned: false,
                             name: ident,
                             langle: generic.lt_token,
                             inner,
                             rangle: generic.gt_token,
+                            pin_tokens: None,
                         })));
                     }
                 } else if ident == "Pin" && generic.args.len() == 1 {
                     if let GenericArgument::Type(arg) = &generic.args[0] {
                         let inner = parse_type(arg, namespace)?;
+                        let pin_token = kw::Pin(ident.span());
                         if let Type::Ref(mut inner) = inner {
-                            let pin_token = kw::Pin(ident.span());
                             inner.pinned = true;
                             inner.pin_tokens =
                                 Some((pin_token, generic.lt_token, generic.gt_token));
                             return Ok(Type::Ref(inner));
+                        } else if let Type::UniquePtr(mut inner) = inner {
+                            inner.pinned = true;
+                            inner.pin_tokens =
+                                Some((pin_token, generic.lt_token, generic.gt_token));
+                            return Ok(Type::UniquePtr(inner));
                         }
                     }
                 }