diff --git a/src/test/compile-fail/macro-follow.rs b/src/test/compile-fail/macro-follow.rs
new file mode 100644
index 00000000000..35944bada4d
--- /dev/null
+++ b/src/test/compile-fail/macro-follow.rs
@@ -0,0 +1,122 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// Check the macro follow sets (see corresponding rpass test).
+
+// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), Ident(in)}
+macro_rules! follow_pat {
+    ($p:pat ()) => {};       //~WARN  `$p:pat` is followed by `(`
+    ($p:pat []) => {};       //~WARN  `$p:pat` is followed by `[`
+    ($p:pat {}) => {};       //~WARN  `$p:pat` is followed by `{`
+    ($p:pat :) => {};        //~ERROR `$p:pat` is followed by `:`
+    ($p:pat >) => {};        //~ERROR `$p:pat` is followed by `>`
+    ($p:pat +) => {};        //~ERROR `$p:pat` is followed by `+`
+    ($p:pat ident) => {};    //~ERROR `$p:pat` is followed by `ident`
+    ($p:pat $p:pat) => {};   //~ERROR `$p:pat` is followed by `$p:pat`
+    ($p:pat $e:expr) => {};  //~ERROR `$p:pat` is followed by `$e:expr`
+    ($p:pat $t:ty) => {};    //~ERROR `$p:pat` is followed by `$t:ty`
+    ($p:pat $s:stmt) => {};  //~ERROR `$p:pat` is followed by `$s:stmt`
+    ($p:pat $p:path) => {};  //~ERROR `$p:pat` is followed by `$p:path`
+    ($p:pat $b:block) => {}; //~ERROR `$p:pat` is followed by `$b:block`
+    ($p:pat $i:ident) => {}; //~ERROR `$p:pat` is followed by `$i:ident`
+    ($p:pat $t:tt) => {};    //~ERROR `$p:pat` is followed by `$t:tt`
+    ($p:pat $i:item) => {};  //~ERROR `$p:pat` is followed by `$i:item`
+    ($p:pat $m:meta) => {};  //~ERROR `$p:pat` is followed by `$m:meta`
+}
+// FOLLOW(expr) = {FatArrow, Comma, Semicolon}
+macro_rules! follow_expr {
+    ($e:expr ()) => {};       //~WARN  `$e:expr` is followed by `(`
+    ($e:expr []) => {};       //~WARN  `$e:expr` is followed by `[`
+    ($e:expr {}) => {};       //~WARN  `$e:expr` is followed by `{`
+    ($e:expr =) => {};        //~ERROR `$e:expr` is followed by `=`
+    ($e:expr |) => {};        //~ERROR `$e:expr` is followed by `|`
+    ($e:expr :) => {};        //~ERROR `$e:expr` is followed by `:`
+    ($e:expr >) => {};        //~ERROR `$e:expr` is followed by `>`
+    ($e:expr +) => {};        //~ERROR `$e:expr` is followed by `+`
+    ($e:expr ident) => {};    //~ERROR `$e:expr` is followed by `ident`
+    ($e:expr if) => {};       //~ERROR `$e:expr` is followed by `if`
+    ($e:expr in) => {};       //~ERROR `$e:expr` is followed by `in`
+    ($e:expr $p:pat) => {};   //~ERROR `$e:expr` is followed by `$p:pat`
+    ($e:expr $e:expr) => {};  //~ERROR `$e:expr` is followed by `$e:expr`
+    ($e:expr $t:ty) => {};    //~ERROR `$e:expr` is followed by `$t:ty`
+    ($e:expr $s:stmt) => {};  //~ERROR `$e:expr` is followed by `$s:stmt`
+    ($e:expr $p:path) => {};  //~ERROR `$e:expr` is followed by `$p:path`
+    ($e:expr $b:block) => {}; //~ERROR `$e:expr` is followed by `$b:block`
+    ($e:expr $i:ident) => {}; //~ERROR `$e:expr` is followed by `$i:ident`
+    ($e:expr $t:tt) => {};    //~ERROR `$e:expr` is followed by `$t:tt`
+    ($e:expr $i:item) => {};  //~ERROR `$e:expr` is followed by `$i:item`
+    ($e:expr $m:meta) => {};  //~ERROR `$e:expr` is followed by `$m:meta`
+}
+// FOLLOW(ty) = {OpenDelim(Brace), Comma, FatArrow, Colon, Eq, Gt, Semi, Or,
+//               Ident(as), Ident(where), OpenDelim(Bracket)}
+macro_rules! follow_ty {
+    ($t:ty ()) => {};       //~WARN  `$t:ty` is followed by `(`
+    ($t:ty []) => {};       // ok (RFC 1462)
+    ($t:ty +) => {};        //~ERROR `$t:ty` is followed by `+`
+    ($t:ty ident) => {};    //~ERROR `$t:ty` is followed by `ident`
+    ($t:ty if) => {};       //~ERROR `$t:ty` is followed by `if`
+    ($t:ty $p:pat) => {};   //~ERROR `$t:ty` is followed by `$p:pat`
+    ($t:ty $e:expr) => {};  //~ERROR `$t:ty` is followed by `$e:expr`
+    ($t:ty $t:ty) => {};    //~ERROR `$t:ty` is followed by `$t:ty`
+    ($t:ty $s:stmt) => {};  //~ERROR `$t:ty` is followed by `$s:stmt`
+    ($t:ty $p:path) => {};  //~ERROR `$t:ty` is followed by `$p:path`
+    ($t:ty $b:block) => {}; //~ERROR `$t:ty` is followed by `$b:block`
+    ($t:ty $i:ident) => {}; //~ERROR `$t:ty` is followed by `$i:ident`
+    ($t:ty $t:tt) => {};    //~ERROR `$t:ty` is followed by `$t:tt`
+    ($t:ty $i:item) => {};  //~ERROR `$t:ty` is followed by `$i:item`
+    ($t:ty $m:meta) => {};  //~ERROR `$t:ty` is followed by `$m:meta`
+}
+// FOLLOW(stmt) = FOLLOW(expr)
+macro_rules! follow_stmt {
+    ($s:stmt ()) => {};       //~WARN  `$s:stmt` is followed by `(`
+    ($s:stmt []) => {};       //~WARN  `$s:stmt` is followed by `[`
+    ($s:stmt {}) => {};       //~WARN  `$s:stmt` is followed by `{`
+    ($s:stmt =) => {};        //~ERROR `$s:stmt` is followed by `=`
+    ($s:stmt |) => {};        //~ERROR `$s:stmt` is followed by `|`
+    ($s:stmt :) => {};        //~ERROR `$s:stmt` is followed by `:`
+    ($s:stmt >) => {};        //~ERROR `$s:stmt` is followed by `>`
+    ($s:stmt +) => {};        //~ERROR `$s:stmt` is followed by `+`
+    ($s:stmt ident) => {};    //~ERROR `$s:stmt` is followed by `ident`
+    ($s:stmt if) => {};       //~ERROR `$s:stmt` is followed by `if`
+    ($s:stmt in) => {};       //~ERROR `$s:stmt` is followed by `in`
+    ($s:stmt $p:pat) => {};   //~ERROR `$s:stmt` is followed by `$p:pat`
+    ($s:stmt $e:expr) => {};  //~ERROR `$s:stmt` is followed by `$e:expr`
+    ($s:stmt $t:ty) => {};    //~ERROR `$s:stmt` is followed by `$t:ty`
+    ($s:stmt $s:stmt) => {};  //~ERROR `$s:stmt` is followed by `$s:stmt`
+    ($s:stmt $p:path) => {};  //~ERROR `$s:stmt` is followed by `$p:path`
+    ($s:stmt $b:block) => {}; //~ERROR `$s:stmt` is followed by `$b:block`
+    ($s:stmt $i:ident) => {}; //~ERROR `$s:stmt` is followed by `$i:ident`
+    ($s:stmt $t:tt) => {};    //~ERROR `$s:stmt` is followed by `$t:tt`
+    ($s:stmt $i:item) => {};  //~ERROR `$s:stmt` is followed by `$i:item`
+    ($s:stmt $m:meta) => {};  //~ERROR `$s:stmt` is followed by `$m:meta`
+}
+// FOLLOW(path) = FOLLOW(ty)
+macro_rules! follow_path {
+    ($p:path ()) => {};       //~WARN  `$p:path` is followed by `(`
+    ($p:path []) => {};       // ok (RFC 1462)
+    ($p:path +) => {};        //~ERROR `$p:path` is followed by `+`
+    ($p:path ident) => {};    //~ERROR `$p:path` is followed by `ident`
+    ($p:path if) => {};       //~ERROR `$p:path` is followed by `if`
+    ($p:path $p:pat) => {};   //~ERROR `$p:path` is followed by `$p:pat`
+    ($p:path $e:expr) => {};  //~ERROR `$p:path` is followed by `$e:expr`
+    ($p:path $t:ty) => {};    //~ERROR `$p:path` is followed by `$t:ty`
+    ($p:path $s:stmt) => {};  //~ERROR `$p:path` is followed by `$s:stmt`
+    ($p:path $p:path) => {};  //~ERROR `$p:path` is followed by `$p:path`
+    ($p:path $b:block) => {}; //~ERROR `$p:path` is followed by `$b:block`
+    ($p:path $i:ident) => {}; //~ERROR `$p:path` is followed by `$i:ident`
+    ($p:path $t:tt) => {};    //~ERROR `$p:path` is followed by `$t:tt`
+    ($p:path $i:item) => {};  //~ERROR `$p:path` is followed by `$i:item`
+    ($p:path $m:meta) => {};  //~ERROR `$p:path` is followed by `$m:meta`
+}
+// FOLLOW(block) = any token
+// FOLLOW(ident) = any token
+
+fn main() {}
+
diff --git a/src/test/run-pass/macro-follow.rs b/src/test/run-pass/macro-follow.rs
new file mode 100644
index 00000000000..ce6498f67f9
--- /dev/null
+++ b/src/test/run-pass/macro-follow.rs
@@ -0,0 +1,190 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check the macro follow sets (see corresponding cfail test).
+
+// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), Ident(in)}
+macro_rules! follow_pat {
+    ($p:pat =>) => {};
+    ($p:pat ,) => {};
+    ($p:pat =) => {};
+    ($p:pat |) => {};
+    ($p:pat if) => {};
+    ($p:pat in) => {};
+}
+// FOLLOW(expr) = {FatArrow, Comma, Semicolon}
+macro_rules! follow_expr {
+    ($e:expr =>) => {};
+    ($e:expr ,) => {};
+    ($e:expr ;) => {};
+}
+// FOLLOW(ty) = {OpenDelim(Brace), Comma, FatArrow, Colon, Eq, Gt, Semi, Or,
+//               Ident(as), Ident(where), OpenDelim(Bracket)}
+macro_rules! follow_ty {
+    ($t:ty {}) => {};
+    ($t:ty ,) => {};
+    ($t:ty =>) => {};
+    ($t:ty :) => {};
+    ($t:ty =) => {};
+    ($t:ty >) => {};
+    ($t:ty ;) => {};
+    ($t:ty |) => {};
+    ($t:ty as) => {};
+    ($t:ty where) => {};
+    ($t:ty []) => {};
+}
+// FOLLOW(stmt) = FOLLOW(expr)
+macro_rules! follow_stmt {
+    ($s:stmt =>) => {};
+    ($s:stmt ,) => {};
+    ($s:stmt ;) => {};
+}
+// FOLLOW(path) = FOLLOW(ty)
+macro_rules! follow_path {
+    ($p:path {}) => {};
+    ($p:path ,) => {};
+    ($p:path =>) => {};
+    ($p:path :) => {};
+    ($p:path =) => {};
+    ($p:path >) => {};
+    ($p:path ;) => {};
+    ($p:path |) => {};
+    ($p:path as) => {};
+    ($p:path where) => {};
+    ($p:path []) => {};
+}
+// FOLLOW(block) = any token
+macro_rules! follow_block {
+    ($b:block ()) => {};
+    ($b:block []) => {};
+    ($b:block {}) => {};
+    ($b:block ,) => {};
+    ($b:block =>) => {};
+    ($b:block :) => {};
+    ($b:block =) => {};
+    ($b:block >) => {};
+    ($b:block ;) => {};
+    ($b:block |) => {};
+    ($b:block +) => {};
+    ($b:block ident) => {};
+    ($b:block $p:pat) => {};
+    ($b:block $e:expr) => {};
+    ($b:block $t:ty) => {};
+    ($b:block $s:stmt) => {};
+    ($b:block $p:path) => {};
+    ($b:block $b:block) => {};
+    ($b:block $i:ident) => {};
+    ($b:block $t:tt) => {};
+    ($b:block $i:item) => {};
+    ($b:block $m:meta) => {};
+}
+// FOLLOW(ident) = any token
+macro_rules! follow_ident {
+    ($i:ident ()) => {};
+    ($i:ident []) => {};
+    ($i:ident {}) => {};
+    ($i:ident ,) => {};
+    ($i:ident =>) => {};
+    ($i:ident :) => {};
+    ($i:ident =) => {};
+    ($i:ident >) => {};
+    ($i:ident ;) => {};
+    ($i:ident |) => {};
+    ($i:ident +) => {};
+    ($i:ident ident) => {};
+    ($i:ident $p:pat) => {};
+    ($i:ident $e:expr) => {};
+    ($i:ident $t:ty) => {};
+    ($i:ident $s:stmt) => {};
+    ($i:ident $p:path) => {};
+    ($i:ident $b:block) => {};
+    ($i:ident $i:ident) => {};
+    ($i:ident $t:tt) => {};
+    ($i:ident $i:item) => {};
+    ($i:ident $m:meta) => {};
+}
+// FOLLOW(tt) = any token
+macro_rules! follow_tt {
+    ($t:tt ()) => {};
+    ($t:tt []) => {};
+    ($t:tt {}) => {};
+    ($t:tt ,) => {};
+    ($t:tt =>) => {};
+    ($t:tt :) => {};
+    ($t:tt =) => {};
+    ($t:tt >) => {};
+    ($t:tt ;) => {};
+    ($t:tt |) => {};
+    ($t:tt +) => {};
+    ($t:tt ident) => {};
+    ($t:tt $p:pat) => {};
+    ($t:tt $e:expr) => {};
+    ($t:tt $t:ty) => {};
+    ($t:tt $s:stmt) => {};
+    ($t:tt $p:path) => {};
+    ($t:tt $b:block) => {};
+    ($t:tt $i:ident) => {};
+    ($t:tt $t:tt) => {};
+    ($t:tt $i:item) => {};
+    ($t:tt $m:meta) => {};
+}
+// FOLLOW(item) = any token
+macro_rules! follow_item {
+    ($i:item ()) => {};
+    ($i:item []) => {};
+    ($i:item {}) => {};
+    ($i:item ,) => {};
+    ($i:item =>) => {};
+    ($i:item :) => {};
+    ($i:item =) => {};
+    ($i:item >) => {};
+    ($i:item ;) => {};
+    ($i:item |) => {};
+    ($i:item +) => {};
+    ($i:item ident) => {};
+    ($i:item $p:pat) => {};
+    ($i:item $e:expr) => {};
+    ($i:item $t:ty) => {};
+    ($i:item $s:stmt) => {};
+    ($i:item $p:path) => {};
+    ($i:item $b:block) => {};
+    ($i:item $i:ident) => {};
+    ($i:item $t:tt) => {};
+    ($i:item $i:item) => {};
+    ($i:item $m:meta) => {};
+}
+// FOLLOW(meta) = any token
+macro_rules! follow_meta {
+    ($m:meta ()) => {};
+    ($m:meta []) => {};
+    ($m:meta {}) => {};
+    ($m:meta ,) => {};
+    ($m:meta =>) => {};
+    ($m:meta :) => {};
+    ($m:meta =) => {};
+    ($m:meta >) => {};
+    ($m:meta ;) => {};
+    ($m:meta |) => {};
+    ($m:meta +) => {};
+    ($m:meta ident) => {};
+    ($m:meta $p:pat) => {};
+    ($m:meta $e:expr) => {};
+    ($m:meta $t:ty) => {};
+    ($m:meta $s:stmt) => {};
+    ($m:meta $p:path) => {};
+    ($m:meta $b:block) => {};
+    ($m:meta $i:ident) => {};
+    ($m:meta $t:tt) => {};
+    ($m:meta $i:item) => {};
+    ($m:meta $m:meta) => {};
+}
+
+fn main() {}
+