Distinguish Impl's impl generics vs generics on the Self type
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 73952e1..30faccc 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -141,13 +141,15 @@
 
 pub struct Impl {
     pub impl_token: Token![impl],
-    pub generics: Lifetimes,
+    pub impl_generics: Lifetimes,
     pub negative: bool,
     pub ty: Type,
+    pub ty_generics: Lifetimes,
     pub brace_token: Brace,
     pub negative_token: Option<Token![!]>,
 }
 
+#[derive(Clone, Default)]
 pub struct Lifetimes {
     pub lt_token: Option<Token![<]>,
     pub lifetimes: Punctuated<Lifetime, Token![,]>,
diff --git a/syntax/parse.rs b/syntax/parse.rs
index db46dc4..8bd8907 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -868,7 +868,7 @@
             "where-clause on an impl is not supported yet",
         ));
     }
-    let mut generics = Lifetimes {
+    let mut impl_generics = Lifetimes {
         lt_token: imp.generics.lt_token,
         lifetimes: Punctuated::new(),
         gt_token: imp.generics.gt_token,
@@ -877,13 +877,13 @@
         let (param, punct) = pair.into_tuple();
         match param {
             GenericParam::Lifetime(def) if def.bounds.is_empty() => {
-                generics.lifetimes.push_value(def.lifetime);
+                impl_generics.lifetimes.push_value(def.lifetime);
                 if let Some(punct) = punct {
-                    generics.lifetimes.push_punct(punct);
+                    impl_generics.lifetimes.push_punct(punct);
                 }
             }
             _ => {
-                let span = quote!(#impl_token #generics);
+                let span = quote!(#impl_token #impl_generics);
                 return Err(Error::new_spanned(
                     span,
                     "generic parameter on an impl is not supported yet",
@@ -907,15 +907,35 @@
         }
     }
 
-    let negative = negative_token.is_some();
     let ty = parse_type(&self_ty)?;
+    let ty_generics = match &ty {
+        Type::RustBox(ty)
+        | Type::RustVec(ty)
+        | Type::UniquePtr(ty)
+        | Type::SharedPtr(ty)
+        | Type::WeakPtr(ty)
+        | Type::CxxVector(ty) => match &ty.inner {
+            Type::Ident(ident) => ident.generics.clone(),
+            _ => Lifetimes::default(),
+        },
+        Type::Ident(_)
+        | Type::Ref(_)
+        | Type::Str(_)
+        | Type::Fn(_)
+        | Type::Void(_)
+        | Type::SliceRef(_)
+        | Type::Array(_) => Lifetimes::default(),
+    };
+
+    let negative = negative_token.is_some();
     let brace_token = imp.brace_token;
 
     Ok(Api::Impl(Impl {
         impl_token,
-        generics,
+        impl_generics,
         negative,
         ty,
+        ty_generics,
         brace_token,
         negative_token,
     }))
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index aec21ae..757673d 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -192,14 +192,15 @@
     fn to_tokens(&self, tokens: &mut TokenStream) {
         let Impl {
             impl_token,
-            generics,
+            impl_generics,
             negative: _,
             ty,
+            ty_generics: _,
             brace_token,
             negative_token,
         } = self;
         impl_token.to_tokens(tokens);
-        generics.to_tokens(tokens);
+        impl_generics.to_tokens(tokens);
         negative_token.to_tokens(tokens);
         ty.to_tokens(tokens);
         brace_token.surround(tokens, |_tokens| {});