mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-01 04:27:38 +00:00

This involves replacing `nt_pretty_printing_compatibility_hack` with `stream_pretty_printing_compatibility_hack`. The handling of statements in `transcribe` is slightly different to other nonterminal kinds, due to the lack of `from_ast` implementation for empty statements. Notable test changes: - `tests/ui/proc-macro/expand-to-derive.rs`: the diff looks large but the only difference is the insertion of a single invisible-delimited group around a metavar.
57 lines
1.6 KiB
Rust
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` metavariable
|
|
}
|
|
|
|
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` metavariable
|
|
(stmt $x:stmt) => { bar!(stmt $x); }; //~ ERROR: no rules expected `stmt` metavariable
|
|
}
|
|
|
|
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() {}
|