diff options
| author | Dan Aloni <alonid@gmail.com> | 2018-04-10 02:08:47 +0300 |
|---|---|---|
| committer | Dan Aloni <alonid@gmail.com> | 2018-05-13 19:17:02 +0300 |
| commit | 37ed2ab91038567bafe3fd2e545c7d1631ff2ab0 (patch) | |
| tree | 27b8125e37ecd34720f6cee3286e821c6a6df96d /src/libsyntax/parse/token.rs | |
| parent | 3e955a058108fcadf0a8222de5868b0c905534d5 (diff) | |
| download | rust-37ed2ab91038567bafe3fd2e545c7d1631ff2ab0.tar.gz rust-37ed2ab91038567bafe3fd2e545c7d1631ff2ab0.zip | |
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
```
Diffstat (limited to 'src/libsyntax/parse/token.rs')
| -rw-r--r-- | src/libsyntax/parse/token.rs | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 938711ca1d4..6bcc1b0f026 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -280,7 +280,12 @@ impl Token { Lifetime(..) | // labeled loop Pound => true, // expression attributes Interpolated(ref nt) => match nt.0 { - NtIdent(..) | NtExpr(..) | NtBlock(..) | NtPath(..) | NtLifetime(..) => true, + NtLiteral(..) | + NtIdent(..) | + NtExpr(..) | + NtBlock(..) | + NtPath(..) | + NtLifetime(..) => true, _ => false, }, _ => false, @@ -324,6 +329,18 @@ impl Token { } } + /// Returns `true` if the token is any literal, a minus (which can follow a literal, + /// for example a '-42', or one of the boolean idents). + pub fn can_begin_literal_or_bool(&self) -> bool { + match *self { + Literal(..) => true, + BinOp(Minus) => true, + Ident(ident, false) if ident.name == keywords::True.name() => true, + Ident(ident, false) if ident.name == keywords::False.name() => true, + _ => false, + } + } + /// Returns an identifier if this token is an identifier. pub fn ident(&self) -> Option<(ast::Ident, /* is_raw */ bool)> { match *self { @@ -672,6 +689,7 @@ pub enum Nonterminal { NtTy(P<ast::Ty>), NtIdent(ast::Ident, /* is_raw */ bool), NtLifetime(ast::Ident), + NtLiteral(P<ast::Expr>), /// Stuff inside brackets for attributes NtMeta(ast::MetaItem), NtPath(ast::Path), @@ -713,6 +731,7 @@ impl fmt::Debug for Nonterminal { NtExpr(..) => f.pad("NtExpr(..)"), NtTy(..) => f.pad("NtTy(..)"), NtIdent(..) => f.pad("NtIdent(..)"), + NtLiteral(..) => f.pad("NtLiteral(..)"), NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), NtTT(..) => f.pad("NtTT(..)"), |
