diff options
author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-05-14 00:01:56 +0300 |
---|---|---|
committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-05-15 23:54:08 +0300 |
commit | c1061254317ac747d2bf5901329545f4cec5ebcb (patch) | |
tree | 4abe39c1bf4c5db072c168ce019c195763e0920b /src/libproc_macro | |
parent | 5b820a694c0fd8392092c3f0301537aafe92cce2 (diff) | |
download | rust-c1061254317ac747d2bf5901329545f4cec5ebcb.tar.gz |
Represent lifetimes as two joint tokens in proc macros
Diffstat (limited to 'src/libproc_macro')
-rw-r--r-- | src/libproc_macro/lib.rs | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index bf99a14a454..267922bf4a1 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -487,7 +487,7 @@ impl PartialEq<FileName> for SourceFile { pub enum TokenTree { /// A token stream surrounded by bracket delimiters. Group(Group), - /// An identifier or lifetime identifier. + /// An identifier. Ident(Ident), /// A single punctuation character (`+`, `,`, `$`, etc.). Punct(Punct), @@ -702,9 +702,10 @@ impl !Sync for Punct {} #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[unstable(feature = "proc_macro", issue = "38356")] pub enum Spacing { - /// e.g. `+` is `Alone` in `+ =`, `+ident` or `+()`. + /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`. Alone, - /// e.g. `+` is `Joint` in `+=` or `+#`. + /// E.g. `+` is `Joint` in `+=` or `'#`. + /// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`. Joint, } @@ -717,8 +718,8 @@ impl Punct { /// which can be further configured with the `set_span` method below. #[unstable(feature = "proc_macro", issue = "38356")] pub fn new(ch: char, spacing: Spacing) -> Punct { - const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', - '^', '&', '|', '@', '.', ',', ';', ':', '#', '$', '?']; + const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', + '&', '|', '@', '.', ',', ';', ':', '#', '$', '?', '\'']; if !LEGAL_CHARS.contains(&ch) { panic!("unsupported character `{:?}`", ch) } @@ -766,7 +767,7 @@ impl fmt::Display for Punct { } } -/// An identifier (`ident`) or lifetime identifier (`'ident`). +/// An identifier (`ident`). #[derive(Clone, Debug)] #[unstable(feature = "proc_macro", issue = "38356")] pub struct Ident { @@ -783,7 +784,7 @@ impl !Sync for Ident {} impl Ident { /// Creates a new `Ident` with the given `string` as well as the specified /// `span`. - /// The `string` argument must be a valid identifier or lifetime identifier permitted by the + /// The `string` argument must be a valid identifier permitted by the /// language, otherwise the function will panic. /// /// Note that `span`, currently in rustc, configures the hygiene information @@ -817,8 +818,7 @@ impl Ident { pub fn new_raw(string: &str, span: Span) -> Ident { let mut ident = Ident::new(string, span); if ident.sym == keywords::Underscore.name() || - token::is_path_segment_keyword(ast::Ident::with_empty_ctxt(ident.sym)) || - ident.sym.as_str().starts_with("\'") { + token::is_path_segment_keyword(ast::Ident::with_empty_ctxt(ident.sym)) { panic!("`{:?}` is not a valid raw identifier", string) } ident.is_raw = true; @@ -1211,13 +1211,19 @@ impl TokenTree { Pound => op!('#'), Dollar => op!('$'), Question => op!('?'), + SingleQuote => op!('\''), - Ident(ident, false) | Lifetime(ident) => { + Ident(ident, false) => { tt!(self::Ident::new(&ident.name.as_str(), Span(span))) } Ident(ident, true) => { tt!(self::Ident::new_raw(&ident.name.as_str(), Span(span))) } + Lifetime(ident) => { + let ident = ident.without_first_quote(); + stack.push(tt!(self::Ident::new(&ident.name.as_str(), Span(span)))); + tt!(Punct::new('\'', Spacing::Joint)) + } Literal(lit, suffix) => tt!(self::Literal { lit, suffix, span: Span(span) }), DocComment(c) => { let style = comments::doc_comment_style(&c.as_str()); @@ -1260,12 +1266,7 @@ impl TokenTree { }).into(); }, self::TokenTree::Ident(tt) => { - let ident = ast::Ident::new(tt.sym, tt.span.0); - let token = if tt.sym.as_str().starts_with("'") { - Lifetime(ident) - } else { - Ident(ident, tt.is_raw) - }; + let token = Ident(ast::Ident::new(tt.sym, tt.span.0), tt.is_raw); return TokenTree::Token(tt.span.0, token).into(); } self::TokenTree::Literal(self::Literal { @@ -1324,6 +1325,7 @@ impl TokenTree { '#' => Pound, '$' => Dollar, '?' => Question, + '\'' => SingleQuote, _ => unreachable!(), }; |