Round trip testing
diff --git a/Cargo.toml b/Cargo.toml
index 72e29ff..c24d48d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,3 +20,8 @@
 clippy = { version = "0.*", optional = true }
 quote = { version = "0.2", optional = true }
 unicode-xid = { version = "0.0.3", optional = true }
+
+[dev-dependencies]
+syntex_pos = "0.44.0"
+syntex_syntax = "0.44.0"
+walkdir = "0.1.8"
diff --git a/src/attr.rs b/src/attr.rs
index 8a16982..068e0ee 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -1,12 +1,24 @@
 use super::*;
 
+use std::iter;
+
 /// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Attribute {
+    pub style: AttrStyle,
     pub value: MetaItem,
     pub is_sugared_doc: bool,
 }
 
+/// Distinguishes between Attributes that decorate items and Attributes that
+/// are contained as statements within items. These two cases need to be
+/// distinguished for pretty-printing.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum AttrStyle {
+    Outer,
+    Inner,
+}
+
 /// A compile-time attribute item.
 ///
 /// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
@@ -36,6 +48,31 @@
     }
 }
 
+pub trait FilterAttrs<'a> {
+    type Ret: Iterator<Item = &'a Attribute>;
+
+    fn outer(self) -> Self::Ret;
+    fn inner(self) -> Self::Ret;
+}
+
+impl<'a, T> FilterAttrs<'a> for T where T: IntoIterator<Item = &'a Attribute> {
+    type Ret = iter::Filter<T::IntoIter, fn(&&Attribute) -> bool>;
+
+    fn outer(self) -> Self::Ret {
+        fn is_outer(attr: &&Attribute) -> bool {
+            attr.style == AttrStyle::Outer
+        }
+        self.into_iter().filter(is_outer)
+    }
+
+    fn inner(self) -> Self::Ret {
+        fn is_inner(attr: &&Attribute) -> bool {
+            attr.style == AttrStyle::Inner
+        }
+        self.into_iter().filter(is_inner)
+    }
+}
+
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
@@ -43,13 +80,27 @@
     use lit::{Lit, StrStyle};
     use lit::parsing::lit;
 
-    named!(pub attribute -> Attribute, alt!(
+    named!(pub inner_attr -> Attribute, do_parse!(
+        punct!("#") >>
+        punct!("!") >>
+        punct!("[") >>
+        meta_item: meta_item >>
+        punct!("]") >>
+        (Attribute {
+            style: AttrStyle::Inner,
+            value: meta_item,
+            is_sugared_doc: false,
+        })
+    ));
+
+    named!(pub outer_attr -> Attribute, alt!(
         do_parse!(
             punct!("#") >>
             punct!("[") >>
             meta_item: meta_item >>
             punct!("]") >>
             (Attribute {
+                style: AttrStyle::Outer,
                 value: meta_item,
                 is_sugared_doc: false,
             })
@@ -60,6 +111,7 @@
             not!(peek!(tag!("/"))) >>
             content: take_until!("\n") >>
             (Attribute {
+                style: AttrStyle::Outer,
                 value: MetaItem::NameValue(
                     "doc".into(),
                     Lit::Str(
@@ -102,6 +154,7 @@
         fn to_tokens(&self, tokens: &mut Tokens) {
             match *self {
                 Attribute {
+                    style: AttrStyle::Outer,
                     value: MetaItem::NameValue(
                         ref name,
                         Lit::Str(ref value, StrStyle::Cooked),
@@ -112,6 +165,9 @@
                 }
                 _ => {
                     tokens.append("#");
+                    if let AttrStyle::Inner = self.style {
+                        tokens.append("!");
+                    }
                     tokens.append("[");
                     self.value.to_tokens(tokens);
                     tokens.append("]");
diff --git a/src/data.rs b/src/data.rs
index 30edc8b..7082363 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -49,7 +49,7 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use attr::parsing::attribute;
+    use attr::parsing::outer_attr;
     use ident::parsing::ident;
     use lit::parsing::int;
     use ty::parsing::ty;
@@ -71,7 +71,7 @@
     ));
 
     named!(variant -> Variant, do_parse!(
-        attrs: many0!(attribute) >>
+        attrs: many0!(outer_attr) >>
         id: ident >>
         data: alt!(
             struct_like_body => { VariantData::Struct }
@@ -106,7 +106,7 @@
     ));
 
     named!(struct_field -> Field, do_parse!(
-        attrs: many0!(attribute) >>
+        attrs: many0!(outer_attr) >>
         vis: visibility >>
         id: ident >>
         punct!(":") >>
@@ -120,7 +120,7 @@
     ));
 
     named!(tuple_field -> Field, do_parse!(
-        attrs: many0!(attribute) >>
+        attrs: many0!(outer_attr) >>
         vis: visibility >>
         ty: ty >>
         (Field {
diff --git a/src/item.rs b/src/item.rs
index d8488c8..86c7df9 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -209,7 +209,7 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use attr::parsing::attribute;
+    use attr::parsing::outer_attr;
     use data::parsing::visibility;
     use ident::parsing::ident;
     use macro_input::{Body, MacroInput};
@@ -234,7 +234,7 @@
     ));
 
     named!(item_extern_crate -> Item, do_parse!(
-        attrs: many0!(attribute) >>
+        attrs: many0!(outer_attr) >>
         vis: visibility >>
         keyword!("extern") >>
         keyword!("crate") >>
@@ -275,3 +275,73 @@
         }
     ));
 }
+
+#[cfg(feature = "printing")]
+mod printing {
+    use super::*;
+    use attr::FilterAttrs;
+    use data::{VariantData, Visibility};
+    use quote::{Tokens, ToTokens};
+
+    impl ToTokens for Item {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            for attr in self.attrs.outer() {
+                attr.to_tokens(tokens);
+            }
+            match self.node {
+                ItemKind::ExternCrate(ref original) => {
+                    tokens.append("extern");
+                    tokens.append("crate");
+                    if let Some(ref original) = *original {
+                        original.to_tokens(tokens);
+                        tokens.append("as");
+                    }
+                    self.ident.to_tokens(tokens);
+                    tokens.append(";");
+                }
+                ItemKind::Use(ref _view_path) => unimplemented!(),
+                ItemKind::Static(ref _ty, ref _mutability, ref _expr) => unimplemented!(),
+                ItemKind::Const(ref _ty, ref _expr) => unimplemented!(),
+                ItemKind::Fn(ref _decl, _unsafety, _constness, ref _abi, ref _generics, ref _block) => unimplemented!(),
+                ItemKind::Mod(ref _items) => unimplemented!(),
+                ItemKind::ForeignMod(ref _foreign_mod) => unimplemented!(),
+                ItemKind::Ty(ref _ty, ref _generics) => unimplemented!(),
+                ItemKind::Enum(ref variants, ref generics) => {
+                    if let Visibility::Public = self.vis {
+                        tokens.append("pub");
+                    }
+                    tokens.append("enum");
+                    self.ident.to_tokens(tokens);
+                    generics.to_tokens(tokens);
+                    generics.where_clause.to_tokens(tokens);
+                    tokens.append("{");
+                    for variant in variants {
+                        variant.to_tokens(tokens);
+                        tokens.append(",");
+                    }
+                    tokens.append("}");
+                }
+                ItemKind::Struct(ref variant_data, ref generics) => {
+                    if let Visibility::Public = self.vis {
+                        tokens.append("pub");
+                    }
+                    tokens.append("struct");
+                    self.ident.to_tokens(tokens);
+                    generics.to_tokens(tokens);
+                    generics.where_clause.to_tokens(tokens);
+                    variant_data.to_tokens(tokens);
+                    match *variant_data {
+                        VariantData::Struct(_) => { /* no semicolon */ }
+                        VariantData::Tuple(_) |
+                        VariantData::Unit => tokens.append(";"),
+                    }
+                }
+                ItemKind::Union(ref _variant_data, ref _generics) => unimplemented!(),
+                ItemKind::Trait(_unsafety, ref _generics, ref _bound, ref _item) => unimplemented!(),
+                ItemKind::DefaultImpl(_unsafety, ref _path) => unimplemented!(),
+                ItemKind::Impl(_unsafety, _polarity, ref _generics, ref _path, ref _ty, ref _item) => unimplemented!(),
+                ItemKind::Mac(ref _mac) => unimplemented!(),
+            }
+        }
+    }
+}
diff --git a/src/krate.rs b/src/krate.rs
new file mode 100644
index 0000000..c5b2126
--- /dev/null
+++ b/src/krate.rs
@@ -0,0 +1,43 @@
+use super::*;
+
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct Crate {
+    attrs: Vec<Attribute>,
+    items: Vec<Item>,
+}
+
+#[cfg(feature = "parsing")]
+pub mod parsing {
+    use super::*;
+    use attr::parsing::inner_attr;
+    use item::parsing::item;
+    use nom::multispace;
+
+    named!(pub krate -> Crate, do_parse!(
+        attrs: many0!(inner_attr) >>
+        items: many0!(item) >>
+        option!(multispace) >>
+        (Crate {
+            attrs: attrs,
+            items: items,
+        })
+    ));
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+    use super::*;
+    use attr::FilterAttrs;
+    use quote::{Tokens, ToTokens};
+
+    impl ToTokens for Crate {
+        fn to_tokens(&self, tokens: &mut Tokens) {
+            for attr in self.attrs.inner() {
+                attr.to_tokens(tokens);
+            }
+            for item in &self.items {
+                item.to_tokens(tokens);
+            }
+        }
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
index df62d75..50a754c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,6 +19,7 @@
 mod attr;
 pub use attr::{
     Attribute,
+    AttrStyle,
     MetaItem,
 };
 
@@ -65,6 +66,11 @@
     WhereRegionPredicate,
 };
 
+#[cfg(feature = "full")]
+mod krate;
+#[cfg(feature = "full")]
+pub use krate::Crate;
+
 mod ident;
 pub use ident::{
     Ident,
@@ -155,13 +161,18 @@
     use nom;
 
     #[cfg(feature = "full")]
-    use {expr, item};
+    use {expr, item, krate};
 
     pub fn parse_macro_input(input: &str) -> Result<MacroInput, String> {
         unwrap("macro input", macro_input::parsing::macro_input, input)
     }
 
     #[cfg(feature = "full")]
+    pub fn parse_crate(input: &str) -> Result<Crate, String> {
+        unwrap("crate", krate::parsing::krate, input)
+    }
+
+    #[cfg(feature = "full")]
     pub fn parse_item(input: &str) -> Result<Item, String> {
         unwrap("item", item::parsing::item, input)
     }
diff --git a/src/macro_input.rs b/src/macro_input.rs
index 848e609..c2b5900 100644
--- a/src/macro_input.rs
+++ b/src/macro_input.rs
@@ -18,14 +18,14 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use attr::parsing::attribute;
+    use attr::parsing::outer_attr;
     use data::parsing::{visibility, struct_body, enum_body};
     use generics::parsing::generics;
     use ident::parsing::ident;
     use nom::multispace;
 
     named!(pub macro_input -> MacroInput, do_parse!(
-        attrs: many0!(attribute) >>
+        attrs: many0!(outer_attr) >>
         vis: visibility >>
         which: alt!(keyword!("struct") | keyword!("enum")) >>
         id: ident >>
@@ -55,12 +55,13 @@
 #[cfg(feature = "printing")]
 mod printing {
     use super::*;
+    use attr::FilterAttrs;
     use data::{Visibility, VariantData};
     use quote::{Tokens, ToTokens};
 
     impl ToTokens for MacroInput {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            for attr in &self.attrs {
+            for attr in self.attrs.outer() {
                 attr.to_tokens(tokens);
             }
             if let Visibility::Public = self.vis {
diff --git a/tests/cases/structs_enums.rs b/tests/cases/structs_enums.rs
new file mode 100644
index 0000000..0236741
--- /dev/null
+++ b/tests/cases/structs_enums.rs
@@ -0,0 +1,529 @@
+#![feature(rustc_macro)]
+
+#[macro_use]
+extern crate serde_derive;
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct DefaultStruct<A, B, C, D, E> where C: MyDefault, E: MyDefault {
+    a1: A,
+    #[serde(default)]
+    a2: B,
+    #[serde(default = "MyDefault::my_default")]
+    a3: C,
+    #[serde(skip_deserializing)]
+    a4: D,
+    #[serde(skip_deserializing, default = "MyDefault::my_default")]
+    a5: E,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+enum DefaultEnum<A, B, C, D, E> where C: MyDefault, E: MyDefault {
+    Struct {
+        a1: A,
+        #[serde(default)]
+        a2: B,
+        #[serde(default = "MyDefault::my_default")]
+        a3: C,
+        #[serde(skip_deserializing)]
+        a4: D,
+        #[serde(skip_deserializing, default = "MyDefault::my_default")]
+        a5: E,
+    },
+}
+
+#[derive(Deserialize)]
+struct NoStdDefault(i8);
+
+#[derive(Deserialize)]
+struct ContainsNoStdDefault<A: MyDefault> {
+    #[serde(default = "MyDefault::my_default")]
+    a: A,
+}
+
+#[derive(Deserialize)]
+struct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> {
+    #[serde(skip_deserializing)]
+    a: A,
+    #[serde(skip_deserializing, default)]
+    b: B,
+    #[serde(deserialize_with = "DeserializeWith::deserialize_with", default)]
+    c: C,
+    #[serde(skip_deserializing, default = "MyDefault::my_default")]
+    e: E,
+}
+
+#[derive(Serialize)]
+#[serde(deny_unknown_fields)]
+#[derive(Deserialize)]
+struct DenyUnknown {
+    a1: i32,
+}
+
+#[derive(Serialize)]
+#[serde(rename = "Superhero")]
+#[derive(Deserialize)]
+struct RenameStruct {
+    a1: i32,
+    #[serde(rename = "a3")]
+    a2: i32,
+}
+
+#[derive(Serialize)]
+#[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
+#[derive(Deserialize)]
+struct RenameStructSerializeDeserialize {
+    a1: i32,
+    #[serde(rename(serialize = "a4", deserialize = "a5"))]
+    a2: i32,
+}
+
+#[derive(Serialize)]
+#[serde(rename = "Superhero")]
+#[derive(Deserialize)]
+enum RenameEnum {
+
+    #[serde(rename = "bruce_wayne")]
+    Batman ,
+
+    #[serde(rename = "clark_kent")]
+    Superman ( i8 ) ,
+
+    #[serde(rename = "diana_prince")]
+    WonderWoman ( i8 , i8 ) ,
+
+    #[serde(rename = "barry_allan")]
+    Flash {
+        #[serde(rename = "b")]
+        a : i32,
+    } ,
+}
+
+#[derive(Deserialize)]
+#[serde ( rename ( serialize = "SuperheroSer" , deserialize = "SuperheroDe" ) ) ]
+#[derive(Serialize)]
+enum RenameEnumSerializeDeserialize<A> {
+
+    #[serde(rename(serialize = "dick_grayson", deserialize = "jason_todd"))]
+    Robin {
+        a: i8,
+        #[serde(rename(serialize = "c"))]
+        #[serde(rename(deserialize = "d"))]
+        b: A,
+    },
+}
+
+#[derive(Serialize)]
+struct SkipSerializingStruct< 'a , B, C> where C : ShouldSkip {
+    a: & 'a i8,
+    #[serde(skip_serializing)]
+    b: B,
+    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
+    c: C,
+}
+
+#[derive(Serialize)]
+enum SkipSerializingEnum<'a, B, C> where C: ShouldSkip {
+    Struct {
+        a: &'a i8,
+        #[serde(skip_serializing)]
+        _b: B,
+        #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
+        c: C,
+    },
+}
+
+#[derive(Serialize)]
+struct ContainsNotSerialize<'a, B, C, D> where B: 'a , D: SerializeWith {
+    a: &'a Option<i8>,
+    #[serde(skip_serializing)]
+    b: &'a B,
+    #[serde(skip_serializing)]
+    c: Option<C>,
+    #[serde(serialize_with = "SerializeWith::serialize_with")]
+    d: D,
+}
+
+#[derive(Serialize)]
+struct SerializeWithStruct<'a, B> where B: SerializeWith {
+    a: &'a i8,
+    #[serde(serialize_with = "SerializeWith::serialize_with")]
+    b: B,
+}
+
+#[derive(Serialize)]
+enum SerializeWithEnum<'a, B> where B: SerializeWith {
+    Struct {
+        a: &'a i8,
+        #[serde(serialize_with = "SerializeWith::serialize_with")]
+        b: B,
+    },
+}
+
+#[derive(Deserialize)]
+struct DeserializeWithStruct<B> where B: DeserializeWith {
+    a: i8,
+    #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
+    b: B,
+}
+
+#[derive(Deserialize)]
+enum DeserializeWithEnum<B> where B: DeserializeWith {
+    Struct {
+        a: i8,
+        #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
+        b: B,
+    },
+}
+
+#[derive(Deserialize)]
+enum InvalidLengthEnum {
+    A(i32, i32, i32),
+    B(
+    #[serde(skip_deserializing)]
+    i32, i32, i32),
+}
+
+#[derive(Deserialize)]
+struct TupleStruct(i32, i32, i32);
+
+#[derive(Deserialize)]
+struct Struct {
+    a: i32,
+    b: i32,
+    #[serde(skip_deserializing)]
+    c: i32,
+}
+
+#[derive(Deserialize)]
+enum Enum {
+    Unit,
+    Simple(i32),
+    Seq(i32, i32, i32),
+    Map {
+        a: i32,
+        b: i32,
+        c: i32,
+    },
+}
+
+#[derive(Deserialize)]
+struct IgnoreBase {
+    a: i32,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct With<T> {
+    t: T,
+    #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+    x: X,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct WithRef<'a, T: 'a> {
+    #[serde(skip_deserializing)]
+    t: Option<&'a T>,
+    #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+    x: X,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct PhantomX {
+    x: PhantomData<X>,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct PhantomT<T> {
+    t: PhantomData<T>,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct NoBounds<T> {
+    t: T,
+    option: Option<T>,
+    boxed: Box<T>,
+    option_boxed: Option<Box<T>>,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+enum EnumWith<T> {
+    Unit,
+    Newtype(
+            #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+            X),
+    Tuple(T,
+        #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+        X),
+    Struct {
+        t: T,
+        #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+        x: X,
+    },
+}
+
+#[derive(Serialize)]
+struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a {
+    t: T,
+    rrrt: &'a &'b &'c T,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct Newtype(
+            #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+            X);
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct Tuple<T>(T,
+                #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
+                X);
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+enum TreeNode<D> {
+    Split {
+        left: Box<TreeNode<D>>,
+        right: Box<TreeNode<D>>,
+    },
+    Leaf {
+        data: D,
+    },
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct ListNode<D> {
+    data: D,
+    next: Box<ListNode<D>>,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct RecursiveA {
+    b: Box<RecursiveB>,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+enum RecursiveB { A(RecursiveA), }
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct RecursiveGenericA<T> {
+    t: T,
+    b: Box<RecursiveGenericB<T>>,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+enum RecursiveGenericB<T> { T(T), A(RecursiveGenericA<T>), }
+
+#[derive(Serialize)]
+struct OptionStatic<'a> {
+    a: Option<&'a str>,
+    b: Option<&'static str>,
+}
+
+#[derive(Serialize)]
+#[serde(bound = "D: SerializeWith + DeserializeWith")]
+#[derive(Deserialize)]
+struct WithTraits1<D, E> {
+    #[serde(serialize_with = "SerializeWith::serialize_with",
+            deserialize_with = "DeserializeWith::deserialize_with")]
+    d: D,
+    #[serde(serialize_with = "SerializeWith::serialize_with",
+            deserialize_with = "DeserializeWith::deserialize_with",
+            bound = "E: SerializeWith + DeserializeWith")]
+    e: E,
+}
+
+#[derive(Serialize)]
+#[serde(bound(serialize = "D: SerializeWith",
+            deserialize = "D: DeserializeWith"))]
+#[derive(Deserialize)]
+struct WithTraits2<D, E> {
+    #[serde(serialize_with = "SerializeWith::serialize_with",
+            deserialize_with = "DeserializeWith::deserialize_with")]
+    d: D,
+    #[serde(serialize_with = "SerializeWith::serialize_with",
+            bound(serialize = "E: SerializeWith"))]
+    #[serde(deserialize_with = "DeserializeWith::deserialize_with",
+            bound(deserialize = "E: DeserializeWith"))]
+    e: E,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct CowStr<'a>(Cow<'a, str>);
+
+#[derive(Serialize)]
+#[serde(bound(deserialize = "T::Owned: Deserialize"))]
+#[derive(Deserialize)]
+struct CowT < 'a , T : ? Sized + 'a + ToOwned > ( Cow < 'a , T > ) ;
+
+#[derive(Serialize)]
+struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
+
+#[derive(Deserialize)]
+struct DeNamedTuple<A, B, C>(A, B, C);
+
+#[derive(Serialize)]
+struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
+    a: &'a A,
+    b: &'b mut B,
+    c: C,
+}
+
+#[derive(Deserialize)]
+struct DeNamedMap<A, B, C> {
+    a: A,
+    b: < Vec < T > as a :: b :: Trait > :: AssociatedItem,
+    c: < Vec < T > > :: AssociatedItem,
+}
+
+#[derive(Serialize)]
+enum SerEnum<'a, B: 'a, C: 'a, D> where for < 'a > D: 'a {
+    Unit,
+    Seq(i8, B, &'a C, &'a mut D),
+    Map {
+        a: i8,
+        b: B,
+        c: &'a C,
+        d: &'a mut D,
+    },
+    _Unit2,
+    _Seq2(i8, B, &'a C, &'a mut D),
+    _Map2 {
+        a: i8,
+        b: B,
+        c: &'a C,
+        d: &'a mut D,
+    },
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+enum DeEnum<B, C, D> {
+    Unit,
+    Seq(i8, B, C, D),
+    Map {
+        a: i8,
+        b: B,
+        c: C,
+        d: D,
+    },
+    _Unit2,
+    _Seq2(i8, B, C, D),
+    _Map2 {
+        a: i8,
+        b: B,
+        c: C,
+        d: D,
+    },
+}
+
+#[derive(Serialize)]
+enum Lifetimes<'a> {
+    LifetimeSeq(&'a i32),
+    NoLifetimeSeq(i32),
+    LifetimeMap {
+        a: &'a i32,
+    },
+    NoLifetimeMap {
+        a: i32,
+    },
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+pub struct GenericStruct<T> {
+    x: T,
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+pub struct GenericNewTypeStruct<T>(T);
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+pub struct GenericTupleStruct<T, U>(T, U);
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+pub enum GenericEnum<T, U: for < 'a > F<'a>> {
+    Unit,
+    NewType(T),
+    Seq(T, U),
+    Map {
+        x: T,
+        y: U,
+    },
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
+    phantom: std :: marker :: PhantomData<T>,
+}
+
+#[derive(Serialize)]
+struct UnitStruct;
+
+#[derive(Serialize)]
+struct TupleStruct(i32, i32, i32);
+
+#[derive(Serialize)]
+struct Struct {
+    a: i32,
+    b: i32,
+    c: i32,
+}
+
+#[derive(Serialize)]
+enum Enum {
+    Unit,
+    One(i32),
+    Seq(i32, i32),
+    Map {
+        a: i32,
+        b: i32,
+    },
+}
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct Bounds<T: Serialize + Deserialize> {
+    t: T,
+    option: Option<T>,
+    boxed: Box<T>,
+    option_boxed: Option<Box<T>>,
+}
+
+#[derive(Deserialize)]
+#[rustc_copy_clone_marker]
+struct UnitStruct;
+
+#[derive(Serialize)]
+#[allow(dead_code)]
+#[deny(unused_variables)]
+enum Void { }
+
+#[derive(Serialize)]
+#[derive(Deserialize)]
+struct NamedUnit;
+
+#[derive(Deserialize)]
+#[doc = r" A custom basic event not covered by the Matrix specification."]
+#[derive(Debug, Serialize)]
+pub struct CustomEvent {
+    /// The event's content.
+    content: String,
+}
diff --git a/tests/test_macro_input.rs b/tests/test_macro_input.rs
index 3c08da4..0334157 100644
--- a/tests/test_macro_input.rs
+++ b/tests/test_macro_input.rs
@@ -38,6 +38,7 @@
         vis: Visibility::Public,
         attrs: vec![
             Attribute {
+                style: AttrStyle::Outer,
                 value: MetaItem::List("derive".into(), vec![
                     MetaItem::Word("Debug".into()),
                     MetaItem::Word("Clone".into()),
@@ -96,6 +97,7 @@
         vis: Visibility::Public,
         attrs: vec![
             Attribute {
+                style: AttrStyle::Outer,
                 value: MetaItem::NameValue(
                     "doc".into(),
                     Lit::Str(
@@ -106,6 +108,7 @@
                 is_sugared_doc: true,
             },
             Attribute {
+                style: AttrStyle::Outer,
                 value: MetaItem::Word("must_use".into()),
                 is_sugared_doc: false,
             },
diff --git a/tests/test_round_trip.rs b/tests/test_round_trip.rs
new file mode 100644
index 0000000..103fb6d
--- /dev/null
+++ b/tests/test_round_trip.rs
@@ -0,0 +1,107 @@
+#![cfg(feature = "full")]
+
+#[macro_use]
+extern crate quote;
+extern crate syn;
+extern crate syntex_pos;
+extern crate syntex_syntax;
+extern crate walkdir;
+
+use syntex_pos::Span;
+use syntex_syntax::ast::{self, Attribute, TyParam};
+use syntex_syntax::fold::{self, Folder};
+use syntex_syntax::parse::{self, ParseSess, PResult};
+
+use std::fs::File;
+use std::io::{self, Read, Write};
+
+macro_rules! errorf {
+    ($($tt:tt)*) => {
+        write!(io::stderr(), $($tt)*).unwrap();
+    };
+}
+
+#[test]
+fn test_round_trip() {
+    let mut success = true;
+
+    for entry in walkdir::WalkDir::new("tests/cases").into_iter() {
+        let entry = entry.unwrap();
+
+        let path = entry.path();
+        if path.extension().map(|e| e != "rs").unwrap_or(true) {
+            continue;
+        }
+        errorf!("=== {}: ", path.display());
+
+        let mut file = File::open(path).unwrap();
+        let mut content = String::new();
+        file.read_to_string(&mut content).unwrap();
+
+        let krate = match syn::parse_crate(&content) {
+            Ok(krate) => krate,
+            Err(msg) => {
+                errorf!("syn failed to parse\n{}\n", msg);
+                success = false;
+                continue;
+            }
+        };
+        let back = quote!(#krate).to_string();
+
+        let sess = ParseSess::new();
+        let before = syntex_parse(content, &sess).unwrap();
+        let after = match syntex_parse(back, &sess) {
+            Ok(after) => after,
+            Err(mut diagnostic) => {
+                errorf!("syntex failed to parse");
+                diagnostic.emit();
+                success = false;
+                continue;
+            }
+        };
+
+        if before == after {
+            errorf!("pass\n");
+        } else {
+            errorf!("FAIL\nbefore: {:?}\nafter: {:?}\n", before, after);
+            success = false;
+        }
+    }
+
+    assert!(success);
+}
+
+fn syntex_parse<'a>(content: String, sess: &'a ParseSess) -> PResult<'a, ast::Crate> {
+    let name = "test_round_trip".to_string();
+    let cfg = Vec::new();
+    parse::parse_crate_from_source_str(name, content, cfg, sess).map(respan_crate)
+}
+
+fn respan_crate(krate: ast::Crate) -> ast::Crate {
+    struct Respanner;
+
+    impl Folder for Respanner {
+        fn new_span(&mut self, _: Span) -> Span {
+            syntex_pos::DUMMY_SP
+        }
+
+        fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
+            TyParam {
+                // default fold_ty_param does not fold the span
+                span: self.new_span(tp.span),
+                .. fold::noop_fold_ty_param(tp, self)
+            }
+        }
+
+        fn fold_attribute(&mut self, mut at: Attribute) -> Option<Attribute> {
+            at.node.id.0 = 0;
+            fold::noop_fold_attribute(at, self)
+        }
+
+        fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+            fold::noop_fold_mac(mac, self)
+        }
+    }
+
+    Respanner.fold_crate(krate)
+}
diff --git a/tests/test_serde_suite.rs b/tests/test_serde_suite.rs
deleted file mode 100644
index 0d6f29a..0000000
--- a/tests/test_serde_suite.rs
+++ /dev/null
@@ -1,606 +0,0 @@
-extern crate syn;
-
-#[macro_use]
-extern crate quote;
-
-/// These are all of the items from serde_codegen's test suite.
-/// Obnoxious whitespace has been added in an attempt to fool the parser.
-#[test]
-fn test_all() {
-    for s in ITEMS {
-        let ast = syn::parse_macro_input(s).unwrap();
-        let tokens = quote!(#ast).to_string();
-        assert_eq!(ast, syn::parse_macro_input(&tokens).unwrap());
-    }
-
-    static ITEMS: &'static [&'static str] = &[
-        r#"
-        # [ derive ( Serialize ) ]
-         #[derive(Deserialize)]
-        struct DefaultStruct <A , B, C, D, E> where C : MyDefault , E: MyDefault {
-            a1 : A,
-            #[serde(default)]
-            a2: B,
-            #[serde(default = "MyDefault::my_default")]
-            a3: C,
-            #[serde(skip_deserializing)]
-            a4: D,
-            #[serde(skip_deserializing, default = "MyDefault::my_default")]
-            a5: E,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        enum DefaultEnum<A, B, C, D, E> where C: MyDefault, E: MyDefault {
-            Struct {
-                a1: A,
-                #[serde(default)]
-                a2: B,
-                #[serde(default = "MyDefault::my_default")]
-                a3: C,
-                #[serde(skip_deserializing)]
-                a4: D,
-                #[serde(skip_deserializing, default = "MyDefault::my_default")]
-                a5: E,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct NoStdDefault(i8);
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct ContainsNoStdDefault <A : MyDefault> {
-            #[serde(default = "MyDefault::my_default")]
-            a: A,
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> {
-            #[serde(skip_deserializing)]
-            a: A,
-            #[serde(skip_deserializing, default)]
-            b: B,
-            #[serde(deserialize_with = "DeserializeWith::deserialize_with", default)]
-            c: C,
-            #[serde(skip_deserializing, default = "MyDefault::my_default")]
-            e: E,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[serde(deny_unknown_fields)]
-        #[derive(Deserialize)]
-        struct DenyUnknown {
-            a1: i32,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[serde(rename = "Superhero")]
-        #[derive(Deserialize)]
-        struct RenameStruct {
-            a1: i32,
-            #[serde(rename = "a3")]
-            a2: i32,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[serde(rename(serialize = "SuperheroSer", deserialize = "SuperheroDe"))]
-        #[derive(Deserialize)]
-        struct RenameStructSerializeDeserialize {
-            a1: i32,
-            #[serde(rename(serialize = "a4", deserialize = "a5"))]
-            a2: i32,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[serde(rename = "Superhero")]
-        #[derive(Deserialize)]
-        enum RenameEnum {
-
-            #[serde(rename = "bruce_wayne")]
-            Batman ,
-
-            #[serde(rename = "clark_kent")]
-            Superman ( i8 ) ,
-
-            #[serde(rename = "diana_prince")]
-            WonderWoman ( i8 , i8 ) ,
-
-            #[serde(rename = "barry_allan")]
-            Flash {
-                #[serde(rename = "b")]
-                a : i32,
-            } ,
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        #[serde ( rename ( serialize = "SuperheroSer" , deserialize = "SuperheroDe" ) ) ]
-        #[derive(Serialize)]
-        enum RenameEnumSerializeDeserialize<A> {
-
-            #[serde(rename(serialize = "dick_grayson", deserialize = "jason_todd"))]
-            Robin {
-                a: i8,
-                #[serde(rename(serialize = "c"))]
-                #[serde(rename(deserialize = "d"))]
-                b: A,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct SkipSerializingStruct< 'a , B, C> where C : ShouldSkip {
-            a: & 'a i8,
-            #[serde(skip_serializing)]
-            b: B,
-            #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
-            c: C,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        enum SkipSerializingEnum<'a, B, C> where C: ShouldSkip {
-            Struct {
-                a: &'a i8,
-                #[serde(skip_serializing)]
-                _b: B,
-                #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
-                c: C,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct ContainsNotSerialize<'a, B, C, D> where B: 'a , D: SerializeWith {
-            a: &'a Option<i8>,
-            #[serde(skip_serializing)]
-            b: &'a B,
-            #[serde(skip_serializing)]
-            c: Option<C>,
-            #[serde(serialize_with = "SerializeWith::serialize_with")]
-            d: D,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct SerializeWithStruct<'a, B> where B: SerializeWith {
-            a: &'a i8,
-            #[serde(serialize_with = "SerializeWith::serialize_with")]
-            b: B,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        enum SerializeWithEnum<'a, B> where B: SerializeWith {
-            Struct {
-                a: &'a i8,
-                #[serde(serialize_with = "SerializeWith::serialize_with")]
-                b: B,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct DeserializeWithStruct<B> where B: DeserializeWith {
-            a: i8,
-            #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
-            b: B,
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        enum DeserializeWithEnum<B> where B: DeserializeWith {
-            Struct {
-                a: i8,
-                #[serde(deserialize_with = "DeserializeWith::deserialize_with")]
-                b: B,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        enum InvalidLengthEnum {
-            A(i32, i32, i32),
-            B(
-            #[serde(skip_deserializing)]
-            i32, i32, i32),
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct TupleStruct(i32, i32, i32);
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct Struct {
-            a: i32,
-            b: i32,
-            #[serde(skip_deserializing)]
-            c: i32,
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        enum Enum {
-            Unit,
-            Simple(i32),
-            Seq(i32, i32, i32),
-            Map {
-                a: i32,
-                b: i32,
-                c: i32,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct IgnoreBase {
-            a: i32,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct With<T> {
-            t: T,
-            #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
-            x: X,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct WithRef<'a, T: 'a> {
-            #[serde(skip_deserializing)]
-            t: Option<&'a T>,
-            #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
-            x: X,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct PhantomX {
-            x: PhantomData<X>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct PhantomT<T> {
-            t: PhantomData<T>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct NoBounds<T> {
-            t: T,
-            option: Option<T>,
-            boxed: Box<T>,
-            option_boxed: Option<Box<T>>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        enum EnumWith<T> {
-            Unit,
-            Newtype(
-                    #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
-                    X),
-            Tuple(T,
-                #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
-                X),
-            Struct {
-                t: T,
-                #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
-                x: X,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a {
-            t: T,
-            rrrt: &'a &'b &'c T,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct Newtype(
-                    #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
-                    X);
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct Tuple<T>(T,
-                        #[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
-                        X);
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        enum TreeNode<D> {
-            Split {
-                left: Box<TreeNode<D>>,
-                right: Box<TreeNode<D>>,
-            },
-            Leaf {
-                data: D,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct ListNode<D> {
-            data: D,
-            next: Box<ListNode<D>>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct RecursiveA {
-            b: Box<RecursiveB>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        enum RecursiveB { A(RecursiveA), }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct RecursiveGenericA<T> {
-            t: T,
-            b: Box<RecursiveGenericB<T>>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        enum RecursiveGenericB<T> { T(T), A(RecursiveGenericA<T>), }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct OptionStatic<'a> {
-            a: Option<&'a str>,
-            b: Option<&'static str>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[serde(bound = "D: SerializeWith + DeserializeWith")]
-        #[derive(Deserialize)]
-        struct WithTraits1<D, E> {
-            #[serde(serialize_with = "SerializeWith::serialize_with",
-                    deserialize_with = "DeserializeWith::deserialize_with")]
-            d: D,
-            #[serde(serialize_with = "SerializeWith::serialize_with",
-                    deserialize_with = "DeserializeWith::deserialize_with",
-                    bound = "E: SerializeWith + DeserializeWith")]
-            e: E,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[serde(bound(serialize = "D: SerializeWith",
-                    deserialize = "D: DeserializeWith"))]
-        #[derive(Deserialize)]
-        struct WithTraits2<D, E> {
-            #[serde(serialize_with = "SerializeWith::serialize_with",
-                    deserialize_with = "DeserializeWith::deserialize_with")]
-            d: D,
-            #[serde(serialize_with = "SerializeWith::serialize_with",
-                    bound(serialize = "E: SerializeWith"))]
-            #[serde(deserialize_with = "DeserializeWith::deserialize_with",
-                    bound(deserialize = "E: DeserializeWith"))]
-            e: E,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct CowStr<'a>(Cow<'a, str>);
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[serde(bound(deserialize = "T::Owned: Deserialize"))]
-        #[derive(Deserialize)]
-        struct CowT < 'a , T : ? Sized + 'a + ToOwned > ( Cow < 'a , T > ) ;
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct DeNamedTuple<A, B, C>(A, B, C);
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
-            a: &'a A,
-            b: &'b mut B,
-            c: C,
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        struct DeNamedMap<A, B, C> {
-            a: A,
-            b: < Vec < T > as a :: b :: Trait > :: AssociatedItem,
-            c: < Vec < T > > :: AssociatedItem,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        enum SerEnum<'a, B: 'a, C: 'a, D> where for < 'a > D: 'a {
-            Unit,
-            Seq(i8, B, &'a C, &'a mut D),
-            Map {
-                a: i8,
-                b: B,
-                c: &'a C,
-                d: &'a mut D,
-            },
-            _Unit2,
-            _Seq2(i8, B, &'a C, &'a mut D),
-            _Map2 {
-                a: i8,
-                b: B,
-                c: &'a C,
-                d: &'a mut D,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        enum DeEnum<B, C, D> {
-            Unit,
-            Seq(i8, B, C, D),
-            Map {
-                a: i8,
-                b: B,
-                c: C,
-                d: D,
-            },
-            _Unit2,
-            _Seq2(i8, B, C, D),
-            _Map2 {
-                a: i8,
-                b: B,
-                c: C,
-                d: D,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        enum Lifetimes<'a> {
-            LifetimeSeq(&'a i32),
-            NoLifetimeSeq(i32),
-            LifetimeMap {
-                a: &'a i32,
-            },
-            NoLifetimeMap {
-                a: i32,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        pub struct GenericStruct<T> {
-            x: T,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        pub struct GenericNewTypeStruct<T>(T);
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        pub struct GenericTupleStruct<T, U>(T, U);
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        pub enum GenericEnum<T, U: for < 'a > F<'a>> {
-            Unit,
-            NewType(T),
-            Seq(T, U),
-            Map {
-                x: T,
-                y: U,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
-            phantom: std :: marker :: PhantomData<T>,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct UnitStruct;
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct TupleStruct(i32, i32, i32);
-        "#,
-        r#"
-        #[derive(Serialize)]
-        struct Struct {
-            a: i32,
-            b: i32,
-            c: i32,
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        enum Enum {
-            Unit,
-            One(i32),
-            Seq(i32, i32),
-            Map {
-                a: i32,
-                b: i32,
-            },
-        }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct Bounds<T: Serialize + Deserialize> {
-            t: T,
-            option: Option<T>,
-            boxed: Box<T>,
-            option_boxed: Option<Box<T>>,
-        }
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        #[rustc_copy_clone_marker]
-        struct UnitStruct;
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[allow(dead_code)]
-        #[deny(unused_variables)]
-        enum Void { }
-        "#,
-        r#"
-        #[derive(Serialize)]
-        #[derive(Deserialize)]
-        struct NamedUnit;
-        "#,
-        r#"
-        #[derive(Deserialize)]
-        #[doc = r" A custom basic event not covered by the Matrix specification."]
-        #[derive(Debug, Serialize)]
-        pub struct CustomEvent {
-            /// The event's content.
-            content: String,
-        }
-        "#,
-    ];
-}