Combine the two heapsize examples
diff --git a/README.md b/README.md
index 560bbbe..bd12278 100644
--- a/README.md
+++ b/README.md
@@ -133,13 +133,6 @@
 
 ## Spans and error reporting
 
-The [`heapsize2`] example directory is an extension of the `heapsize` example
-that demonstrates some of the hygiene and error reporting properties of Macros
-2.0. This example currently requires a nightly Rust compiler \>=1.24.0-nightly
-but we are working to stabilize all of the APIs involved.
-
-[`heapsize2`]: examples/heapsize2
-
 The token-based procedural macro API provides great control over where the
 compiler's error messages are displayed in user code. Consider the error the
 user sees if one of their field types does not implement `HeapSize`.
@@ -152,20 +145,8 @@
 }
 ```
 
-In the Macros 1.1 string-based procedural macro world, the resulting error would
-point unhelpfully to the invocation of the derive macro and not to the actual
-problematic field.
-
-```
-error[E0599]: no method named `heap_size_of_children` found for type `std::thread::Thread` in the current scope
- --> src/main.rs:4:10
-  |
-4 | #[derive(HeapSize)]
-  |          ^^^^^^^^
-```
-
 By tracking span information all the way through the expansion of a procedural
-macro as shown in the `heapsize2` example, token-based macros in Syn are able to
+macro as shown in the `heapsize` example, token-based macros in Syn are able to
 trigger errors that directly pinpoint the source of the problem.
 
 ```
diff --git a/examples/README.md b/examples/README.md
index 75bc450..267c28f 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -5,16 +5,8 @@
 
 ### [`heapsize`](heapsize)
 
-A complete working Macros 1.1 implementation of a custom derive. Works on any
-Rust compiler >=1.15.0.
-
-### [`heapsize2`](heapsize2)
-
-The equivalent of the previous example but using fancy new APIs from the nightly
-compiler. It illustrates some neat features of the hygiene system of Macros 2.0
-and shows how to leverage those to provide amazing error messages to users.
-Currently requires a nightly Rust compiler >=1.24.0-nightly but we are working
-to stabilize all of the APIs involved.
+A complete working implementation of a custom derive. Works on any Rust compiler
+>=1.15.0.
 
 ### [`lazy-static`](lazy-static)
 
diff --git a/examples/heapsize/README.md b/examples/heapsize/README.md
index b3deb8d..1fe56ff 100644
--- a/examples/heapsize/README.md
+++ b/examples/heapsize/README.md
@@ -1,5 +1,5 @@
-A complete working Macros 1.1 implementation of a custom derive. Works on any
-Rust compiler >=1.15.0.
+A complete working implementation of a custom derive. Works on any Rust compiler
+\>=1.15.0.
 
 - [`heapsize/src/lib.rs`](heapsize/src/lib.rs)
 - [`heapsize_derive/src/lib.rs`](heapsize_derive/src/lib.rs)
@@ -40,3 +40,34 @@
     }
 }
 ```
+
+The implementation of `heapsize_derive` demonstrates some attention to "spans"
+of error messages. For each subexpression in the generated code we apply the
+span of the input fragment under which we would want to trigger a compiler error
+if the subexpression fails to compile. In this example, each recursive call to
+`heap_size_of_children` is associated with the span of the corresponding struct
+field. Thus we get errors in the right place if any of the field types do not
+implement the `HeapSize` trait.
+
+```
+error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
+ --> src/main.rs:7:5
+  |
+7 |     bad: std::thread::Thread,
+  |     ^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`
+```
+
+Some unstable APIs in the `proc-macro2` crate let us improve this further by
+joining together the span of the field name and the field type. There is no
+difference in our code -- everything is as shown in this directory -- but
+building the example crate with `cargo build` shows errors like the one above
+and building with `RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build` is
+able to show errors like the following.
+
+```
+error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
+ --> src/main.rs:7:5
+  |
+7 |     bad: std::thread::Thread,
+  |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`
+```
diff --git a/examples/heapsize/heapsize_derive/src/lib.rs b/examples/heapsize/heapsize_derive/src/lib.rs
index 5e9d153..2693bdd 100644
--- a/examples/heapsize/heapsize_derive/src/lib.rs
+++ b/examples/heapsize/heapsize_derive/src/lib.rs
@@ -8,7 +8,8 @@
 extern crate quote;
 
 use proc_macro2::TokenStream;
-use syn::{Data, DeriveInput, Fields, GenericParam, Generics};
+use syn::spanned::Spanned;
+use syn::{Data, DeriveInput, Fields, GenericParam, Generics, Index};
 
 #[proc_macro_derive(HeapSize)]
 pub fn derive_heap_size(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
@@ -59,22 +60,35 @@
                     //     0 + self.x.heap_size() + self.y.heap_size() + self.z.heap_size()
                     //
                     // but using fully qualified function call syntax.
-                    let fnames = fields.named.iter().map(|f| &f.ident);
+                    //
+                    // We take some care to use the span of each `syn::Field` as
+                    // the span of the corresponding `heap_size_of_children`
+                    // call. This way if one of the field types does not
+                    // implement `HeapSize` then the compiler's error message
+                    // underlines which field it is. An example is shown in the
+                    // readme of the parent directory.
+                    let recurse = fields.named.iter().map(|f| {
+                        let name = &f.ident;
+                        quote_spanned! {f.span()=>
+                            ::heapsize::HeapSize::heap_size_of_children(&self.#name)
+                        }
+                    });
                     quote! {
-                        0 #(
-                            + ::heapsize::HeapSize::heap_size_of_children(&self.#fnames)
-                        )*
+                        0 #(+ #recurse)*
                     }
                 }
                 Fields::Unnamed(ref fields) => {
                     // Expands to an expression like
                     //
                     //     0 + self.0.heap_size() + self.1.heap_size() + self.2.heap_size()
-                    let indices = 0..fields.unnamed.len();
+                    let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| {
+                        let index = Index::from(i);
+                        quote_spanned! {f.span()=>
+                            ::heapsize::HeapSize::heap_size_of_children(&self.#index)
+                        }
+                    });
                     quote! {
-                        0 #(
-                            + ::heapsize::HeapSize::heap_size_of_children(&self.#indices)
-                        )*
+                        0 #(+ #recurse)*
                     }
                 }
                 Fields::Unit => {
diff --git a/examples/heapsize2/README.md b/examples/heapsize2/README.md
deleted file mode 100644
index 3d232e7..0000000
--- a/examples/heapsize2/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-A complete working custom derive that illustrates the hygiene properties of
-Macros 2.0. Currently requires a nightly Rust compiler >=1.24.0-nightly but we
-are working to stabilize all of the APIs used here.
-
-This is the same example as the unhygienic stable [`heapsize`](../heapsize)
-example. Please read that other example first before diving into this one, as
-the comments here assume an understanding of how the other one works.
-
-- [`heapsize/src/lib.rs`](heapsize/src/lib.rs) (unchanged)
-- [`heapsize_derive/src/lib.rs`](heapsize_derive/src/lib.rs)
-- [`example/src/main.rs`](example/src/main.rs)
-
-A major advantage of spans and the token-based procedural macro API is that we
-get great control over where the compiler's error messages are displayed.
-Consider the error the user sees if one of their field types does not implement
-`HeapSize`.
-
-```rust
-#[derive(HeapSize)]
-struct Broken {
-    ok: String,
-    bad: std::thread::Thread,
-}
-```
-
-The Macros 1.1 string-based procedural macro and a naively implemented
-token-based procedural macro result in the following error.
-
-```
-error[E0599]: no method named `heap_size_of_children` found for type `std::thread::Thread` in the current scope
- --> src/main.rs:4:10
-  |
-4 | #[derive(HeapSize)]
-  |          ^^^^^^^^
-```
-
-With just a bit of work, as shown in the `heapsize_derive` implementation here,
-we can improve this error to point out exactly which field is not right.
-
-```
-error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
- --> src/main.rs:7:5
-  |
-7 |     bad: std::thread::Thread,
-  |     ^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`
-```
-
-Some unstable APIs in the `proc-macro2` crate let us improve this further by
-joining together the span of the field name and the field type. There is no
-difference in our code -- everything is as shown in this directory -- but
-building the example crate with `cargo build` shows errors like the one above
-and building with `RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build` is
-able to show errors like the following.
-
-```
-error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
- --> src/main.rs:7:5
-  |
-7 |     bad: std::thread::Thread,
-  |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`
-```
diff --git a/examples/heapsize2/example/Cargo.toml b/examples/heapsize2/example/Cargo.toml
deleted file mode 100644
index 0384d16..0000000
--- a/examples/heapsize2/example/Cargo.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-name = "heapsize_example"
-version = "0.0.0"
-authors = ["David Tolnay <dtolnay@gmail.com>"]
-publish = false
-
-[dependencies]
-heapsize = { path = "../heapsize" }
-heapsize_derive = { path = "../heapsize_derive" }
diff --git a/examples/heapsize2/example/src/main.rs b/examples/heapsize2/example/src/main.rs
deleted file mode 100644
index e424c11..0000000
--- a/examples/heapsize2/example/src/main.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-#[macro_use]
-extern crate heapsize_derive;
-
-extern crate heapsize;
-
-#[derive(HeapSize)]
-struct Demo<'a, T: ?Sized> {
-    a: Box<T>,
-    b: u8,
-    c: &'a str,
-    d: HeapSize,
-}
-
-#[derive(HeapSize)]
-struct HeapSize {
-    e: String,
-}
-
-fn main() {
-    let demo = Demo {
-        a: b"bytestring".to_vec().into_boxed_slice(),
-        b: 255,
-        c: "&'static str",
-        d: HeapSize {
-            e: "String".to_owned(),
-        },
-    };
-    println!(
-        "heap size = {}",
-        heapsize::HeapSize::heap_size_of_children(&demo)
-    );
-}
diff --git a/examples/heapsize2/heapsize/Cargo.toml b/examples/heapsize2/heapsize/Cargo.toml
deleted file mode 100644
index 7f321b5..0000000
--- a/examples/heapsize2/heapsize/Cargo.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-[package]
-name = "heapsize"
-version = "0.0.0"
-authors = ["David Tolnay <dtolnay@gmail.com>"]
-publish = false
-
-[dependencies]
diff --git a/examples/heapsize2/heapsize/src/lib.rs b/examples/heapsize2/heapsize/src/lib.rs
deleted file mode 100644
index 8b4ce03..0000000
--- a/examples/heapsize2/heapsize/src/lib.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use std::mem;
-
-pub trait HeapSize {
-    /// Total number of bytes of heap memory owned by `self`.
-    ///
-    /// Does not include the size of `self` itself, which may or may not be on
-    /// the heap. Includes only children of `self`, meaning things pointed to by
-    /// `self`.
-    fn heap_size_of_children(&self) -> usize;
-}
-
-//
-// In a real version of this library there would be lots more impls here, but
-// here are some interesting ones.
-//
-
-impl HeapSize for u8 {
-    /// A `u8` does not own any heap memory.
-    fn heap_size_of_children(&self) -> usize {
-        0
-    }
-}
-
-impl HeapSize for String {
-    /// A `String` owns enough heap memory to hold its reserved capacity.
-    fn heap_size_of_children(&self) -> usize {
-        self.capacity()
-    }
-}
-
-impl<T> HeapSize for Box<T>
-where
-    T: ?Sized + HeapSize,
-{
-    /// A `Box` owns however much heap memory was allocated to hold the value of
-    /// type `T` that we placed on the heap, plus transitively however much `T`
-    /// itself owns.
-    fn heap_size_of_children(&self) -> usize {
-        mem::size_of_val(&**self) + (**self).heap_size_of_children()
-    }
-}
-
-impl<T> HeapSize for [T]
-where
-    T: HeapSize,
-{
-    /// Sum of heap memory owned by each element of a dynamically sized slice of
-    /// `T`.
-    fn heap_size_of_children(&self) -> usize {
-        self.iter().map(HeapSize::heap_size_of_children).sum()
-    }
-}
-
-impl<'a, T> HeapSize for &'a T
-where
-    T: ?Sized,
-{
-    /// A shared reference does not own heap memory.
-    fn heap_size_of_children(&self) -> usize {
-        0
-    }
-}
diff --git a/examples/heapsize2/heapsize_derive/Cargo.toml b/examples/heapsize2/heapsize_derive/Cargo.toml
deleted file mode 100644
index 9dd7af7..0000000
--- a/examples/heapsize2/heapsize_derive/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "heapsize_derive"
-version = "0.0.0"
-authors = ["David Tolnay <dtolnay@gmail.com>"]
-publish = false
-
-[lib]
-proc-macro = true
-
-[dependencies]
-syn = { path = "../../.." }
-quote = "0.6"
-proc-macro2 = { version = "0.4", features = ["nightly"] }
diff --git a/examples/heapsize2/heapsize_derive/src/lib.rs b/examples/heapsize2/heapsize_derive/src/lib.rs
deleted file mode 100644
index 4d70771..0000000
--- a/examples/heapsize2/heapsize_derive/src/lib.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-extern crate proc_macro;
-extern crate proc_macro2;
-
-#[macro_use]
-extern crate syn;
-
-#[macro_use]
-extern crate quote;
-
-use proc_macro2::{Span, TokenStream};
-use syn::spanned::Spanned;
-use syn::{Data, DeriveInput, Fields, GenericParam, Generics, Index};
-
-#[proc_macro_derive(HeapSize)]
-pub fn derive_heap_size(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    // Parse the input tokens into a syntax tree.
-    let input = parse_macro_input!(input as DeriveInput);
-
-    // Used in the quasi-quotation below as `#name`.
-    let name = input.ident;
-
-    // Add a bound `T: HeapSize` to every type parameter T.
-    let generics = add_trait_bounds(input.generics);
-    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
-
-    // Generate an expression to sum up the heap size of each field.
-    let var = quote!(self);
-    let sum = heap_size_sum(&input.data, &var);
-
-    let expanded = quote! {
-        // The generated impl.
-        impl #impl_generics ::heapsize::HeapSize for #name #ty_generics #where_clause {
-            fn heap_size_of_children(&#var) -> usize {
-                #sum
-            }
-        }
-    };
-
-    // Hand the output tokens back to the compiler.
-    proc_macro::TokenStream::from(expanded)
-}
-
-// Add a bound `T: HeapSize` to every type parameter T.
-fn add_trait_bounds(mut generics: Generics) -> Generics {
-    for param in &mut generics.params {
-        if let GenericParam::Type(ref mut type_param) = *param {
-            type_param.bounds.push(parse_quote!(::heapsize::HeapSize));
-        }
-    }
-    generics
-}
-
-// Generate an expression to sum up the heap size of each field.
-fn heap_size_sum(data: &Data, var: &TokenStream) -> TokenStream {
-    let call_site = Span::call_site();
-
-    match *data {
-        Data::Struct(ref data) => {
-            match data.fields {
-                Fields::Named(ref fields) => {
-                    // Expands to an expression like
-                    //
-                    //     0 + HeapSize::heap_size(&self.x) + HeapSize::heap_size(&self.y)
-                    //
-                    // We take some care to use the span of each `syn::Field` as
-                    // the span of the corresponding `heap_size_of_children`
-                    // call. This way if one of the field types does not
-                    // implement `HeapSize` then the compiler's error message
-                    // underlines which field it is. An example is shown in the
-                    // readme of the parent directory.
-                    let recurse = fields.named.iter().map(|f| {
-                        let name = &f.ident;
-                        let access = quote_spanned!(call_site=> #var.#name);
-                        quote_spanned! {f.span()=>
-                            ::heapsize::HeapSize::heap_size_of_children(&#access)
-                        }
-                    });
-                    quote! {
-                        0 #(+ #recurse)*
-                    }
-                }
-                Fields::Unnamed(ref fields) => {
-                    // This expands to an expression like
-                    //
-                    //     0 + HeapSize::heap_size(&self.0) + HeapSize::heap_size(&self.1)
-                    let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| {
-                        let index = Index {
-                            index: i as u32,
-                            span: call_site,
-                        };
-                        let access = quote_spanned!(call_site=> #var.#index);
-                        quote_spanned! {f.span()=>
-                            ::heapsize::HeapSize::heap_size_of_children(&#access)
-                        }
-                    });
-                    quote! {
-                        0 #(+ #recurse)*
-                    }
-                }
-                Fields::Unit => {
-                    // Unit structs cannot own more than 0 bytes of heap memory.
-                    quote!(0)
-                }
-            }
-        }
-        Data::Enum(_) | Data::Union(_) => unimplemented!(),
-    }
-}
diff --git a/src/lib.rs b/src/lib.rs
index 68fc5fc..5953c64 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -133,13 +133,6 @@
 //!
 //! ## Spans and error reporting
 //!
-//! The [`heapsize2`] example directory is an extension of the `heapsize`
-//! example that demonstrates some of the hygiene and error reporting properties
-//! of Macros 2.0. This example currently requires a nightly Rust compiler
-//! \>=1.24.0-nightly but we are working to stabilize all of the APIs involved.
-//!
-//! [`heapsize2`]: https://github.com/dtolnay/syn/tree/master/examples/heapsize2
-//!
 //! The token-based procedural macro API provides great control over where the
 //! compiler's error messages are displayed in user code. Consider the error the
 //! user sees if one of their field types does not implement `HeapSize`.
@@ -154,20 +147,8 @@
 //! }
 //! ```
 //!
-//! In the Macros 1.1 string-based procedural macro world, the resulting error
-//! would point unhelpfully to the invocation of the derive macro and not to the
-//! actual problematic field.
-//!
-//! ```text
-//! error[E0599]: no method named `heap_size_of_children` found for type `std::thread::Thread` in the current scope
-//!  --> src/main.rs:4:10
-//!   |
-//! 4 | #[derive(HeapSize)]
-//!   |          ^^^^^^^^
-//! ```
-//!
 //! By tracking span information all the way through the expansion of a
-//! procedural macro as shown in the `heapsize2` example, token-based macros in
+//! procedural macro as shown in the `heapsize` example, token-based macros in
 //! Syn are able to trigger errors that directly pinpoint the source of the
 //! problem.
 //!