From 2cfd79017744aa55abdd470b93bc544685644612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 23 Oct 2018 21:37:32 -0700 Subject: [PATCH] List allowed tokens after macro fragments --- src/libsyntax/ext/tt/macro_rules.rs | 138 ++++--- src/test/ui/macros/macro-follow.stderr | 340 +++++++++++++----- .../macros/macro-followed-by-seq-bad.stderr | 8 +- .../macros/macro-input-future-proofing.stderr | 36 +- .../unused-macro-with-follow-violation.stderr | 4 +- 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 805aa9bef227d..a28d114bda784 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -792,15 +792,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 { @@ -809,15 +809,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::>().join(", "), + ts[ts.len() - 1], + )); + } + } + err.emit(); } } } @@ -860,6 +886,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 @@ -868,81 +900,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: "ed::TokenTree, frag: &str) -> Result { +fn is_in_follow(tok: "ed::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 ccd658af89fbb..8760f6eb572e3 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 bb070334d36e9..2ad8990e1156f 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 aed7a8a119ced..4bb46e39562cb 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 8efb191c7c645..78362fcb05a8c 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