Parse generic params on impl block
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 4fa0335..fd8162f 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -413,11 +413,13 @@
     fn hash<H: Hasher>(&self, state: &mut H) {
         let Impl {
             impl_token: _,
+            generics,
             negative,
             ty,
             brace_token: _,
             negative_token: _,
         } = self;
+        generics.hash(state);
         if *negative {
             negative.hash(state);
         }
@@ -431,6 +433,7 @@
     fn eq(&self, other: &Impl) -> bool {
         let Impl {
             impl_token: _,
+            generics,
             negative,
             ty,
             brace_token: _,
@@ -438,11 +441,12 @@
         } = self;
         let Impl {
             impl_token: _,
+            generics: generics2,
             negative: negative2,
             ty: ty2,
             brace_token: _,
             negative_token: _,
         } = other;
-        negative == negative2 && ty == ty2
+        generics == generics2 && negative == negative2 && ty == ty2
     }
 }
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 9a21087..1dcb55c 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -136,6 +136,7 @@
 
 pub struct Impl {
     pub impl_token: Token![impl],
+    pub generics: Lifetimes,
     pub negative: bool,
     pub ty: Type,
     pub brace_token: Brace,
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 405006c..07fbf4a 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -827,6 +827,8 @@
 }
 
 fn parse_impl(imp: ItemImpl) -> Result<Api> {
+    let impl_token = imp.impl_token;
+
     if !imp.items.is_empty() {
         let mut span = Group::new(Delimiter::Brace, TokenStream::new());
         span.set_span(imp.brace_token.span);
@@ -842,13 +844,35 @@
         ));
     }
 
-    let generics = &imp.generics;
-    if !generics.params.is_empty() || generics.where_clause.is_some() {
+    if let Some(where_clause) = imp.generics.where_clause {
         return Err(Error::new_spanned(
-            imp,
-            "generic parameters on an impl is not supported",
+            where_clause,
+            "where-clause on an impl is not supported yet",
         ));
     }
+    let mut generics = Lifetimes {
+        lt_token: imp.generics.lt_token,
+        lifetimes: Punctuated::new(),
+        gt_token: imp.generics.gt_token,
+    };
+    for pair in imp.generics.params.into_pairs() {
+        let (param, punct) = pair.into_tuple();
+        match param {
+            GenericParam::Lifetime(def) if def.bounds.is_empty() => {
+                generics.lifetimes.push_value(def.lifetime);
+                if let Some(punct) = punct {
+                    generics.lifetimes.push_punct(punct);
+                }
+            }
+            _ => {
+                let span = quote!(#impl_token #generics);
+                return Err(Error::new_spanned(
+                    span,
+                    "generic parameter on an impl is not supported yet",
+                ));
+            }
+        }
+    }
 
     let mut negative_token = None;
     let mut self_ty = *imp.self_ty;
@@ -865,13 +889,13 @@
         }
     }
 
-    let impl_token = imp.impl_token;
     let negative = negative_token.is_some();
     let ty = parse_type(&self_ty)?;
     let brace_token = imp.brace_token;
 
     Ok(Api::Impl(Impl {
         impl_token,
+        generics,
         negative,
         ty,
         brace_token,
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index 1c7c5bc..dd5be01 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -192,12 +192,14 @@
     fn to_tokens(&self, tokens: &mut TokenStream) {
         let Impl {
             impl_token,
+            generics,
             negative: _,
             ty,
             brace_token,
             negative_token,
         } = self;
         impl_token.to_tokens(tokens);
+        generics.to_tokens(tokens);
         negative_token.to_tokens(tokens);
         ty.to_tokens(tokens);
         brace_token.surround(tokens, |_tokens| {});