Parse lifetimes on Ident type names
diff --git a/syntax/check.rs b/syntax/check.rs
index fcd5f9a..42e92f4 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -2,7 +2,7 @@
 use crate::syntax::report::Errors;
 use crate::syntax::{
     error, ident, trivial, Api, Array, Enum, ExternFn, ExternType, Impl, Lang, Receiver, Ref,
-    Signature, SliceRef, Struct, Trait, Ty1, Type, TypeAlias, Types,
+    RustName, Signature, SliceRef, Struct, Trait, Ty1, Type, TypeAlias, Types,
 };
 use proc_macro2::{Delimiter, Group, Ident, TokenStream};
 use quote::{quote, ToTokens};
@@ -27,7 +27,7 @@
 
     for ty in cx.types {
         match ty {
-            Type::Ident(ident) => check_type_ident(cx, &ident.rust),
+            Type::Ident(ident) => check_type_ident(cx, ident),
             Type::RustBox(ptr) => check_type_box(cx, ptr),
             Type::RustVec(ty) => check_type_rust_vec(cx, ty),
             Type::UniquePtr(ptr) => check_type_unique_ptr(cx, ptr),
@@ -61,7 +61,8 @@
     }
 }
 
-fn check_type_ident(cx: &mut Check, ident: &Ident) {
+fn check_type_ident(cx: &mut Check, name: &RustName) {
+    let ident = &name.rust;
     if Atom::from(ident).is_none()
         && !cx.types.structs.contains_key(ident)
         && !cx.types.enums.contains_key(ident)
@@ -70,6 +71,11 @@
     {
         let msg = format!("unsupported type: {}", ident);
         cx.error(ident, &msg);
+        return;
+    }
+
+    if !name.generics.lifetimes.is_empty() {
+        cx.error(name, "type with lifetime parameter is not supported yet");
     }
 }
 
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 93dfba0..405006c 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -1056,6 +1056,31 @@
                             return Ok(Type::Ref(inner));
                         }
                     }
+                } else {
+                    let mut lifetimes = Punctuated::new();
+                    let mut only_lifetimes = true;
+                    for pair in generic.args.pairs() {
+                        let (param, punct) = pair.into_tuple();
+                        if let GenericArgument::Lifetime(param) = param {
+                            lifetimes.push_value(param.clone());
+                            if let Some(punct) = punct {
+                                lifetimes.push_punct(*punct);
+                            }
+                        } else {
+                            only_lifetimes = false;
+                            break;
+                        }
+                    }
+                    if only_lifetimes {
+                        return Ok(Type::Ident(RustName {
+                            rust: ident,
+                            generics: Lifetimes {
+                                lt_token: Some(generic.lt_token),
+                                lifetimes,
+                                gt_token: Some(generic.gt_token),
+                            },
+                        }));
+                    }
                 }
             }
             PathArguments::Parenthesized(_) => {}
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index 71f77b1..19e361f 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -256,8 +256,9 @@
 
 impl ToTokens for RustName {
     fn to_tokens(&self, tokens: &mut TokenStream) {
-        let RustName { rust, generics: _ } = self;
+        let RustName { rust, generics } = self;
         rust.to_tokens(tokens);
+        generics.to_tokens(tokens);
     }
 }