Auto merge of #57617 - mark-i-m:multiple-matcher-bindings, r=petrochenkov

Error on duplicate matcher bindings

fix  #57593

This should not be merged without a crater run and maybe an FCP. Discussion is ongoing at  #57593.

TODO:
- [x] write tests
- [x] crater run
- [x] ~maybe need edition gating?~ not for 1 regression /centril

r? @petrochenkov
This commit is contained in:
bors 2019-02-09 09:48:41 +00:00
commit 618f5a08a1
10 changed files with 171 additions and 38 deletions

View file

@ -12,11 +12,11 @@ macro_rules! follow_pat {
($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 $q:pat) => {}; //~ERROR `$p:pat` is followed by `$q: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 $q:path) => {}; //~ERROR `$p:pat` is followed by `$q: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`
@ -37,7 +37,7 @@ macro_rules! follow_expr {
($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 $f:expr) => {}; //~ERROR `$e:expr` is followed by `$f: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`
@ -57,12 +57,12 @@ macro_rules! follow_ty {
($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 $r:ty) => {}; //~ERROR `$t:ty` is followed by `$r: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) => {}; // ok (RFC 1494)
($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 $r:tt) => {}; //~ERROR `$t:ty` is followed by `$r: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`
}
@ -82,7 +82,7 @@ macro_rules! follow_stmt {
($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 $t:stmt) => {}; //~ERROR `$s:stmt` is followed by `$t: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`
@ -97,11 +97,11 @@ macro_rules! follow_path {
($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 $q:pat) => {}; //~ERROR `$p:path` is followed by `$q: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 $q:path) => {}; //~ERROR `$p:path` is followed by `$q:path`
($p:path $b:block) => {}; // ok (RFC 1494)
($p:path $i:ident) => {}; //~ERROR `$p:path` is followed by `$i:ident`
($p:path $t:tt) => {}; //~ERROR `$p:path` is followed by `$t:tt`

View file

@ -54,10 +54,10 @@ LL | ($p:pat ident) => {}; //~ERROR `$p:pat` is followed by `ident`
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
error: `$p:pat` is followed by `$p:pat`, which is not allowed for `pat` fragments
error: `$p:pat` is followed by `$q:pat`, which is not allowed for `pat` fragments
--> $DIR/macro-follow.rs:15:13
|
LL | ($p:pat $p:pat) => {}; //~ERROR `$p:pat` is followed by `$p:pat`
LL | ($p:pat $q:pat) => {}; //~ERROR `$p:pat` is followed by `$q:pat`
| ^^^^^^ not allowed after `pat` fragments
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
@ -86,10 +86,10 @@ LL | ($p:pat $s:stmt) => {}; //~ERROR `$p:pat` is followed by `$s:stmt`
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
error: `$p:pat` is followed by `$p:path`, which is not allowed for `pat` fragments
error: `$p:pat` is followed by `$q:path`, which is not allowed for `pat` fragments
--> $DIR/macro-follow.rs:19:13
|
LL | ($p:pat $p:path) => {}; //~ERROR `$p:pat` is followed by `$p:path`
LL | ($p:pat $q:path) => {}; //~ERROR `$p:pat` is followed by `$q:path`
| ^^^^^^^ not allowed after `pat` fragments
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
@ -230,10 +230,10 @@ LL | ($e:expr $p:pat) => {}; //~ERROR `$e:expr` is followed by `$p:pat`
|
= note: allowed there are: `=>`, `,` or `;`
error: `$e:expr` is followed by `$e:expr`, which is not allowed for `expr` fragments
error: `$e:expr` is followed by `$f:expr`, which is not allowed for `expr` fragments
--> $DIR/macro-follow.rs:40:14
|
LL | ($e:expr $e:expr) => {}; //~ERROR `$e:expr` is followed by `$e:expr`
LL | ($e:expr $f:expr) => {}; //~ERROR `$e:expr` is followed by `$f:expr`
| ^^^^^^^ not allowed after `expr` fragments
|
= note: allowed there are: `=>`, `,` or `;`
@ -350,10 +350,10 @@ LL | ($t:ty $e:expr) => {}; //~ERROR `$t:ty` is followed by `$e:expr`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
error: `$t:ty` is followed by `$t:ty`, which is not allowed for `ty` fragments
error: `$t:ty` is followed by `$r:ty`, which is not allowed for `ty` fragments
--> $DIR/macro-follow.rs:60:12
|
LL | ($t:ty $t:ty) => {}; //~ERROR `$t:ty` is followed by `$t:ty`
LL | ($t:ty $r:ty) => {}; //~ERROR `$t:ty` is followed by `$r:ty`
| ^^^^^ not allowed after `ty` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
@ -382,10 +382,10 @@ LL | ($t:ty $i:ident) => {}; //~ERROR `$t:ty` is followed by `$i:ident`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
error: `$t:ty` is followed by `$t:tt`, which is not allowed for `ty` fragments
error: `$t:ty` is followed by `$r:tt`, which is not allowed for `ty` fragments
--> $DIR/macro-follow.rs:65:12
|
LL | ($t:ty $t:tt) => {}; //~ERROR `$t:ty` is followed by `$t:tt`
LL | ($t:ty $r:tt) => {}; //~ERROR `$t:ty` is followed by `$r:tt`
| ^^^^^ not allowed after `ty` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
@ -518,10 +518,10 @@ LL | ($s:stmt $t:ty) => {}; //~ERROR `$s:stmt` is followed by `$t:ty`
|
= note: allowed there are: `=>`, `,` or `;`
error: `$s:stmt` is followed by `$s:stmt`, which is not allowed for `stmt` fragments
error: `$s:stmt` is followed by `$t:stmt`, which is not allowed for `stmt` fragments
--> $DIR/macro-follow.rs:85:14
|
LL | ($s:stmt $s:stmt) => {}; //~ERROR `$s:stmt` is followed by `$s:stmt`
LL | ($s:stmt $t:stmt) => {}; //~ERROR `$s:stmt` is followed by `$t:stmt`
| ^^^^^^^ not allowed after `stmt` fragments
|
= note: allowed there are: `=>`, `,` or `;`
@ -606,10 +606,10 @@ LL | ($p:path if) => {}; //~ERROR `$p:path` is followed by `if`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
error: `$p:path` is followed by `$p:pat`, which is not allowed for `path` fragments
error: `$p:path` is followed by `$q:pat`, which is not allowed for `path` fragments
--> $DIR/macro-follow.rs:100:14
|
LL | ($p:path $p:pat) => {}; //~ERROR `$p:path` is followed by `$p:pat`
LL | ($p:path $q:pat) => {}; //~ERROR `$p:path` is followed by `$q:pat`
| ^^^^^^ not allowed after `path` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
@ -638,10 +638,10 @@ LL | ($p:path $s:stmt) => {}; //~ERROR `$p:path` is followed by `$s:stmt`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
error: `$p:path` is followed by `$p:path`, which is not allowed for `path` fragments
error: `$p:path` is followed by `$q:path`, which is not allowed for `path` fragments
--> $DIR/macro-follow.rs:104:14
|
LL | ($p:path $p:path) => {}; //~ERROR `$p:path` is followed by `$p:path`
LL | ($p:path $q:path) => {}; //~ERROR `$p:path` is followed by `$q:path`
| ^^^^^^^ not allowed after `path` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`

View file

@ -0,0 +1,25 @@
// Test that duplicate matcher binding names are caught at declaration time, rather than at macro
// invocation time.
//
// FIXME(mark-i-m): Update this when it becomes a hard error.
// compile-pass
#![allow(unused_macros)]
macro_rules! foo1 {
($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding
($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding
}
macro_rules! foo2 {
($a:ident) => {}; // OK
($a:path) => {}; // OK
}
macro_rules! foo3 {
($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding
($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding
}
fn main() {}

View file

@ -0,0 +1,37 @@
warning: duplicate matcher binding
--> $DIR/macro-multiple-matcher-bindings.rs:11:6
|
LL | ($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding
| ^^^^^^^^ ^^^^^^^^
|
= note: #[warn(duplicate_matcher_binding_name)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
warning: duplicate matcher binding
--> $DIR/macro-multiple-matcher-bindings.rs:12:6
|
LL | ($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding
| ^^^^^^^^ ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
warning: duplicate matcher binding
--> $DIR/macro-multiple-matcher-bindings.rs:21:6
|
LL | ($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding
| ^^^^^^^^ ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
warning: duplicate matcher binding
--> $DIR/macro-multiple-matcher-bindings.rs:22:8
|
LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding
| ^^^^^^^^ ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>