Documentation of expression types
diff --git a/src/expr.rs b/src/expr.rs
index b019231..cf3c519 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -17,16 +17,16 @@
 use std::mem;
 
 ast_enum_of_structs! {
-    /// An expression.
+    /// A Rust expression.
     pub enum Expr {
-        /// A `box x` expression.
+        /// A box expression: `box f`.
         pub Box(ExprBox #full {
             pub attrs: Vec<Attribute>,
             pub box_token: Token![box],
             pub expr: Box<Expr>,
         }),
 
-        /// E.g. 'place <- value'.
+        /// A placement expression: `place <- value`.
         pub InPlace(ExprInPlace #full {
             pub attrs: Vec<Attribute>,
             pub place: Box<Expr>,
@@ -34,14 +34,14 @@
             pub value: Box<Expr>,
         }),
 
-        /// An array, e.g. `[a, b, c, d]`.
+        /// A slice literal expression: `[a, b, c, d]`.
         pub Array(ExprArray #full {
             pub attrs: Vec<Attribute>,
             pub bracket_token: token::Bracket,
             pub elems: Punctuated<Expr, Token![,]>,
         }),
 
-        /// A function call.
+        /// A function call expression: `invoke(a, b)`.
         pub Call(ExprCall {
             pub attrs: Vec<Attribute>,
             pub func: Box<Expr>,
@@ -49,11 +49,7 @@
             pub args: Punctuated<Expr, Token![,]>,
         }),
 
-        /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
-        ///
-        /// The `Ident` is the identifier for the method name.
-        /// The vector of `Type`s are the ascripted type parameters for the method
-        /// (within the angle brackets).
+        /// A method call expression: `x.foo::<T>(a, b)`.
         pub MethodCall(ExprMethodCall #full {
             pub attrs: Vec<Attribute>,
             pub receiver: Box<Expr>,
@@ -64,14 +60,14 @@
             pub args: Punctuated<Expr, Token![,]>,
         }),
 
-        /// A tuple, e.g. `(a, b, c, d)`.
+        /// A tuple expression: `(a, b, c, d)`.
         pub Tuple(ExprTuple #full {
             pub attrs: Vec<Attribute>,
             pub paren_token: token::Paren,
             pub elems: Punctuated<Expr, Token![,]>,
         }),
 
-        /// A binary operation, e.g. `a + b`, `a * b`.
+        /// A binary operation: `a + b`, `a * b`.
         pub Binary(ExprBinary {
             pub attrs: Vec<Attribute>,
             pub left: Box<Expr>,
@@ -79,20 +75,20 @@
             pub right: Box<Expr>,
         }),
 
-        /// A unary operation, e.g. `!x`, `*x`.
+        /// A unary operation: `!x`, `*x`.
         pub Unary(ExprUnary {
             pub attrs: Vec<Attribute>,
             pub op: UnOp,
             pub expr: Box<Expr>,
         }),
 
-        /// A literal, e.g. `1`, `"foo"`.
+        /// A literal in place of an expression: `1`, `"foo"`.
         pub Lit(ExprLit {
             pub attrs: Vec<Attribute>,
             pub lit: Lit,
         }),
 
-        /// A cast, e.g. `foo as f64`.
+        /// A cast expression: `foo as f64`.
         pub Cast(ExprCast {
             pub attrs: Vec<Attribute>,
             pub expr: Box<Expr>,
@@ -100,7 +96,7 @@
             pub ty: Box<Type>,
         }),
 
-        /// A type ascription, e.g. `foo: f64`.
+        /// A type ascription expression: `foo: f64`.
         pub Type(ExprType #full {
             pub attrs: Vec<Attribute>,
             pub expr: Box<Expr>,
@@ -108,9 +104,11 @@
             pub ty: Box<Type>,
         }),
 
-        /// An `if` block, with an optional else block
+        /// An `if` expression with an optional `else` block: `if expr { ... }
+        /// else { ... }`.
         ///
-        /// E.g., `if expr { block } else { expr }`
+        /// The `else` branch expression may only be an `If`, `IfLet`, or
+        /// `Block` expression, not any of the other types of expression.
         pub If(ExprIf #full {
             pub attrs: Vec<Attribute>,
             pub if_token: Token![if],
@@ -119,11 +117,11 @@
             pub else_branch: Option<(Token![else], Box<Expr>)>,
         }),
 
-        /// An `if let` expression with an optional else block
+        /// An `if let` expression with an optional `else` block: `if let pat =
+        /// expr { ... } else { ... }`.
         ///
-        /// E.g., `if let pat = expr { block } else { expr }`
-        ///
-        /// This is desugared to a `match` expression.
+        /// The `else` branch expression may only be an `If`, `IfLet`, or
+        /// `Block` expression, not any of the other types of expression.
         pub IfLet(ExprIfLet #full {
             pub attrs: Vec<Attribute>,
             pub if_token: Token![if],
@@ -135,9 +133,7 @@
             pub else_branch: Option<(Token![else], Box<Expr>)>,
         }),
 
-        /// A while loop, with an optional label
-        ///
-        /// E.g., `'label: while expr { block }`
+        /// A while loop: `while expr { ... }`.
         pub While(ExprWhile #full {
             pub attrs: Vec<Attribute>,
             pub label: Option<Label>,
@@ -146,11 +142,7 @@
             pub body: Block,
         }),
 
-        /// A while-let loop, with an optional label.
-        ///
-        /// E.g., `'label: while let pat = expr { block }`
-        ///
-        /// This is desugared to a combination of `loop` and `match` expressions.
+        /// A while-let loop: `while let pat = expr { ... }`.
         pub WhileLet(ExprWhileLet #full {
             pub attrs: Vec<Attribute>,
             pub label: Option<Label>,
@@ -162,11 +154,7 @@
             pub body: Block,
         }),
 
-        /// A for loop, with an optional label.
-        ///
-        /// E.g., `'label: for pat in expr { block }`
-        ///
-        /// This is desugared to a combination of `loop` and `match` expressions.
+        /// A for loop: `for pat in expr { ... }`.
         pub ForLoop(ExprForLoop #full {
             pub attrs: Vec<Attribute>,
             pub label: Option<Label>,
@@ -177,9 +165,7 @@
             pub body: Block,
         }),
 
-        /// Conditionless loop with an optional label.
-        ///
-        /// E.g. `'label: loop { block }`
+        /// Conditionless loop: `loop { ... }`.
         pub Loop(ExprLoop #full {
             pub attrs: Vec<Attribute>,
             pub label: Option<Label>,
@@ -187,7 +173,7 @@
             pub body: Block,
         }),
 
-        /// A `match` block.
+        /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
         pub Match(ExprMatch #full {
             pub attrs: Vec<Attribute>,
             pub match_token: Token![match],
@@ -196,7 +182,7 @@
             pub arms: Vec<Arm>,
         }),
 
-        /// A closure (for example, `move |a, b, c| a + b + c`)
+        /// A closure expression: `|a, b| a + b`.
         pub Closure(ExprClosure #full {
             pub attrs: Vec<Attribute>,
             pub capture: Option<Token![move]>,
@@ -207,20 +193,20 @@
             pub body: Box<Expr>,
         }),
 
-        /// An unsafe block (`unsafe { ... }`)
+        /// An unsafe block: `unsafe { ... }`.
         pub Unsafe(ExprUnsafe #full {
             pub attrs: Vec<Attribute>,
             pub unsafe_token: Token![unsafe],
             pub block: Block,
         }),
 
-        /// A block (`{ ... }`)
+        /// A blocked scope: `{ ... }`.
         pub Block(ExprBlock #full {
             pub attrs: Vec<Attribute>,
             pub block: Block,
         }),
 
-        /// An assignment (`a = foo()`)
+        /// An assignment expression: `a = compute()`.
         pub Assign(ExprAssign #full {
             pub attrs: Vec<Attribute>,
             pub left: Box<Expr>,
@@ -228,9 +214,7 @@
             pub right: Box<Expr>,
         }),
 
-        /// An assignment with an operator
-        ///
-        /// For example, `a += 1`.
+        /// A compound assignment expression: `counter += 1`.
         pub AssignOp(ExprAssignOp #full {
             pub attrs: Vec<Attribute>,
             pub left: Box<Expr>,
@@ -238,7 +222,7 @@
             pub right: Box<Expr>,
         }),
 
-        /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
+        /// Access of a named struct field (`obj.k`) or unnamed tuple struct
         /// field (`obj.0`).
         pub Field(ExprField #full {
             pub attrs: Vec<Attribute>,
@@ -247,7 +231,7 @@
             pub member: Member,
         }),
 
-        /// An indexing operation (`foo[2]`)
+        /// A square bracketed indexing expression: `vector[2]`
         pub Index(ExprIndex {
             pub attrs: Vec<Attribute>,
             pub expr: Box<Expr>,
@@ -255,7 +239,7 @@
             pub index: Box<Expr>,
         }),
 
-        /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
+        /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
         pub Range(ExprRange #full {
             pub attrs: Vec<Attribute>,
             pub from: Option<Box<Expr>>,
@@ -263,18 +247,17 @@
             pub to: Option<Box<Expr>>,
         }),
 
-        /// Variable reference, possibly containing `::` and/or type
-        /// parameters, e.g. foo::bar::<baz>.
+        /// A path like `std::mem::replace` possibly containing generic
+        /// parameters and a qualified self-type.
         ///
-        /// Optionally "qualified",
-        /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
+        /// A plain identifier like `x` is a path of length 1.
         pub Path(ExprPath {
             pub attrs: Vec<Attribute>,
             pub qself: Option<QSelf>,
             pub path: Path,
         }),
 
-        /// A referencing operation (`&a` or `&mut a`)
+        /// A referencing operation: `&a` or `&mut a`.
         pub AddrOf(ExprAddrOf #full {
             pub attrs: Vec<Attribute>,
             pub and_token: Token![&],
@@ -282,7 +265,8 @@
             pub expr: Box<Expr>,
         }),
 
-        /// A `break`, with an optional label to break, and an optional expression
+        /// A `break`, with an optional label to break and an optional
+        /// expression.
         pub Break(ExprBreak #full {
             pub attrs: Vec<Attribute>,
             pub break_token: Token![break],
@@ -290,30 +274,30 @@
             pub expr: Option<Box<Expr>>,
         }),
 
-        /// A `continue`, with an optional label
+        /// A `continue`, with an optional label.
         pub Continue(ExprContinue #full {
             pub attrs: Vec<Attribute>,
             pub continue_token: Token![continue],
             pub label: Option<Lifetime>,
         }),
 
-        /// A `return`, with an optional value to be returned
+        /// A `return`, with an optional value to be returned.
         pub Return(ExprReturn #full {
             pub attrs: Vec<Attribute>,
             pub return_token: Token![return],
             pub expr: Option<Box<Expr>>,
         }),
 
-        /// A macro invocation; pre-expansion
+        /// A macro invocation expression: `format!("{}", q)`.
         pub Macro(ExprMacro #full {
             pub attrs: Vec<Attribute>,
             pub mac: Macro,
         }),
 
-        /// A struct literal expression.
+        /// A struct literal expression: `Point { x: 1, y: 1 }`.
         ///
-        /// For example, `Foo {x: 1, y: 2}`, or
-        /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
+        /// The `rest` provides the value of the remaining fields as in `S { a:
+        /// 1, b: 1, ..rest }`.
         pub Struct(ExprStruct #full {
             pub attrs: Vec<Attribute>,
             pub path: Path,
@@ -323,10 +307,7 @@
             pub rest: Option<Box<Expr>>,
         }),
 
-        /// An array literal constructed from one repeated element.
-        ///
-        /// For example, `[1; 5]`. The first expression is the element
-        /// to be repeated; the second is the number of times to repeat it.
+        /// An array literal constructed from one repeated element: `[0u8; N]`.
         pub Repeat(ExprRepeat #full {
             pub attrs: Vec<Attribute>,
             pub bracket_token: token::Bracket,
@@ -335,34 +316,32 @@
             pub amt: Box<Expr>,
         }),
 
-        /// No-op: used solely so we can pretty-print faithfully
+        /// A parenthesized expression: `(a + b)`.
         pub Paren(ExprParen #full {
             pub attrs: Vec<Attribute>,
             pub paren_token: token::Paren,
             pub expr: Box<Expr>,
         }),
 
-        /// No-op: used solely so we can pretty-print faithfully
+        /// An expression contained within invisible delimiters.
         ///
-        /// A `group` represents a `None`-delimited span in the input
-        /// `TokenStream` which affects the precidence of the resulting
-        /// expression. They are used for macro hygiene.
+        /// This variant is important for faithfully representing the precedence
+        /// of expressions and is related to `None`-delimited spans in a
+        /// `TokenStream`.
         pub Group(ExprGroup #full {
             pub attrs: Vec<Attribute>,
             pub group_token: token::Group,
             pub expr: Box<Expr>,
         }),
 
-        /// `expr?`
+        /// A try-expression: `expr?`.
         pub Try(ExprTry #full {
             pub attrs: Vec<Attribute>,
             pub expr: Box<Expr>,
             pub question_token: Token![?],
         }),
 
-        /// A catch expression.
-        ///
-        /// E.g. `do catch { block }`
+        /// A catch expression: `do catch { ... }`.
         pub Catch(ExprCatch #full {
             pub attrs: Vec<Attribute>,
             pub do_token: Token![do],
@@ -370,15 +349,14 @@
             pub block: Block,
         }),
 
-        /// A yield expression.
-        ///
-        /// E.g. `yield expr`
+        /// A yield expression: `yield expr`.
         pub Yield(ExprYield #full {
             pub attrs: Vec<Attribute>,
             pub yield_token: Token![yield],
             pub expr: Option<Box<Expr>>,
         }),
 
+        /// Tokens in expression position not interpreted by Syn.
         pub Verbatim(ExprVerbatim #manual_extra_traits {
             pub tts: TokenStream,
         }),
@@ -506,6 +484,8 @@
 
 #[cfg(feature = "full")]
 ast_struct! {
+    /// The `::<>` explicit type parameters passed to a method call:
+    /// `parse::<u64>()`.
     pub struct MethodTurbofish {
         pub colon2_token: Token![::],
         pub lt_token: Token![<],
@@ -516,11 +496,11 @@
 
 #[cfg(feature = "full")]
 ast_enum! {
-    /// A individual generic argument like `T`.
+    /// An individual generic argument to a method, like `T`.
     pub enum GenericMethodArgument {
-        /// The type parameters for this path segment, if present.
+        /// A type argument.
         Type(Type),
-        /// Const expression. Must be inside of a block.
+        /// A const expression. Must be inside of a block.
         ///
         /// NOTE: Identity expressions are represented as Type arguments, as
         /// they are indistinguishable syntactically.
@@ -549,6 +529,7 @@
 
 #[cfg(feature = "full")]
 ast_struct! {
+    /// A lifetime labeling a `for`, `while`, or `loop`.
     pub struct Label {
         pub name: Lifetime,
         pub colon_token: Token![:],
@@ -557,9 +538,7 @@
 
 #[cfg(feature = "full")]
 ast_struct! {
-    /// A Block (`{ .. }`).
-    ///
-    /// E.g. `{ .. }` as in `fn foo() { .. }`
+    /// A braced block containing Rust statements.
     pub struct Block {
         pub brace_token: token::Brace,
         /// Statements in a block
@@ -580,20 +559,19 @@
         /// Expr without trailing semicolon.
         Expr(Expr),
 
-        /// Expression with trailing semicolon;
+        /// Expression with trailing semicolon.
         Semi(Expr, Token![;]),
     }
 }
 
 #[cfg(feature = "full")]
 ast_struct! {
-    /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
+    /// A local `let` binding: `let x: u64 = s.parse()?`.
     pub struct Local {
         pub attrs: Vec<Attribute>,
         pub let_token: Token![let],
         pub pat: Box<Pat>,
         pub ty: Option<(Token![:], Box<Type>)>,
-        /// Initializer expression to set the value, if any
         pub init: Option<(Token![=], Box<Expr>)>,
         pub semi_token: Token![;],
     }
@@ -601,19 +579,18 @@
 
 #[cfg(feature = "full")]
 ast_enum_of_structs! {
+    /// A pattern in a local binding, function signature, match expression, or
+    /// various other places.
     // Clippy false positive
     // https://github.com/Manishearth/rust-clippy/issues/1241
     #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
     pub enum Pat {
-        /// Represents a wildcard pattern (`_`)
+        /// A pattern that matches any value: `_`.
         pub Wild(PatWild {
             pub underscore_token: Token![_],
         }),
 
-        /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
-        /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
-        /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
-        /// during name resolution.
+        /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
         pub Ident(PatIdent {
             pub by_ref: Option<Token![ref]>,
             pub mutability: Option<Token![mut]>,
@@ -621,8 +598,7 @@
             pub subpat: Option<(Token![@], Box<Pat>)>,
         }),
 
-        /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
-        /// The `bool` is `true` in the presence of a `..`.
+        /// A struct or struct variant pattern: `Variant { x, y, .. }`.
         pub Struct(PatStruct {
             pub path: Path,
             pub brace_token: token::Brace,
@@ -630,26 +606,25 @@
             pub dot2_token: Option<Token![..]>,
         }),
 
-        /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
-        /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
-        /// 0 <= position <= subpats.len()
+        /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
         pub TupleStruct(PatTupleStruct {
             pub path: Path,
             pub pat: PatTuple,
         }),
 
-        /// A possibly qualified path pattern.
-        /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
-        /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
-        /// only legally refer to associated constants.
+        /// A path pattern like `Color::Red`, optionally qualified with a
+        /// self-type.
+        ///
+        /// Unquailfied path patterns can legally refer to variants, structs,
+        /// constants or associated constants. Quailfied path patterns like
+        /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
+        /// associated constants.
         pub Path(PatPath {
             pub qself: Option<QSelf>,
             pub path: Path,
         }),
 
-        /// A tuple pattern `(a, b)`.
-        /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
-        /// 0 <= position <= subpats.len()
+        /// A tuple pattern: `(a, b)`.
         pub Tuple(PatTuple {
             pub paren_token: token::Paren,
             pub front: Punctuated<Pat, Token![,]>,
@@ -657,28 +632,36 @@
             pub comma_token: Option<Token![,]>,
             pub back: Punctuated<Pat, Token![,]>,
         }),
-        /// A `box` pattern
+
+        /// A box pattern: `box v`.
         pub Box(PatBox {
             pub box_token: Token![box],
             pub pat: Box<Pat>,
         }),
-        /// A reference pattern, e.g. `&mut (a, b)`
+
+        /// A reference pattern: `&mut (first, second)`.
         pub Ref(PatRef {
             pub and_token: Token![&],
             pub mutability: Option<Token![mut]>,
             pub pat: Box<Pat>,
         }),
-        /// A literal
+
+        /// A literal pattern: `0`.
+        ///
+        /// This holds an `Expr` rather than a `Lit` because negative numbers
+        /// are represented as an `Expr::Unary`.
         pub Lit(PatLit {
             pub expr: Box<Expr>,
         }),
-        /// A range pattern, e.g. `1..=2`
+
+        /// A range pattern: `1..=2`.
         pub Range(PatRange {
             pub lo: Box<Expr>,
             pub limits: RangeLimits,
             pub hi: Box<Expr>,
         }),
-        /// `[a, b, i.., y, z]` is represented as:
+
+        /// A dynamically sized slice pattern: `[a, b, i.., y, z]`.
         pub Slice(PatSlice {
             pub bracket_token: token::Bracket,
             pub front: Punctuated<Pat, Token![,]>,
@@ -687,10 +670,13 @@
             pub comma_token: Option<Token![,]>,
             pub back: Punctuated<Pat, Token![,]>,
         }),
-        /// A macro pattern; pre-expansion
+
+        /// A macro in expression position.
         pub Macro(PatMacro {
             pub mac: Macro,
         }),
+
+        /// Tokens in pattern position not interpreted by Syn.
         pub Verbatim(PatVerbatim #manual_extra_traits {
             pub tts: TokenStream,
         }),
@@ -719,20 +705,21 @@
 
 #[cfg(feature = "full")]
 ast_struct! {
-    /// An arm of a 'match'.
+    /// One arm of a `match` expression: `0...10 => { return true; }`.
     ///
-    /// E.g. `0..=10 => { println!("match!") }` as in
+    /// As in:
     ///
     /// ```rust
-    /// # #![feature(dotdoteq_in_patterns)]
-    /// #
-    /// # fn main() {
+    /// # fn f() -> bool {
     /// #     let n = 0;
     /// match n {
-    ///     0..=10 => { println!("match!") }
-    ///     // ..
+    ///     0...10 => {
+    ///         return true;
+    ///     }
+    ///     // ...
     ///     # _ => {}
     /// }
+    /// #   false
     /// # }
     /// ```
     pub struct Arm {
@@ -747,29 +734,26 @@
 
 #[cfg(feature = "full")]
 ast_enum! {
-    /// Limit types of a range (inclusive or exclusive)
+    /// Limit types of a range, inclusive or exclusive.
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum RangeLimits {
-        /// Inclusive at the beginning, exclusive at the end
+        /// Inclusive at the beginning, exclusive at the end.
         HalfOpen(Token![..]),
-        /// Inclusive at the beginning and end
+        /// Inclusive at the beginning and end.
         Closed(Token![..=]),
     }
 }
 
 #[cfg(feature = "full")]
 ast_struct! {
-    /// A single field in a struct pattern
+    /// A single field in a struct pattern.
     ///
-    /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
-    /// are treated the same as `x: x, y: ref y, z: ref mut z` but
-    /// there is no colon token.
+    /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
+    /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
     pub struct FieldPat {
         pub attrs: Vec<Attribute>,
-        /// The identifier for the field
         pub member: Member,
         pub colon_token: Option<Token![:]>,
-        /// The pattern the field is destructured to
         pub pat: Box<Pat>,
     }
 }
@@ -1305,7 +1289,7 @@
         (e)
     ));
 
-    // Parse all atomic expressions which don't have to worry about precidence
+    // Parse all atomic expressions which don't have to worry about precedence
     // interactions, as they are fully contained.
     #[cfg(feature = "full")]
     named!(atom_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(