Macros: Add a 'literal' fragment specifier

Implements RFC 1576.

See: https://github.com/rust-lang/rfcs/blob/master/text/1576-macros-literal-matcher.md

Changes are mostly in libsyntax, docs, and tests. Feature gate is
enabled for 1.27.0.

Many thanks to Vadim Petrochenkov for following through code reviews
and suggestions.

Example:

````rust

macro_rules! test_literal {
    ($l:literal) => {
        println!("literal: {}", $l);
    };
    ($e:expr) => {
        println!("expr: {}", $e);
    };
}

fn main() {
    let a = 1;
    test_literal!(a);
    test_literal!(2);
    test_literal!(-3);
}
```

Output:

```
expr: 1
literal: 2
literal: -3
```
This commit is contained in:
Dan Aloni 2018-04-10 02:08:47 +03:00
parent 3e955a0581
commit 37ed2ab910
14 changed files with 251 additions and 15 deletions

View file

@ -735,6 +735,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
"expr" => token.can_begin_expr(),
"ty" => token.can_begin_type(),
"ident" => get_macro_ident(token).is_some(),
"literal" => token.can_begin_literal_or_bool(),
"vis" => match *token {
// The follow-set of :vis + "priv" keyword + interpolated
Token::Comma | Token::Ident(..) | Token::Interpolated(_) => true,
@ -821,6 +822,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
},
"pat" => token::NtPat(panictry!(p.parse_pat())),
"expr" => token::NtExpr(panictry!(p.parse_expr())),
"literal" => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())),
"ty" => token::NtTy(panictry!(p.parse_ty())),
// this could be handled like a token, since it is one
"ident" => if let Some((ident, is_raw)) = get_macro_ident(&p.token) {