diff --git a/tests/common/mod.rs b/tests/common/mod.rs
new file mode 100644
index 0000000..fcb8c61
--- /dev/null
+++ b/tests/common/mod.rs
@@ -0,0 +1,85 @@
+extern crate walkdir;
+
+use walkdir::DirEntry;
+use std::env;
+use std::u32;
+
+macro_rules! errorf {
+    ($($tt:tt)*) => {
+        {
+            use ::std::io::Write;
+            write!(::std::io::stderr(), $($tt)*).unwrap();
+        }
+    };
+}
+
+pub mod parse;
+pub mod respan;
+
+pub fn check_min_stack() {
+    let min_stack_value = env::var("RUST_MIN_STACK")
+        .expect("RUST_MIN_STACK env var should be set since some tests require it.");
+    let min_stack_value: usize = min_stack_value.parse()
+        .expect("RUST_MIN_STACK env var should be set since some tests require it.");
+    assert!(min_stack_value >= 16000000);
+}
+
+/// Read the `ABORT_AFTER_FAILURE` environment variable, and parse it.
+pub fn abort_after() -> u32 {
+    if let Ok(s) = env::var("ABORT_AFTER_FAILURE") {
+        if let Ok(n) = s.parse::<u32>() {
+            return n;
+        }
+    }
+    u32::MAX
+}
+
+pub fn base_dir_filter(entry: &DirEntry) -> bool {
+    let path = entry.path();
+    if path.is_dir() {
+        return true; // otherwise walkdir does not visit the files
+    }
+    if path.extension().map(|e| e != "rs").unwrap_or(true) {
+        return false;
+    }
+    let path_string = path.to_string_lossy();
+    let path_string = if cfg!(windows) {
+        path_string.replace('\\', "/").into()
+    } else {
+        path_string
+    };
+    // TODO assert that parsing fails on the parse-fail cases
+    if path_string.starts_with("tests/rust/src/test/parse-fail") ||
+       path_string.starts_with("tests/rust/src/test/compile-fail") {
+        return false;
+    }
+
+    if path_string.starts_with("tests/rust/src/test/ui") {
+        let stderr_path = path.with_extension("stderr");
+        if stderr_path.exists() {
+            // Expected to fail in some way
+            return false;
+        }
+    }
+
+    match path_string.as_ref() {
+        // TODO better support for attributes
+        "tests/rust/src/librustc_data_structures/blake2b.rs" |
+        // TODO better support for attributes
+        "tests/rust/src/test/incremental/hashes/enum_defs.rs" |
+        // TODO better support for attributes
+        "tests/rust/src/test/pretty/stmt_expr_attributes.rs" |
+        // not actually a test case
+        "tests/rust/src/test/run-pass/auxiliary/macro-include-items-expr.rs" |
+        // TODO better support for attributes
+        "tests/rust/src/test/run-pass/cfg_stmt_expr.rs" |
+        // TODO weird glob import
+        "tests/rust/src/test/run-pass/import-glob-crate.rs" |
+        // TODO better support for attributes
+        "tests/rust/src/test/run-pass/inner-attrs-on-impl.rs" |
+        // TODO better support for attributes
+        "tests/rust/src/test/run-pass/item-attributes.rs" => false,
+        _ => true,
+    }
+}
+
diff --git a/tests/common/parse.rs b/tests/common/parse.rs
new file mode 100644
index 0000000..15c2faf
--- /dev/null
+++ b/tests/common/parse.rs
@@ -0,0 +1,47 @@
+extern crate syn;
+extern crate syntex_syntax;
+
+use self::syntex_syntax::ast;
+use self::syntex_syntax::ptr::P;
+use self::syntex_syntax::parse::{self, ParseSess};
+use self::syntex_syntax::codemap::FilePathMapping;
+
+use std::panic;
+
+pub fn syntex_expr(input: &str) -> Option<P<ast::Expr>> {
+    match panic::catch_unwind(|| {
+        let sess = ParseSess::new(FilePathMapping::empty());
+        sess.span_diagnostic.set_continue_after_error(false);
+        let e = parse::parse_expr_from_source_str(
+            "test_precedence".to_string(),
+            input.to_string(),
+            &sess,
+        );
+        Some(match e {
+            Ok(expr) => expr,
+            Err(mut diagnostic) => {
+                diagnostic.emit();;
+                return None
+            }
+        })
+    }) {
+        Ok(Some(e)) => Some(e),
+        Ok(None) => {
+            None
+        }
+        Err(_) => {
+            errorf!("syntex paniced\n");
+            None
+        }
+    }
+}
+
+pub fn syn_expr(input: &str) -> Option<syn::Expr> {
+    match input.parse::<syn::Expr>() {
+        Ok(e) => Some(e),
+        Err(msg) => {
+            errorf!("syn failed to parse\n{:?}\n", msg);
+            None
+        }
+    }
+}
diff --git a/tests/common/respan.rs b/tests/common/respan.rs
new file mode 100644
index 0000000..c9d12f5
--- /dev/null
+++ b/tests/common/respan.rs
@@ -0,0 +1,245 @@
+use std::rc::Rc;
+use syntex_syntax::ast::{Attribute, Expr, ExprKind, Field, FnDecl, FunctionRetTy, ImplItem,
+                         ImplItemKind, ItemKind, Mac, MetaItem, MetaItemKind, MethodSig,
+                         NestedMetaItem, NestedMetaItemKind, TraitItem, TraitItemKind, TyParam,
+                         Visibility};
+use syntex_syntax::codemap::{self, Spanned};
+use syntex_syntax::fold::{self, Folder};
+use syntex_syntax::parse::token::{Lit, Token};
+use syntex_syntax::ptr::P;
+use syntex_syntax::symbol::Symbol;
+use syntex_syntax::tokenstream::{Delimited, TokenTree};
+use syntex_syntax::util::move_map::MoveMap;
+use syntex_syntax::util::small_vector::SmallVector;
+
+use syntex_pos::{Span, DUMMY_SP};
+use syntex_syntax::ast;
+
+struct Respanner;
+
+impl Respanner {
+    fn fold_spanned<T>(&mut self, spanned: Spanned<T>) -> Spanned<T> {
+        codemap::respan(self.new_span(spanned.span), spanned.node)
+    }
+
+    fn fold_lit(&mut self, l: Lit) -> Lit {
+        // Give up on comparing literals inside of macros because there are
+        // so many equivalent representations of the same literal; they are
+        // tested elsewhere
+        match l {
+            Lit::Byte(_) => Lit::Byte(Symbol::intern("")),
+            Lit::Char(_) => Lit::Char(Symbol::intern("")),
+            Lit::Integer(_) => Lit::Integer(Symbol::intern("")),
+            Lit::Float(_) => Lit::Float(Symbol::intern("")),
+            Lit::Str_(_) => Lit::Str_(Symbol::intern("")),
+            Lit::ByteStr(_) => Lit::ByteStr(Symbol::intern("")),
+            _ => l,
+        }
+    }
+}
+
+impl Folder for Respanner {
+    fn new_span(&mut self, _: Span) -> Span {
+        DUMMY_SP
+    }
+
+    fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind {
+        match i {
+            ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => {
+                let generics = self.fold_generics(generics);
+                let decl = self.fold_fn_decl(decl);
+                let body = self.fold_block(body);
+                // default fold_item_kind does not fold this span
+                let constness = self.fold_spanned(constness);
+                ItemKind::Fn(decl, unsafety, constness, abi, generics, body)
+            }
+            _ => fold::noop_fold_item_kind(i, self),
+        }
+    }
+
+    fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
+        e.map(|e| {
+            let folded = fold::noop_fold_expr(e, self);
+            Expr {
+                node: match folded.node {
+                    ExprKind::Lit(l) => {
+                        // default fold_expr does not fold lits
+                        ExprKind::Lit(l.map(|l| self.fold_spanned(l)))
+                    }
+                    ExprKind::Binary(op, lhs, rhs) => {
+                        // default fold_expr does not fold the op span
+                        ExprKind::Binary(self.fold_spanned(op),
+                                            self.fold_expr(lhs),
+                                            self.fold_expr(rhs))
+                    }
+                    ExprKind::AssignOp(op, lhs, rhs) => {
+                        // default fold_expr does not fold the op span
+                        ExprKind::AssignOp(self.fold_spanned(op),
+                                            self.fold_expr(lhs),
+                                            self.fold_expr(rhs))
+                    }
+                    other => other,
+                },
+                ..folded
+            }
+        })
+    }
+
+    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_fn_decl(&mut self, decl: P<FnDecl>) -> P<FnDecl> {
+        decl.map(|FnDecl { inputs, output, variadic }| {
+            FnDecl {
+                inputs: inputs.move_map(|x| self.fold_arg(x)),
+                output: match output {
+                    FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(self.fold_ty(ty)),
+                    // default fold_fn_decl does not fold this span
+                    FunctionRetTy::Default(span) => FunctionRetTy::Default(self.new_span(span)),
+                },
+                variadic: variadic,
+            }
+        })
+    }
+
+    fn fold_field(&mut self, field: Field) -> Field {
+        Field {
+            ident: codemap::respan(// default fold_field does not fold this span
+                                    self.new_span(field.ident.span),
+                                    self.fold_ident(field.ident.node)),
+            expr: self.fold_expr(field.expr),
+            span: self.new_span(field.span),
+            is_shorthand: field.is_shorthand,
+            attrs: ast::ThinVec::new(),
+        }
+    }
+
+    fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> {
+        let noop = fold::noop_fold_trait_item(i, self).expect_one("");
+        SmallVector::one(TraitItem {
+                                node: match noop.node {
+                                    TraitItemKind::Method(sig, body) => {
+                    TraitItemKind::Method(MethodSig {
+                                                constness: self.fold_spanned(sig.constness),
+                                                ..sig
+                                            },
+                                            body)
+                }
+                                    node => node,
+                                },
+                                ..noop
+                            })
+    }
+
+    fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> {
+        let noop = fold::noop_fold_impl_item(i, self).expect_one("");
+        SmallVector::one(ImplItem {
+                                node: match noop.node {
+                                    ImplItemKind::Method(sig, body) => {
+                    ImplItemKind::Method(MethodSig {
+                                                constness: self.fold_spanned(sig.constness),
+                                                ..sig
+                                            },
+                                            body)
+                }
+                                    node => node,
+                                },
+                                ..noop
+                            })
+    }
+
+    fn fold_attribute(&mut self, mut at: Attribute) -> Option<Attribute> {
+        at.id.0 = 0;
+        fold::noop_fold_attribute(at, self)
+    }
+
+    fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem {
+        let MetaItem { name, node, span } = meta_item;
+        MetaItem {
+            name: name,
+            node: match node {
+                MetaItemKind::Word => MetaItemKind::Word,
+                MetaItemKind::List(nested) => {
+                    MetaItemKind::List(nested.move_map(|e| self.fold_meta_list_item(e)))
+                }
+                // default fold_meta_item does not fold the value span
+                MetaItemKind::NameValue(lit) => MetaItemKind::NameValue(self.fold_spanned(lit)),
+            },
+            span: self.new_span(span),
+        }
+    }
+
+    fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem {
+        Spanned {
+            node: match list_item.node {
+                NestedMetaItemKind::MetaItem(mi) => {
+                    NestedMetaItemKind::MetaItem(self.fold_meta_item(mi))
+                }
+                // default fold_meta_list_item does not fold the span
+                NestedMetaItemKind::Literal(lit) => {
+                    NestedMetaItemKind::Literal(self.fold_spanned(lit))
+                }
+            },
+            span: self.new_span(list_item.span),
+        }
+    }
+
+    fn fold_mac(&mut self, mac: Mac) -> Mac {
+        fold::noop_fold_mac(mac, self)
+    }
+
+    fn fold_tt(&mut self, tt: TokenTree) -> TokenTree {
+        match tt {
+            TokenTree::Token(span, ref tok) => {
+                TokenTree::Token(self.new_span(span), self.fold_token(tok.clone()))
+            }
+            TokenTree::Delimited(span, ref delimed) => {
+                TokenTree::Delimited(self.new_span(span),
+                                        Delimited {
+                                            delim: delimed.delim,
+                                            tts: self.fold_tts(delimed.tts.clone().into()).into(),
+                                        })
+            }
+        }
+    }
+
+    fn fold_token(&mut self, t: Token) -> Token {
+        match t {
+            // default fold_token does not fold literals
+            Token::Literal(lit, repr) => Token::Literal(self.fold_lit(lit), repr),
+            Token::Ident(id) => Token::Ident(self.fold_ident(id)),
+            Token::Lifetime(id) => Token::Lifetime(self.fold_ident(id)),
+            Token::Interpolated(nt) => {
+                let nt = match Rc::try_unwrap(nt) {
+                    Ok(nt) => nt,
+                    Err(nt) => (*nt).clone(),
+                };
+                Token::Interpolated(Rc::new(self.fold_interpolated(nt)))
+            }
+            Token::SubstNt(ident) => Token::SubstNt(self.fold_ident(ident)),
+            _ => t,
+        }
+    }
+
+    fn fold_vis(&mut self, vis: Visibility) -> Visibility {
+        match vis {
+            Visibility::Crate(span) => Visibility::Crate(self.new_span(span)),
+            _ => fold::noop_fold_vis(vis, self),
+        }
+    }
+}
+
+#[allow(dead_code)]
+pub fn respan_crate(krate: ast::Crate) -> ast::Crate {
+    Respanner.fold_crate(krate)
+}
+
+#[allow(dead_code)]
+pub fn respan_expr(expr: P<ast::Expr>) -> P<ast::Expr> {
+    Respanner.fold_expr(expr)
+}
diff --git a/tests/test_precedence.rs b/tests/test_precedence.rs
new file mode 100644
index 0000000..a97f622
--- /dev/null
+++ b/tests/test_precedence.rs
@@ -0,0 +1,378 @@
+#![cfg(all(feature = "full", feature = "fold"))]
+
+//! The tests in this module do the following:
+//!
+//! 1. Parse a given expression in both `syn` and `syntex`.
+//! 2. Fold over the expression adding brackets around each subexpression (with
+//!    some complications - see the `syn_brackets` and `syntex_brackets`
+//!    methods).
+//! 3. Serialize the `syn` expression back into a string, and re-parse it with
+//!    `syntex`.
+//! 4. Respan all of the expressions, replacing the spans with the default spans.
+//! 5. Compare the expressions with one another, if they are not equal fail.
+
+#[macro_use]
+extern crate quote;
+extern crate syn;
+extern crate synom;
+extern crate syntex_pos;
+extern crate syntex_syntax;
+extern crate walkdir;
+extern crate proc_macro2;
+
+use syntex_syntax::ast;
+use syntex_syntax::ptr::P;
+
+use common::{respan, parse};
+
+#[allow(dead_code)]
+#[macro_use]
+mod common;
+
+/// Test some pre-set expressions chosen by us.
+#[test]
+fn test_simple_precedence() {
+    const EXPRS: &[&str] = &[
+        "1 + 2 * 3 + 4",
+        "1 + 2 * ( 3 + 4 )",
+        "{ for i in r { } *some_ptr += 1; }",
+        "{ loop { break 5; } }",
+        "{ if true { () }.mthd() }",
+    ];
+
+    let mut failed = 0;
+
+    for input in EXPRS {
+        let expr = if let Some(expr) = parse::syn_expr(input) {
+            expr
+        } else {
+            failed += 1;
+            continue;
+        };
+
+        let pf = match test_expressions(vec![expr]) {
+            (1, 0) => "passed",
+            (0, 1) => {
+                failed += 1;
+                "failed"
+            }
+            _ => unreachable!(),
+        };
+        errorf!("=== {}: {}\n", input, pf);
+    }
+
+    if failed > 0 {
+        panic!("Failed {} tests", failed);
+    }
+}
+
+/// Test expressions from rustc, like in `test_round_trip`.
+#[test]
+fn test_rustc_precedence() {
+    use walkdir::{WalkDir, WalkDirIterator};
+    use std::fs::File;
+    use std::io::Read;
+
+    common::check_min_stack();
+    let abort_after = common::abort_after();
+    if abort_after == 0 {
+        panic!("Skipping all precedence tests");
+    }
+
+    let mut passed = 0;
+    let mut failed = 0;
+
+    let walk = WalkDir::new("tests/rust").sort_by(|a, b| a.cmp(b));
+    for entry in walk.into_iter().filter_entry(common::base_dir_filter) {
+        let entry = entry.unwrap();
+
+        let path = entry.path();
+        if path.is_dir() {
+            continue;
+        }
+
+        let mut file = File::open(path).unwrap();
+        let mut content = String::new();
+        file.read_to_string(&mut content).unwrap();
+
+        let (l_passed, l_failed) = match content.parse::<syn::Crate>() {
+            Ok(krate) => {
+                let exprs = collect_exprs(krate);
+                test_expressions(exprs)
+            }
+            Err(msg) => {
+                errorf!("syn failed to parse\n{:?}\n", msg);
+                failed += 1;
+                (0, 1)
+            }
+        };
+
+        passed += l_passed;
+        failed += l_failed;
+
+        errorf!("=== {}: {} passed | {} failed\n", path.display(), l_passed, l_failed);
+
+        if failed >= abort_after {
+            errorf!("Aborting Immediately due to ABORT_AFTER_FAILURE\n");
+            break;
+        }
+    }
+
+    errorf!("\n===== Precedence Test Results =====\n");
+    errorf!("{} passed | {} failed\n", passed, failed);
+
+
+    if failed > 0 {
+        panic!("{} failures", failed);
+    }
+}
+
+fn test_expressions(exprs: Vec<syn::Expr>) -> (u32, u32) {
+    let mut passed = 0;
+    let mut failed = 0;
+
+    for expr in exprs {
+        let raw = quote!(#expr).to_string();
+
+        let syntex_ast = if let Some(e) = syntex_parse_and_rewrite(&raw) {
+            e
+        } else {
+            failed += 1;
+            errorf!("\nFAIL - syntex failed to parse raw\n");
+            continue;
+        };
+
+        let syn_expr = syn_brackets(expr);
+        let syn_ast = if let Some(e) = parse::syntex_expr(&quote!(#syn_expr).to_string()) {
+            e
+        } else {
+            failed += 1;
+            errorf!("\nFAIL - syntex failed to parse bracketed\n");
+            continue;
+        };
+
+        let syn_ast = respan::respan_expr(syn_ast);
+        let syntex_ast = respan::respan_expr(syntex_ast);
+
+        if syn_ast == syntex_ast {
+            passed += 1;
+        } else {
+            failed += 1;
+            errorf!("\nFAIL\n{:?}\n!=\n{:?}\n", syn_ast, syntex_ast);
+        }
+    }
+
+    (passed, failed)
+}
+
+fn syntex_parse_and_rewrite(input: &str) -> Option<P<ast::Expr>> {
+    parse::syntex_expr(input).and_then(|e| syntex_brackets(e))
+}
+
+/// Wrap every expression which is not already wrapped in parens with parens, to
+/// reveal the precidence of the parsed expressions, and produce a stringified form
+/// of the resulting expression.
+///
+/// This method operates on syntex objects.
+fn syntex_brackets(syntex_expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
+    use syntex_syntax::ast::{Expr, ExprKind, Mac, Stmt, StmtKind, Pat, Ty, Field};
+    use syntex_syntax::fold::{self, Folder};
+    use syntex_syntax::util::ThinVec;
+    use syntex_syntax::util::small_vector::SmallVector;
+    use syntex_syntax::ext::quote::rt::DUMMY_SP;
+    use syntex_syntax::codemap;
+
+    fn expr(node: ExprKind) -> P<Expr> {
+        P(Expr {
+            id: ast::DUMMY_NODE_ID,
+            node: node,
+            span: DUMMY_SP,
+            attrs: ThinVec::new(),
+        })
+    }
+
+    struct BracketsFolder {
+        failed: bool,
+    };
+    impl Folder for BracketsFolder {
+        fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
+            e.map(|e| {
+                Expr {
+                    node: match e.node {
+                        ExprKind::Paren(inner) => {
+                            ExprKind::Paren(inner.map(|e| {
+                                fold::noop_fold_expr(e, self)
+                            }))
+                        }
+                        ExprKind::If(..) |
+                        ExprKind::Block(..) |
+                        ExprKind::IfLet(..) => {
+                            return fold::noop_fold_expr(e, self);
+                        }
+                        node => {
+                            ExprKind::Paren(expr(node).map(|e| {
+                                fold::noop_fold_expr(e, self)
+                            }))
+                        }
+                    },
+                    ..e
+                }
+            })
+        }
+
+        fn fold_field(&mut self, f: Field) -> Field {
+            Field {
+                ident: codemap::respan(f.ident.span, self.fold_ident(f.ident.node)),
+                expr: if f.is_shorthand {
+                    f.expr.map(|e| fold::noop_fold_expr(e, self))
+                } else {
+                    self.fold_expr(f.expr)
+                },
+                span: self.new_span(f.span),
+                is_shorthand: f.is_shorthand,
+                attrs: fold::fold_thin_attrs(f.attrs, self),
+            }
+        }
+
+        // We don't want to look at expressions that might appear in patterns or
+        // types yet. We'll look into comparing those in the future. For now
+        // focus on expressions appearing in other places.
+        fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
+            pat
+        }
+
+        fn fold_ty(&mut self, ty: P<Ty>) -> P<Ty> {
+            ty
+        }
+
+        fn fold_stmt(&mut self, stmt: Stmt) -> SmallVector<Stmt> {
+            let node = match stmt.node {
+                // Don't wrap toplevel expressions in statements.
+                StmtKind::Expr(e) => {
+                    StmtKind::Expr(e.map(|e| fold::noop_fold_expr(e, self)))
+                }
+                StmtKind::Semi(e) => {
+                    StmtKind::Semi(e.map(|e| fold::noop_fold_expr(e, self)))
+                }
+                s => s,
+            };
+
+            SmallVector::one(Stmt {
+                node: node,
+                ..stmt
+            })
+        }
+
+        fn fold_mac(&mut self, mac: Mac) -> Mac {
+            // By default when folding over macros, syntex panics. This is
+            // because it's usually not what you want, you want to run after
+            // macro expansion. We do want to do that (syn doesn't do macro
+            // expansion), so we implement fold_mac to just return the macro
+            // unchanged.
+            mac
+        }
+    }
+
+    let mut folder = BracketsFolder {
+        failed: false,
+    };
+    let e = folder.fold_expr(syntex_expr);
+    if folder.failed {
+        None
+    } else {
+        Some(e)
+    }
+}
+
+/// Wrap every expression which is not already wrapped in parens with parens, to
+/// reveal the precidence of the parsed expressions, and produce a stringified form
+/// of the resulting expression.
+fn syn_brackets(syn_expr: syn::Expr) -> syn::Expr {
+    use syn::*;
+    use syn::fold::*;
+
+    fn paren(folder: &mut BracketsFolder, node: ExprKind) -> ExprKind {
+        ExprKind::Paren(ExprParen {
+            expr: Box::new(noop_fold_expr(folder, Expr {
+                node: node,
+                attrs: vec![],
+            })),
+            paren_token: tokens::Paren::default(),
+        })
+    }
+
+    struct BracketsFolder;
+    impl Folder for BracketsFolder {
+        fn fold_expr(&mut self, expr: Expr) -> Expr {
+            let kind = match expr.node {
+                ExprKind::Group(_) => unreachable!(),
+                ExprKind::Paren(p) => paren(self, p.expr.node),
+                ExprKind::If(..) |
+                ExprKind::Block(..) |
+                ExprKind::IfLet(..) => {
+                    return noop_fold_expr(self, expr);
+                }
+                node => paren(self, node),
+            };
+
+            Expr {
+                node: kind,
+                ..expr
+            }
+        }
+
+        fn fold_stmt(&mut self, stmt: Stmt) -> Stmt {
+            match stmt {
+                // Don't wrap toplevel expressions in statements.
+                Stmt::Expr(e) => {
+                    Stmt::Expr(Box::new(noop_fold_expr(self, *e)))
+                }
+                Stmt::Semi(e, semi) => {
+                    Stmt::Semi(Box::new(noop_fold_expr(self, *e)), semi)
+                }
+                s => s,
+            }
+        }
+
+        // We don't want to look at expressions that might appear in patterns or
+        // types yet. We'll look into comparing those in the future. For now
+        // focus on expressions appearing in other places.
+        fn fold_pat(&mut self, pat: Pat) -> Pat {
+            pat
+        }
+
+        fn fold_ty(&mut self, ty: Ty) -> Ty {
+            ty
+        }
+    }
+
+    let mut folder = BracketsFolder;
+    folder.fold_expr(syn_expr)
+}
+
+/// Walk through a crate collecting all expressions we can find in it.
+fn collect_exprs(krate: syn::Crate) -> Vec<syn::Expr> {
+    use synom::delimited::Delimited;
+    use syn::*;
+    use syn::fold::*;
+
+    struct CollectExprsFolder(Vec<Expr>);
+    impl Folder for CollectExprsFolder {
+        fn fold_expr(&mut self, expr: Expr) -> Expr {
+            self.0.push(expr);
+
+            Expr {
+                node: ExprKind::Tup(ExprTup {
+                    args: Delimited::new(),
+                    paren_token: tokens::Paren::default(),
+                    lone_comma: None
+                }),
+                attrs: vec![],
+            }
+        }
+    }
+
+    let mut folder = CollectExprsFolder(vec![]);
+    folder.fold_crate(krate);
+    folder.0
+}
