about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs138
-rw-r--r--src/test/ui/macros/macro-follow.stderr340
-rw-r--r--src/test/ui/macros/macro-followed-by-seq-bad.stderr8
-rw-r--r--src/test/ui/macros/macro-input-future-proofing.stderr36
-rw-r--r--src/test/ui/unused/unused-macro-with-follow-violation.stderr4
5 files changed, 385 insertions, 141 deletions
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 543dc478d7b..f298d626cd8 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -808,15 +808,15 @@ fn check_matcher_core(sess: &ParseSess,
             if let TokenTree::MetaVarDecl(_, ref name, ref frag_spec) = *token {
                 for next_token in &suffix_first.tokens {
                     match is_in_follow(next_token, &frag_spec.as_str()) {
-                        Err((msg, help)) => {
+                        IsInFollow::Invalid(msg, help) => {
                             sess.span_diagnostic.struct_span_err(next_token.span(), &msg)
                                 .help(help).emit();
                             // don't bother reporting every source of
                             // conflict for a particular element of `last`.
                             continue 'each_last;
                         }
-                        Ok(true) => {}
-                        Ok(false) => {
+                        IsInFollow::Yes => {}
+                        IsInFollow::No(ref possible) => {
                             let may_be = if last.tokens.len() == 1 &&
                                 suffix_first.tokens.len() == 1
                             {
@@ -825,15 +825,41 @@ fn check_matcher_core(sess: &ParseSess,
                                 "may be"
                             };
 
-                            sess.span_diagnostic.span_err(
-                                next_token.span(),
+                            let sp = next_token.span();
+                            let mut err = sess.span_diagnostic.struct_span_err(
+                                sp,
                                 &format!("`${name}:{frag}` {may_be} followed by `{next}`, which \
                                           is not allowed for `{frag}` fragments",
                                          name=name,
                                          frag=frag_spec,
                                          next=quoted_tt_to_string(next_token),
-                                         may_be=may_be)
+                                         may_be=may_be),
                             );
+                            err.span_label(
+                                sp,
+                                format!("not allowed after `{}` fragments", frag_spec),
+                            );
+                            let msg = "allowed there are: ";
+                            match &possible[..] {
+                                &[] => {}
+                                &[t] => {
+                                    err.note(&format!(
+                                        "only {} is allowed after `{}` fragments",
+                                        t,
+                                        frag_spec,
+                                    ));
+                                }
+                                ts => {
+                                    err.note(&format!(
+                                        "{}{} or {}",
+                                        msg,
+                                        ts[..ts.len() - 1].iter().map(|s| *s)
+                                            .collect::<Vec<_>>().join(", "),
+                                        ts[ts.len() - 1],
+                                    ));
+                                }
+                            }
+                            err.emit();
                         }
                     }
                 }
@@ -876,6 +902,12 @@ fn frag_can_be_followed_by_any(frag: &str) -> bool {
     }
 }
 
+enum IsInFollow {
+    Yes,
+    No(Vec<&'static str>),
+    Invalid(String, &'static str),
+}
+
 /// True if `frag` can legally be followed by the token `tok`. For
 /// fragments that can consume an unbounded number of tokens, `tok`
 /// must be within a well-defined follow set. This is intended to
@@ -884,81 +916,99 @@ fn frag_can_be_followed_by_any(frag: &str) -> bool {
 /// break macros that were relying on that binary operator as a
 /// separator.
 // when changing this do not forget to update doc/book/macros.md!
-fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> Result<bool, (String, &'static str)> {
+fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
     use self::quoted::TokenTree;
 
     if let TokenTree::Token(_, token::CloseDelim(_)) = *tok {
         // closing a token tree can never be matched by any fragment;
         // iow, we always require that `(` and `)` match, etc.
-        Ok(true)
+        IsInFollow::Yes
     } else {
         match frag {
             "item" => {
                 // since items *must* be followed by either a `;` or a `}`, we can
                 // accept anything after them
-                Ok(true)
+                IsInFollow::Yes
             },
             "block" => {
                 // anything can follow block, the braces provide an easy boundary to
                 // maintain
-                Ok(true)
+                IsInFollow::Yes
             },
-            "stmt" | "expr"  => match *tok {
-                TokenTree::Token(_, ref tok) => match *tok {
-                    FatArrow | Comma | Semi => Ok(true),
-                    _ => Ok(false)
-                },
-                _ => Ok(false),
+            "stmt" | "expr"  => {
+                let tokens = vec!["`=>`", "`,`", "`;`"];
+                match *tok {
+                    TokenTree::Token(_, ref tok) => match *tok {
+                        FatArrow | Comma | Semi => IsInFollow::Yes,
+                        _ => IsInFollow::No(tokens),
+                    },
+                    _ => IsInFollow::No(tokens),
+                }
             },
-            "pat" => match *tok {
-                TokenTree::Token(_, ref tok) => match *tok {
-                    FatArrow | Comma | Eq | BinOp(token::Or) => Ok(true),
-                    Ident(i, false) if i.name == "if" || i.name == "in" => Ok(true),
-                    _ => Ok(false)
-                },
-                _ => Ok(false),
+            "pat" => {
+                let tokens = vec!["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
+                match *tok {
+                    TokenTree::Token(_, ref tok) => match *tok {
+                        FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes,
+                        Ident(i, false) if i.name == "if" || i.name == "in" => IsInFollow::Yes,
+                        _ => IsInFollow::No(tokens),
+                    },
+                    _ => IsInFollow::No(tokens),
+                }
             },
-            "path" | "ty" => match *tok {
-                TokenTree::Token(_, ref tok) => match *tok {
-                    OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) |
-                    Comma | FatArrow | Colon | Eq | Gt | BinOp(token::Shr) | Semi |
-                    BinOp(token::Or) => Ok(true),
-                    Ident(i, false) if i.name == "as" || i.name == "where" => Ok(true),
-                    _ => Ok(false)
-                },
-                TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => Ok(true),
-                _ => Ok(false),
+            "path" | "ty" => {
+                let tokens = vec![
+                    "`{`", "`[`", "`=>`", "`,`", "`>`","`=`", "`:`", "`;`", "`|`", "`as`",
+                    "`where`",
+                ];
+                match *tok {
+                    TokenTree::Token(_, ref tok) => match *tok {
+                        OpenDelim(token::DelimToken::Brace) |
+                        OpenDelim(token::DelimToken::Bracket) |
+                        Comma | FatArrow | Colon | Eq | Gt | BinOp(token::Shr) | Semi |
+                        BinOp(token::Or) => IsInFollow::Yes,
+                        Ident(i, false) if i.name == "as" || i.name == "where" => IsInFollow::Yes,
+                        _ => IsInFollow::No(tokens),
+                    },
+                    TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => IsInFollow::Yes,
+                    _ => IsInFollow::No(tokens),
+                }
             },
             "ident" | "lifetime" => {
                 // being a single token, idents and lifetimes are harmless
-                Ok(true)
+                IsInFollow::Yes
             },
             "literal" => {
                 // literals may be of a single token, or two tokens (negative numbers)
-                Ok(true)
+                IsInFollow::Yes
             },
             "meta" | "tt" => {
                 // being either a single token or a delimited sequence, tt is
                 // harmless
-                Ok(true)
+                IsInFollow::Yes
             },
             "vis" => {
                 // Explicitly disallow `priv`, on the off chance it comes back.
+                let tokens = vec!["`,`", "an ident", "a type"];
                 match *tok {
                     TokenTree::Token(_, ref tok) => match *tok {
-                        Comma => Ok(true),
-                        Ident(i, is_raw) if is_raw || i.name != "priv" => Ok(true),
-                        ref tok => Ok(tok.can_begin_type())
+                        Comma => IsInFollow::Yes,
+                        Ident(i, is_raw) if is_raw || i.name != "priv" => IsInFollow::Yes,
+                        ref tok => if tok.can_begin_type() {
+                            IsInFollow::Yes
+                        } else {
+                            IsInFollow::No(tokens)
+                        }
                     },
                     TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident"
                                                        || frag.name == "ty"
-                                                       || frag.name == "path" => Ok(true),
-                    _ => Ok(false)
+                                                       || frag.name == "path" => IsInFollow::Yes,
+                    _ => IsInFollow::No(tokens),
                 }
             },
-            "" => Ok(true), // keywords::Invalid
-            _ => Err((format!("invalid fragment specifier `{}`", frag),
-                     VALID_FRAGMENT_NAMES_MSG))
+            "" => IsInFollow::Yes, // keywords::Invalid
+            _ => IsInFollow::Invalid(format!("invalid fragment specifier `{}`", frag),
+                                     VALID_FRAGMENT_NAMES_MSG),
         }
     }
 }
diff --git a/src/test/ui/macros/macro-follow.stderr b/src/test/ui/macros/macro-follow.stderr
index ccd658af89f..8760f6eb572 100644
--- a/src/test/ui/macros/macro-follow.stderr
+++ b/src/test/ui/macros/macro-follow.stderr
@@ -2,511 +2,681 @@ error: `$p:pat` is followed by `(`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:17:14
    |
 LL |     ($p:pat ()) => {};       //~ERROR  `$p:pat` is followed by `(`
-   |              ^
+   |              ^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `[`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:18:14
    |
 LL |     ($p:pat []) => {};       //~ERROR  `$p:pat` is followed by `[`
-   |              ^
+   |              ^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `{`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:19:14
    |
 LL |     ($p:pat {}) => {};       //~ERROR  `$p:pat` is followed by `{`
-   |              ^
+   |              ^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `:`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:20:13
    |
 LL |     ($p:pat :) => {};        //~ERROR `$p:pat` is followed by `:`
-   |             ^
+   |             ^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `>`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:21:13
    |
 LL |     ($p:pat >) => {};        //~ERROR `$p:pat` is followed by `>`
-   |             ^
+   |             ^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `+`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:22:13
    |
 LL |     ($p:pat +) => {};        //~ERROR `$p:pat` is followed by `+`
-   |             ^
+   |             ^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `ident`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:23:13
    |
 LL |     ($p:pat ident) => {};    //~ERROR `$p:pat` is followed by `ident`
-   |             ^^^^^
+   |             ^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$p:pat`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:24:13
    |
 LL |     ($p:pat $p:pat) => {};   //~ERROR `$p:pat` is followed by `$p:pat`
-   |             ^^^^^^
+   |             ^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$e:expr`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:25:13
    |
 LL |     ($p:pat $e:expr) => {};  //~ERROR `$p:pat` is followed by `$e:expr`
-   |             ^^^^^^^
+   |             ^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$t:ty`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:26:13
    |
 LL |     ($p:pat $t:ty) => {};    //~ERROR `$p:pat` is followed by `$t:ty`
-   |             ^^^^^
+   |             ^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$s:stmt`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:27:13
    |
 LL |     ($p:pat $s:stmt) => {};  //~ERROR `$p:pat` is followed by `$s:stmt`
-   |             ^^^^^^^
+   |             ^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$p:path`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:28:13
    |
 LL |     ($p:pat $p:path) => {};  //~ERROR `$p:pat` is followed by `$p:path`
-   |             ^^^^^^^
+   |             ^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$b:block`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:29:13
    |
 LL |     ($p:pat $b:block) => {}; //~ERROR `$p:pat` is followed by `$b:block`
-   |             ^^^^^^^^
+   |             ^^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$i:ident`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:30:13
    |
 LL |     ($p:pat $i:ident) => {}; //~ERROR `$p:pat` is followed by `$i:ident`
-   |             ^^^^^^^^
+   |             ^^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$t:tt`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:31:13
    |
 LL |     ($p:pat $t:tt) => {};    //~ERROR `$p:pat` is followed by `$t:tt`
-   |             ^^^^^
+   |             ^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$i:item`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:32:13
    |
 LL |     ($p:pat $i:item) => {};  //~ERROR `$p:pat` is followed by `$i:item`
-   |             ^^^^^^^
+   |             ^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$p:pat` is followed by `$m:meta`, which is not allowed for `pat` fragments
   --> $DIR/macro-follow.rs:33:13
    |
 LL |     ($p:pat $m:meta) => {};  //~ERROR `$p:pat` is followed by `$m:meta`
-   |             ^^^^^^^
+   |             ^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$e:expr` is followed by `(`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:37:15
    |
 LL |     ($e:expr ()) => {};       //~ERROR  `$e:expr` is followed by `(`
-   |               ^
+   |               ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `[`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:38:15
    |
 LL |     ($e:expr []) => {};       //~ERROR  `$e:expr` is followed by `[`
-   |               ^
+   |               ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `{`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:39:15
    |
 LL |     ($e:expr {}) => {};       //~ERROR  `$e:expr` is followed by `{`
-   |               ^
+   |               ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `=`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:40:14
    |
 LL |     ($e:expr =) => {};        //~ERROR `$e:expr` is followed by `=`
-   |              ^
+   |              ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `|`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:41:14
    |
 LL |     ($e:expr |) => {};        //~ERROR `$e:expr` is followed by `|`
-   |              ^
+   |              ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `:`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:42:14
    |
 LL |     ($e:expr :) => {};        //~ERROR `$e:expr` is followed by `:`
-   |              ^
+   |              ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `>`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:43:14
    |
 LL |     ($e:expr >) => {};        //~ERROR `$e:expr` is followed by `>`
-   |              ^
+   |              ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:44:14
    |
 LL |     ($e:expr +) => {};        //~ERROR `$e:expr` is followed by `+`
-   |              ^
+   |              ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `ident`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:45:14
    |
 LL |     ($e:expr ident) => {};    //~ERROR `$e:expr` is followed by `ident`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `if`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:46:14
    |
 LL |     ($e:expr if) => {};       //~ERROR `$e:expr` is followed by `if`
-   |              ^^
+   |              ^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `in`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:47:14
    |
 LL |     ($e:expr in) => {};       //~ERROR `$e:expr` is followed by `in`
-   |              ^^
+   |              ^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$p:pat`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:48:14
    |
 LL |     ($e:expr $p:pat) => {};   //~ERROR `$e:expr` is followed by `$p:pat`
-   |              ^^^^^^
+   |              ^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$e:expr`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:49:14
    |
 LL |     ($e:expr $e:expr) => {};  //~ERROR `$e:expr` is followed by `$e:expr`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$t:ty`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:50:14
    |
 LL |     ($e:expr $t:ty) => {};    //~ERROR `$e:expr` is followed by `$t:ty`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$s:stmt`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:51:14
    |
 LL |     ($e:expr $s:stmt) => {};  //~ERROR `$e:expr` is followed by `$s:stmt`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$p:path`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:52:14
    |
 LL |     ($e:expr $p:path) => {};  //~ERROR `$e:expr` is followed by `$p:path`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$b:block`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:53:14
    |
 LL |     ($e:expr $b:block) => {}; //~ERROR `$e:expr` is followed by `$b:block`
-   |              ^^^^^^^^
+   |              ^^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$i:ident`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:54:14
    |
 LL |     ($e:expr $i:ident) => {}; //~ERROR `$e:expr` is followed by `$i:ident`
-   |              ^^^^^^^^
+   |              ^^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$t:tt`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:55:14
    |
 LL |     ($e:expr $t:tt) => {};    //~ERROR `$e:expr` is followed by `$t:tt`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$i:item`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:56:14
    |
 LL |     ($e:expr $i:item) => {};  //~ERROR `$e:expr` is followed by `$i:item`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$e:expr` is followed by `$m:meta`, which is not allowed for `expr` fragments
   --> $DIR/macro-follow.rs:57:14
    |
 LL |     ($e:expr $m:meta) => {};  //~ERROR `$e:expr` is followed by `$m:meta`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$t:ty` is followed by `(`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:62:13
    |
 LL |     ($t:ty ()) => {};       //~ERROR  `$t:ty` is followed by `(`
-   |             ^
+   |             ^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `+`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:64:12
    |
 LL |     ($t:ty +) => {};        //~ERROR `$t:ty` is followed by `+`
-   |            ^
+   |            ^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `ident`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:65:12
    |
 LL |     ($t:ty ident) => {};    //~ERROR `$t:ty` is followed by `ident`
-   |            ^^^^^
+   |            ^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `if`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:66:12
    |
 LL |     ($t:ty if) => {};       //~ERROR `$t:ty` is followed by `if`
-   |            ^^
+   |            ^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$p:pat`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:67:12
    |
 LL |     ($t:ty $p:pat) => {};   //~ERROR `$t:ty` is followed by `$p:pat`
-   |            ^^^^^^
+   |            ^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$e:expr`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:68:12
    |
 LL |     ($t:ty $e:expr) => {};  //~ERROR `$t:ty` is followed by `$e:expr`
-   |            ^^^^^^^
+   |            ^^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$t:ty`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:69:12
    |
 LL |     ($t:ty $t:ty) => {};    //~ERROR `$t:ty` is followed by `$t:ty`
-   |            ^^^^^
+   |            ^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$s:stmt`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:70:12
    |
 LL |     ($t:ty $s:stmt) => {};  //~ERROR `$t:ty` is followed by `$s:stmt`
-   |            ^^^^^^^
+   |            ^^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$p:path`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:71:12
    |
 LL |     ($t:ty $p:path) => {};  //~ERROR `$t:ty` is followed by `$p:path`
-   |            ^^^^^^^
+   |            ^^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$i:ident`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:73:12
    |
 LL |     ($t:ty $i:ident) => {}; //~ERROR `$t:ty` is followed by `$i:ident`
-   |            ^^^^^^^^
+   |            ^^^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$t:tt`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:74:12
    |
 LL |     ($t:ty $t:tt) => {};    //~ERROR `$t:ty` is followed by `$t:tt`
-   |            ^^^^^
+   |            ^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$i:item`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:75:12
    |
 LL |     ($t:ty $i:item) => {};  //~ERROR `$t:ty` is followed by `$i:item`
-   |            ^^^^^^^
+   |            ^^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$t:ty` is followed by `$m:meta`, which is not allowed for `ty` fragments
   --> $DIR/macro-follow.rs:76:12
    |
 LL |     ($t:ty $m:meta) => {};  //~ERROR `$t:ty` is followed by `$m:meta`
-   |            ^^^^^^^
+   |            ^^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$s:stmt` is followed by `(`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:80:15
    |
 LL |     ($s:stmt ()) => {};       //~ERROR  `$s:stmt` is followed by `(`
-   |               ^
+   |               ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `[`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:81:15
    |
 LL |     ($s:stmt []) => {};       //~ERROR  `$s:stmt` is followed by `[`
-   |               ^
+   |               ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `{`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:82:15
    |
 LL |     ($s:stmt {}) => {};       //~ERROR  `$s:stmt` is followed by `{`
-   |               ^
+   |               ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `=`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:83:14
    |
 LL |     ($s:stmt =) => {};        //~ERROR `$s:stmt` is followed by `=`
-   |              ^
+   |              ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `|`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:84:14
    |
 LL |     ($s:stmt |) => {};        //~ERROR `$s:stmt` is followed by `|`
-   |              ^
+   |              ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `:`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:85:14
    |
 LL |     ($s:stmt :) => {};        //~ERROR `$s:stmt` is followed by `:`
-   |              ^
+   |              ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `>`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:86:14
    |
 LL |     ($s:stmt >) => {};        //~ERROR `$s:stmt` is followed by `>`
-   |              ^
+   |              ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `+`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:87:14
    |
 LL |     ($s:stmt +) => {};        //~ERROR `$s:stmt` is followed by `+`
-   |              ^
+   |              ^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `ident`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:88:14
    |
 LL |     ($s:stmt ident) => {};    //~ERROR `$s:stmt` is followed by `ident`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `if`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:89:14
    |
 LL |     ($s:stmt if) => {};       //~ERROR `$s:stmt` is followed by `if`
-   |              ^^
+   |              ^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `in`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:90:14
    |
 LL |     ($s:stmt in) => {};       //~ERROR `$s:stmt` is followed by `in`
-   |              ^^
+   |              ^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$p:pat`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:91:14
    |
 LL |     ($s:stmt $p:pat) => {};   //~ERROR `$s:stmt` is followed by `$p:pat`
-   |              ^^^^^^
+   |              ^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$e:expr`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:92:14
    |
 LL |     ($s:stmt $e:expr) => {};  //~ERROR `$s:stmt` is followed by `$e:expr`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$t:ty`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:93:14
    |
 LL |     ($s:stmt $t:ty) => {};    //~ERROR `$s:stmt` is followed by `$t:ty`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$s:stmt`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:94:14
    |
 LL |     ($s:stmt $s:stmt) => {};  //~ERROR `$s:stmt` is followed by `$s:stmt`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$p:path`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:95:14
    |
 LL |     ($s:stmt $p:path) => {};  //~ERROR `$s:stmt` is followed by `$p:path`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$b:block`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:96:14
    |
 LL |     ($s:stmt $b:block) => {}; //~ERROR `$s:stmt` is followed by `$b:block`
-   |              ^^^^^^^^
+   |              ^^^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$i:ident`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:97:14
    |
 LL |     ($s:stmt $i:ident) => {}; //~ERROR `$s:stmt` is followed by `$i:ident`
-   |              ^^^^^^^^
+   |              ^^^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$t:tt`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:98:14
    |
 LL |     ($s:stmt $t:tt) => {};    //~ERROR `$s:stmt` is followed by `$t:tt`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$i:item`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:99:14
    |
 LL |     ($s:stmt $i:item) => {};  //~ERROR `$s:stmt` is followed by `$i:item`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$s:stmt` is followed by `$m:meta`, which is not allowed for `stmt` fragments
   --> $DIR/macro-follow.rs:100:14
    |
 LL |     ($s:stmt $m:meta) => {};  //~ERROR `$s:stmt` is followed by `$m:meta`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `stmt` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$p:path` is followed by `(`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:104:15
    |
 LL |     ($p:path ()) => {};       //~ERROR  `$p:path` is followed by `(`
-   |               ^
+   |               ^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `+`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:106:14
    |
 LL |     ($p:path +) => {};        //~ERROR `$p:path` is followed by `+`
-   |              ^
+   |              ^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `ident`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:107:14
    |
 LL |     ($p:path ident) => {};    //~ERROR `$p:path` is followed by `ident`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `if`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:108:14
    |
 LL |     ($p:path if) => {};       //~ERROR `$p:path` is followed by `if`
-   |              ^^
+   |              ^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$p:pat`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:109:14
    |
 LL |     ($p:path $p:pat) => {};   //~ERROR `$p:path` is followed by `$p:pat`
-   |              ^^^^^^
+   |              ^^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$e:expr`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:110:14
    |
 LL |     ($p:path $e:expr) => {};  //~ERROR `$p:path` is followed by `$e:expr`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$t:ty`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:111:14
    |
 LL |     ($p:path $t:ty) => {};    //~ERROR `$p:path` is followed by `$t:ty`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$s:stmt`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:112:14
    |
 LL |     ($p:path $s:stmt) => {};  //~ERROR `$p:path` is followed by `$s:stmt`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$p:path`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:113:14
    |
 LL |     ($p:path $p:path) => {};  //~ERROR `$p:path` is followed by `$p:path`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$i:ident`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:115:14
    |
 LL |     ($p:path $i:ident) => {}; //~ERROR `$p:path` is followed by `$i:ident`
-   |              ^^^^^^^^
+   |              ^^^^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$t:tt`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:116:14
    |
 LL |     ($p:path $t:tt) => {};    //~ERROR `$p:path` is followed by `$t:tt`
-   |              ^^^^^
+   |              ^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$i:item`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:117:14
    |
 LL |     ($p:path $i:item) => {};  //~ERROR `$p:path` is followed by `$i:item`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$p:path` is followed by `$m:meta`, which is not allowed for `path` fragments
   --> $DIR/macro-follow.rs:118:14
    |
 LL |     ($p:path $m:meta) => {};  //~ERROR `$p:path` is followed by `$m:meta`
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `path` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: aborting due to 85 previous errors
 
diff --git a/src/test/ui/macros/macro-followed-by-seq-bad.stderr b/src/test/ui/macros/macro-followed-by-seq-bad.stderr
index bb070334d36..2ad8990e115 100644
--- a/src/test/ui/macros/macro-followed-by-seq-bad.stderr
+++ b/src/test/ui/macros/macro-followed-by-seq-bad.stderr
@@ -2,13 +2,17 @@ error: `$a:expr` is followed by `$b:tt`, which is not allowed for `expr` fragmen
   --> $DIR/macro-followed-by-seq-bad.rs:17:15
    |
 LL |   ( $a:expr $($b:tt)* ) => { }; //~ ERROR not allowed for `expr` fragments
-   |               ^^^^^
+   |               ^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: `$a:ty` is followed by `$b:tt`, which is not allowed for `ty` fragments
   --> $DIR/macro-followed-by-seq-bad.rs:18:13
    |
 LL |   ( $a:ty $($b:tt)* ) => { };   //~ ERROR not allowed for `ty` fragments
-   |             ^^^^^
+   |             ^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/macro-input-future-proofing.stderr b/src/test/ui/macros/macro-input-future-proofing.stderr
index aed7a8a119c..4bb46e39562 100644
--- a/src/test/ui/macros/macro-input-future-proofing.stderr
+++ b/src/test/ui/macros/macro-input-future-proofing.stderr
@@ -2,55 +2,73 @@ error: `$ty:ty` is followed by `<`, which is not allowed for `ty` fragments
   --> $DIR/macro-input-future-proofing.rs:14:13
    |
 LL |     ($ty:ty <) => (); //~ ERROR `$ty:ty` is followed by `<`, which is not allowed for `ty`
-   |             ^
+   |             ^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$ty:ty` is followed by `<`, which is not allowed for `ty` fragments
   --> $DIR/macro-input-future-proofing.rs:15:13
    |
 LL |     ($ty:ty < foo ,) => (); //~ ERROR `$ty:ty` is followed by `<`, which is not allowed for `ty`
-   |             ^
+   |             ^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$pa:pat` is followed by `>`, which is not allowed for `pat` fragments
   --> $DIR/macro-input-future-proofing.rs:21:14
    |
 LL |     ($pa:pat >) => (); //~ ERROR `$pa:pat` is followed by `>`, which is not allowed for `pat`
-   |              ^
+   |              ^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$pa:pat` is followed by `$pb:pat`, which is not allowed for `pat` fragments
   --> $DIR/macro-input-future-proofing.rs:23:14
    |
 LL |     ($pa:pat $pb:pat $ty:ty ,) => ();
-   |              ^^^^^^^
+   |              ^^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$pb:pat` is followed by `$ty:ty`, which is not allowed for `pat` fragments
   --> $DIR/macro-input-future-proofing.rs:23:22
    |
 LL |     ($pa:pat $pb:pat $ty:ty ,) => ();
-   |                      ^^^^^^
+   |                      ^^^^^^ not allowed after `pat` fragments
+   |
+   = note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
 
 error: `$ty:ty` is followed by `-`, which is not allowed for `ty` fragments
   --> $DIR/macro-input-future-proofing.rs:26:17
    |
 LL |     ($($ty:ty)* -) => (); //~ ERROR `$ty:ty` is followed by `-`
-   |                 ^
+   |                 ^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$b:ty` is followed by `-`, which is not allowed for `ty` fragments
   --> $DIR/macro-input-future-proofing.rs:27:23
    |
 LL |     ($($a:ty, $b:ty)* -) => (); //~ ERROR `$b:ty` is followed by `-`
-   |                       ^
+   |                       ^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$ty:ty` is followed by `-`, which is not allowed for `ty` fragments
   --> $DIR/macro-input-future-proofing.rs:28:7
    |
 LL |     ($($ty:ty)-+) => (); //~ ERROR `$ty:ty` is followed by `-`, which is not allowed for `ty`
-   |       ^^^^^^^^
+   |       ^^^^^^^^ not allowed after `ty` fragments
+   |
+   = note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
 
 error: `$a:expr` is followed by `$b:tt`, which is not allowed for `expr` fragments
   --> $DIR/macro-input-future-proofing.rs:29:21
    |
 LL |     ( $($a:expr)* $($b:tt)* ) => { };
-   |                     ^^^^^
+   |                     ^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/unused/unused-macro-with-follow-violation.stderr b/src/test/ui/unused/unused-macro-with-follow-violation.stderr
index 8efb191c7c6..78362fcb05a 100644
--- a/src/test/ui/unused/unused-macro-with-follow-violation.stderr
+++ b/src/test/ui/unused/unused-macro-with-follow-violation.stderr
@@ -2,7 +2,9 @@ error: `$e:expr` is followed by `+`, which is not allowed for `expr` fragments
   --> $DIR/unused-macro-with-follow-violation.rs:14:14
    |
 LL |     ($e:expr +) => () //~ ERROR not allowed for `expr` fragments
-   |              ^
+   |              ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
 
 error: aborting due to previous error