C++ std::vector<T> and Rust std::vec::Vec<T> support

Add basic std::vector and std::vec::Vec support across FFI boundary.
diff --git a/syntax/atom.rs b/syntax/atom.rs
index eeea831..c68b3fe 100644
--- a/syntax/atom.rs
+++ b/syntax/atom.rs
@@ -42,6 +42,43 @@
             _ => None,
         }
     }
+
+    pub fn to_cxx(&self) -> &'static str {
+        use self::Atom::*;
+        match self {
+            Bool => "bool",
+            U8 => "uint8_t",
+            U16 => "uint16_t",
+            U32 => "uint32_t",
+            U64 => "uint64_t",
+            Usize => "size_t",
+            I8 => "int8_t",
+            I16 => "int16_t",
+            I32 => "int32_t",
+            I64 => "int64_t",
+            Isize => "::rust::isize",
+            F32 => "float",
+            F64 => "double",
+            CxxString => "::std::string",
+            RustString => "::rust::String",
+        }
+    }
+
+    pub fn is_valid_vector_target(&self) -> bool {
+        use self::Atom::*;
+        *self == U8
+            || *self == U16
+            || *self == U32
+            || *self == U64
+            || *self == Usize
+            || *self == I8
+            || *self == I16
+            || *self == I32
+            || *self == I64
+            || *self == Isize
+            || *self == F32
+            || *self == F64
+    }
 }
 
 impl PartialEq<Atom> for Ident {
diff --git a/syntax/check.rs b/syntax/check.rs
index 5e8cc09..387f9a6 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -29,7 +29,9 @@
         match ty {
             Type::Ident(ident) => check_type_ident(cx, ident),
             Type::RustBox(ptr) => check_type_box(cx, ptr),
+            Type::RustVec(ptr) => check_type_vec(cx, ptr),
             Type::UniquePtr(ptr) => check_type_unique_ptr(cx, ptr),
+            Type::Vector(ptr) => check_type_vector(cx, ptr),
             Type::Ref(ty) => check_type_ref(cx, ty),
             Type::Slice(ty) => check_type_slice(cx, ty),
             _ => {}
@@ -87,6 +89,21 @@
     cx.error(ptr, "unsupported target type of Box");
 }
 
+fn check_type_vec(cx: &mut Check, ptr: &Ty1) {
+    // Vec can contain either user-defined type or u8
+    if let Type::Ident(ident) = &ptr.inner {
+        if Atom::from(ident).map(|a| a.is_valid_vector_target()) == Some(true) {
+            return;
+        } else if cx.types.cxx.contains(ident) {
+            cx.error(ptr, error::VEC_CXX_TYPE.msg);
+        } else {
+            return;
+        }
+    }
+
+    cx.error(ptr, "unsupported target type of Vec");
+}
+
 fn check_type_unique_ptr(cx: &mut Check, ptr: &Ty1) {
     if let Type::Ident(ident) = &ptr.inner {
         if cx.types.rust.contains(ident) {
@@ -97,11 +114,31 @@
             None | Some(CxxString) => return,
             _ => {}
         }
+    } else if let Type::Vector(_) = &ptr.inner {
+        return;
     }
 
     cx.error(ptr, "unsupported unique_ptr target type");
 }
 
+fn check_type_vector(cx: &mut Check, ptr: &Ty1) {
+    if let Type::Ident(ident) = &ptr.inner {
+        if cx.types.rust.contains(ident) {
+            cx.error(ptr, "vector of a Rust type is not supported yet");
+        }
+
+        match Atom::from(ident) {
+            None => return,
+            Some(atom) => {
+                if atom.is_valid_vector_target() {
+                    return;
+                }
+            }
+        }
+    }
+    cx.error(ptr, "unsupported vector target type");
+}
+
 fn check_type_ref(cx: &mut Check, ty: &Ref) {
     if ty.lifetime.is_some() {
         cx.error(ty, "references with explicit lifetimes are not supported");
@@ -310,9 +347,11 @@
             }
         }
         Type::RustBox(_) => "Box".to_owned(),
+        Type::RustVec(_) => "Vec".to_owned(),
         Type::UniquePtr(_) => "unique_ptr".to_owned(),
         Type::Ref(_) => "reference".to_owned(),
         Type::Str(_) => "&str".to_owned(),
+        Type::Vector(_) => "vector".to_owned(),
         Type::Slice(_) => "slice".to_owned(),
         Type::SliceRefU8(_) => "&[u8]".to_owned(),
         Type::Fn(_) => "function pointer".to_owned(),
diff --git a/syntax/error.rs b/syntax/error.rs
index f52d651..103a54f 100644
--- a/syntax/error.rs
+++ b/syntax/error.rs
@@ -15,6 +15,7 @@
 
 pub static ERRORS: &[Error] = &[
     BOX_CXX_TYPE,
+    VEC_CXX_TYPE,
     CXXBRIDGE_RESERVED,
     CXX_STRING_BY_VALUE,
     CXX_TYPE_BY_VALUE,
@@ -29,6 +30,12 @@
     note: Some("hint: use UniquePtr<>"),
 };
 
+pub static VEC_CXX_TYPE: Error = Error {
+    msg: "Vec of a C++ type is not supported yet",
+    label: None,
+    note: Some("hint: use UniquePtr<>"),
+};
+
 pub static CXXBRIDGE_RESERVED: Error = Error {
     msg: "identifiers starting with cxxbridge are reserved",
     label: Some("reserved identifier"),
diff --git a/syntax/impls.rs b/syntax/impls.rs
index a2ce05b..8e94f06 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -26,6 +26,8 @@
             Type::UniquePtr(t) => t.hash(state),
             Type::Ref(t) => t.hash(state),
             Type::Str(t) => t.hash(state),
+            Type::RustVec(t) => t.hash(state),
+            Type::Vector(t) => t.hash(state),
             Type::Fn(t) => t.hash(state),
             Type::Slice(t) => t.hash(state),
             Type::SliceRefU8(t) => t.hash(state),
@@ -44,6 +46,8 @@
             (Type::UniquePtr(lhs), Type::UniquePtr(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,
+            (Type::Vector(lhs), Type::Vector(rhs)) => lhs == rhs,
             (Type::Fn(lhs), Type::Fn(rhs)) => lhs == rhs,
             (Type::Slice(lhs), Type::Slice(rhs)) => lhs == rhs,
             (Type::SliceRefU8(lhs), Type::SliceRefU8(rhs)) => lhs == rhs,
diff --git a/syntax/mangled.rs b/syntax/mangled.rs
new file mode 100644
index 0000000..56e8b73
--- /dev/null
+++ b/syntax/mangled.rs
@@ -0,0 +1,30 @@
+use crate::syntax::{Atom, Type};
+
+pub trait ToMangled {
+    fn to_mangled(&self, namespace: &Vec<String>) -> String;
+}
+
+impl ToMangled for Type {
+    fn to_mangled(&self, namespace: &Vec<String>) -> String {
+        match self {
+            Type::Ident(ident) => {
+                let mut instance = String::new();
+                // Do not apply namespace to built-in type
+                let is_user_type = Atom::from(ident).is_none();
+                if is_user_type {
+                    for name in namespace {
+                        instance += name;
+                        instance += "$";
+                    }
+                }
+                instance += &ident.to_string();
+                instance
+            }
+            Type::RustBox(ptr) => format!("rust_box${}", ptr.inner.to_mangled(namespace)),
+            Type::RustVec(ptr) => format!("rust_vec${}", ptr.inner.to_mangled(namespace)),
+            Type::UniquePtr(ptr) => format!("std$unique_ptr${}", ptr.inner.to_mangled(namespace)),
+            Type::Vector(ptr) => format!("std$vector${}", ptr.inner.to_mangled(namespace)),
+            _ => unimplemented!(),
+        }
+    }
+}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index ab5cecc..4e0b908 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -8,11 +8,13 @@
 pub mod ident;
 mod impls;
 pub mod mangle;
+pub mod mangled;
 pub mod namespace;
 mod parse;
 pub mod set;
 pub mod symbol;
 mod tokens;
+pub mod typename;
 pub mod types;
 
 use self::parse::kw;
@@ -86,9 +88,11 @@
 pub enum Type {
     Ident(Ident),
     RustBox(Box<Ty1>),
+    RustVec(Box<Ty1>),
     UniquePtr(Box<Ty1>),
     Ref(Box<Ref>),
     Str(Box<Ref>),
+    Vector(Box<Ty1>),
     Fn(Box<Signature>),
     Void(Span),
     Slice(Box<Slice>),
diff --git a/syntax/namespace.rs b/syntax/namespace.rs
index d26bb9e..a4e972b 100644
--- a/syntax/namespace.rs
+++ b/syntax/namespace.rs
@@ -11,7 +11,7 @@
 
 #[derive(Clone)]
 pub struct Namespace {
-    segments: Vec<String>,
+    pub segments: Vec<String>,
 }
 
 impl Namespace {
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 7d92b1b..f5c598d 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -300,6 +300,16 @@
                             rangle: generic.gt_token,
                         })));
                     }
+                } else if ident == "Vector" && generic.args.len() == 1 {
+                    if let GenericArgument::Type(arg) = &generic.args[0] {
+                        let inner = parse_type(arg)?;
+                        return Ok(Type::Vector(Box::new(Ty1 {
+                            name: ident,
+                            langle: generic.lt_token,
+                            inner,
+                            rangle: generic.gt_token,
+                        })));
+                    }
                 } else if ident == "Box" && generic.args.len() == 1 {
                     if let GenericArgument::Type(arg) = &generic.args[0] {
                         let inner = parse_type(arg)?;
@@ -310,6 +320,16 @@
                             rangle: generic.gt_token,
                         })));
                     }
+                } else if ident == "Vec" && generic.args.len() == 1 {
+                    if let GenericArgument::Type(arg) = &generic.args[0] {
+                        let inner = parse_type(arg)?;
+                        return Ok(Type::RustVec(Box::new(Ty1 {
+                            name: ident,
+                            langle: generic.lt_token,
+                            inner,
+                            rangle: generic.gt_token,
+                        })));
+                    }
                 }
             }
             PathArguments::Parenthesized(_) => {}
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index 26bb3d1..3d67a0a 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -14,7 +14,9 @@
                 }
                 ident.to_tokens(tokens);
             }
-            Type::RustBox(ty) | Type::UniquePtr(ty) => ty.to_tokens(tokens),
+            Type::RustBox(ty) | Type::UniquePtr(ty) | Type::Vector(ty) | Type::RustVec(ty) => {
+                ty.to_tokens(tokens)
+            }
             Type::Ref(r) | Type::Str(r) | Type::SliceRefU8(r) => r.to_tokens(tokens),
             Type::Slice(s) => s.to_tokens(tokens),
             Type::Fn(f) => f.to_tokens(tokens),
@@ -33,7 +35,8 @@
 
 impl ToTokens for Ty1 {
     fn to_tokens(&self, tokens: &mut TokenStream) {
-        if self.name == "UniquePtr" {
+        // Do not add cxx namespace to Vector since we're defining it in the user crate
+        if self.name == "UniquePtr" || self.name == "RustVec" {
             let span = self.name.span();
             tokens.extend(quote_spanned!(span=> ::cxx::));
         }
diff --git a/syntax/typename.rs b/syntax/typename.rs
new file mode 100644
index 0000000..883e1fb
--- /dev/null
+++ b/syntax/typename.rs
@@ -0,0 +1,36 @@
+use crate::syntax::{Atom, Type};
+
+pub trait ToTypename {
+    fn to_typename(&self, namespace: &Vec<String>) -> String;
+}
+
+impl ToTypename for Type {
+    fn to_typename(&self, namespace: &Vec<String>) -> String {
+        match self {
+            Type::Ident(ident) => {
+                let mut inner = String::new();
+                // Do not apply namespace to built-in type
+                let is_user_type = Atom::from(ident).is_none();
+                if is_user_type {
+                    for name in namespace {
+                        inner += name;
+                        inner += "::";
+                    }
+                }
+                if let Some(ti) = Atom::from(ident) {
+                    inner += ti.to_cxx();
+                } else {
+                    inner += &ident.to_string();
+                };
+                inner
+            }
+            Type::RustBox(ptr) => format!("rust_box<{}>", ptr.inner.to_typename(namespace)),
+            Type::RustVec(ptr) => format!("rust_vec<{}>", ptr.inner.to_typename(namespace)),
+            Type::UniquePtr(ptr) => {
+                format!("std::unique_ptr<{}>", ptr.inner.to_typename(namespace))
+            }
+            Type::Vector(ptr) => format!("std::vector<{}>", ptr.inner.to_typename(namespace)),
+            _ => unimplemented!(),
+        }
+    }
+}
diff --git a/syntax/types.rs b/syntax/types.rs
index 6f3af09..7bce154 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -24,7 +24,9 @@
             all.insert(ty);
             match ty {
                 Type::Ident(_) | Type::Str(_) | Type::Void(_) | Type::SliceRefU8(_) => {}
-                Type::RustBox(ty) | Type::UniquePtr(ty) => visit(all, &ty.inner),
+                Type::RustBox(ty) | Type::UniquePtr(ty) | Type::Vector(ty) | Type::RustVec(ty) => {
+                    visit(all, &ty.inner)
+                }
                 Type::Ref(r) => visit(all, &r.inner),
                 Type::Slice(s) => visit(all, &s.inner),
                 Type::Fn(f) => {