rust/tests/ui/macros/nonterminal-matching.rs
Nicholas Nethercote dd2b027d5d Tweak more warnings.
Much like the previous commit.

I think the removal of "the token" in each message is fine here. There
are many more error messages that mention tokens without saying "the
token" than those that do say it.
2024-10-28 14:20:28 +11:00

57 lines
1.6 KiB
Rust

// Check that we are refusing to match on complex nonterminals for which tokens are
// unavailable and we'd have to go through AST comparisons.
#![feature(decl_macro)]
macro simple_nonterminal($nt_ident: ident, $nt_lifetime: lifetime, $nt_tt: tt) {
macro n(a $nt_ident b $nt_lifetime c $nt_tt d) {
struct S;
}
n!(a $nt_ident b $nt_lifetime c $nt_tt d);
}
macro complex_nonterminal($nt_item: item) {
macro n(a $nt_item b) {
struct S;
}
n!(a $nt_item b); //~ ERROR no rules expected item `enum E {}`
}
simple_nonterminal!(a, 'a, (x, y, z)); // OK
complex_nonterminal!(enum E {});
// `ident`, `lifetime`, and `tt` all work. Other fragments do not. See
// https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment
macro_rules! foo {
(ident $x:ident) => { bar!(ident $x); };
(lifetime $x:lifetime) => { bar!(lifetime $x); };
(tt $x:tt) => { bar!(tt $x); };
(expr $x:expr) => { bar!(expr $x); }; //~ ERROR: no rules expected expression `3`
(literal $x:literal) => { bar!(literal $x); }; //~ ERROR: no rules expected literal `4`
(path $x:path) => { bar!(path $x); }; //~ ERROR: no rules expected path `a::b::c`
(stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected statement `let abc = 0`
}
macro_rules! bar {
(ident abc) => {};
(lifetime 'abc) => {};
(tt 2) => {};
(expr 3) => {};
(literal 4) => {};
(path a::b::c) => {};
(stmt let abc = 0) => {};
}
foo!(ident abc);
foo!(lifetime 'abc);
foo!(tt 2);
foo!(expr 3);
foo!(literal 4);
foo!(path a::b::c);
foo!(stmt let abc = 0);
fn main() {}