Add Rust std::weak_ptr binding
diff --git a/syntax/check.rs b/syntax/check.rs
index ded5c53..39ea04e 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -32,6 +32,7 @@
             Type::RustVec(ty) => check_type_rust_vec(cx, ty),
             Type::UniquePtr(ptr) => check_type_unique_ptr(cx, ptr),
             Type::SharedPtr(ptr) => check_type_shared_ptr(cx, ptr),
+            Type::WeakPtr(ptr) => check_type_weak_ptr(cx, ptr),
             Type::CxxVector(ptr) => check_type_cxx_vector(cx, ptr),
             Type::Ref(ty) => check_type_ref(cx, ty),
             Type::Array(array) => check_type_array(cx, array),
@@ -152,6 +153,27 @@
     cx.error(ptr, "unsupported shared_ptr target type");
 }
 
+fn check_type_weak_ptr(cx: &mut Check, ptr: &Ty1) {
+    if let Type::Ident(ident) = &ptr.inner {
+        if cx.types.rust.contains(&ident.rust) {
+            cx.error(ptr, "weak_ptr of a Rust type is not supported yet");
+            return;
+        }
+
+        match Atom::from(&ident.rust) {
+            None | Some(Bool) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize)
+            | Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32)
+            | Some(F64) | Some(CxxString) => return,
+            Some(Char) | Some(RustString) => {}
+        }
+    } else if let Type::CxxVector(_) = &ptr.inner {
+        cx.error(ptr, "std::weak_ptr<std::vector> is not supported yet");
+        return;
+    }
+
+    cx.error(ptr, "unsupported weak_ptr target type");
+}
+
 fn check_type_cxx_vector(cx: &mut Check, ptr: &Ty1) {
     if let Type::Ident(ident) = &ptr.inner {
         if cx.types.rust.contains(&ident.rust) {
@@ -434,6 +456,7 @@
         | Type::RustVec(ty)
         | Type::UniquePtr(ty)
         | Type::SharedPtr(ty)
+        | Type::WeakPtr(ty)
         | Type::CxxVector(ty) => {
             if let Type::Ident(inner) = &ty.inner {
                 if Atom::from(&inner.rust).is_none() {
@@ -506,6 +529,7 @@
     if ident == "Box"
         || ident == "UniquePtr"
         || ident == "SharedPtr"
+        || ident == "WeakPtr"
         || ident == "Vec"
         || ident == "CxxVector"
         || ident == "str"
@@ -527,6 +551,7 @@
         | Type::RustVec(_)
         | Type::UniquePtr(_)
         | Type::SharedPtr(_)
+        | Type::WeakPtr(_)
         | Type::Ref(_)
         | Type::Str(_)
         | Type::SliceRef(_) => false,
@@ -599,6 +624,7 @@
         Type::RustVec(_) => "Vec".to_owned(),
         Type::UniquePtr(_) => "unique_ptr".to_owned(),
         Type::SharedPtr(_) => "shared_ptr".to_owned(),
+        Type::WeakPtr(_) => "weak_ptr".to_owned(),
         Type::Ref(_) => "reference".to_owned(),
         Type::Str(_) => "&str".to_owned(),
         Type::CxxVector(_) => "C++ vector".to_owned(),
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 9b154f6..d70e7cc 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -46,6 +46,7 @@
             Type::RustBox(t) => t.hash(state),
             Type::UniquePtr(t) => t.hash(state),
             Type::SharedPtr(t) => t.hash(state),
+            Type::WeakPtr(t) => t.hash(state),
             Type::Ref(t) => t.hash(state),
             Type::Str(t) => t.hash(state),
             Type::RustVec(t) => t.hash(state),
@@ -67,6 +68,7 @@
             (Type::RustBox(lhs), Type::RustBox(rhs)) => lhs == rhs,
             (Type::UniquePtr(lhs), Type::UniquePtr(rhs)) => lhs == rhs,
             (Type::SharedPtr(lhs), Type::SharedPtr(rhs)) => lhs == rhs,
+            (Type::WeakPtr(lhs), Type::WeakPtr(rhs)) => lhs == rhs,
             (Type::Ref(lhs), Type::Ref(rhs)) => lhs == rhs,
             (Type::Str(lhs), Type::Str(rhs)) => lhs == rhs,
             (Type::RustVec(lhs), Type::RustVec(rhs)) => lhs == rhs,
diff --git a/syntax/improper.rs b/syntax/improper.rs
index c0f6983..d672e7d 100644
--- a/syntax/improper.rs
+++ b/syntax/improper.rs
@@ -28,7 +28,9 @@
             | Type::Fn(_)
             | Type::Void(_)
             | Type::SliceRef(_) => Definite(true),
-            Type::UniquePtr(_) | Type::SharedPtr(_) | Type::CxxVector(_) => Definite(false),
+            Type::UniquePtr(_) | Type::SharedPtr(_) | Type::WeakPtr(_) | Type::CxxVector(_) => {
+                Definite(false)
+            }
             Type::Ref(ty) => self.determine_improper_ctype(&ty.inner),
             Type::Array(ty) => self.determine_improper_ctype(&ty.inner),
         }
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 7f8fd9a..111cec3 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -170,6 +170,7 @@
     RustVec(Box<Ty1>),
     UniquePtr(Box<Ty1>),
     SharedPtr(Box<Ty1>),
+    WeakPtr(Box<Ty1>),
     Ref(Box<Ref>),
     Str(Box<Ref>),
     CxxVector(Box<Ty1>),
diff --git a/syntax/parse.rs b/syntax/parse.rs
index f72253a..1ae4c2d 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -901,6 +901,16 @@
                             rangle: generic.gt_token,
                         })));
                     }
+                } else if ident == "WeakPtr" && generic.args.len() == 1 {
+                    if let GenericArgument::Type(arg) = &generic.args[0] {
+                        let inner = parse_type(arg)?;
+                        return Ok(Type::WeakPtr(Box::new(Ty1 {
+                            name: ident,
+                            langle: generic.lt_token,
+                            inner,
+                            rangle: generic.gt_token,
+                        })));
+                    }
                 } else if ident == "CxxVector" && generic.args.len() == 1 {
                     if let GenericArgument::Type(arg) = &generic.args[0] {
                         let inner = parse_type(arg)?;
diff --git a/syntax/pod.rs b/syntax/pod.rs
index d808a99..e1c4831 100644
--- a/syntax/pod.rs
+++ b/syntax/pod.rs
@@ -26,6 +26,7 @@
             | Type::RustVec(_)
             | Type::UniquePtr(_)
             | Type::SharedPtr(_)
+            | Type::WeakPtr(_)
             | Type::CxxVector(_)
             | Type::Void(_) => false,
             Type::Ref(_) | Type::Str(_) | Type::Fn(_) | Type::SliceRef(_) => true,
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index ae2d1d9..8348704 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -23,6 +23,7 @@
             Type::RustBox(ty)
             | Type::UniquePtr(ty)
             | Type::SharedPtr(ty)
+            | Type::WeakPtr(ty)
             | Type::CxxVector(ty)
             | Type::RustVec(ty) => ty.to_tokens(tokens),
             Type::Ref(r) | Type::Str(r) => r.to_tokens(tokens),
@@ -46,7 +47,7 @@
     fn to_tokens(&self, tokens: &mut TokenStream) {
         let span = self.name.span();
         let name = self.name.to_string();
-        if let "UniquePtr" | "SharedPtr" | "CxxVector" = name.as_str() {
+        if let "UniquePtr" | "SharedPtr" | "WeakPtr" | "CxxVector" = name.as_str() {
             tokens.extend(quote_spanned!(span=> ::cxx::));
         } else if name == "Vec" {
             tokens.extend(quote_spanned!(span=> ::std::vec::));
diff --git a/syntax/types.rs b/syntax/types.rs
index 1056854..f7682bc 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -45,6 +45,7 @@
                 Type::RustBox(ty)
                 | Type::UniquePtr(ty)
                 | Type::SharedPtr(ty)
+                | Type::WeakPtr(ty)
                 | Type::CxxVector(ty)
                 | Type::RustVec(ty) => visit(all, &ty.inner),
                 Type::Ref(r) => visit(all, &r.inner),