Skip to content

Commit 4625fda

Browse files
committed
Resurrecting rust-lang#33135
Started rebasing @sgrif's PR rust-lang#33135 off of current master. (Well, actually merging it into a new branch based off current master.) The following files still need to be fixed or at least reviewed: - `src/libsyntax/ext/tt/macro_parser.rs`: calls `Parser::parse_lifetime`, which doesn't exist anymore - `src/libsyntax/parse/parser.rs`: @sgrif added an error message to `Parser::parse_lifetime`. Code has since been refactored, so I just took it out for now. - `src/libsyntax/ext/tt/transcribe.rs`: This code has been refactored bigtime. Not sure whether @sgrif's changes here are still necessary. Took it out for this commit.
1 parent c1a960a commit 4625fda

9 files changed

+89
-7
lines changed

src/libsyntax/ext/quote.rs

+7
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,13 @@ pub mod rt {
191191
}
192192
}
193193

194+
impl ToTokens for ast::Lifetime {
195+
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
196+
let lifetime_ident = ast::Ident::with_empty_ctxt(self.name);
197+
vec![TokenTree::Token(DUMMY_SP, token::Lifetime(lifetime_ident))]
198+
}
199+
}
200+
194201
macro_rules! impl_to_tokens_slice {
195202
($t: ty, $sep: expr) => {
196203
impl ToTokens for [$t] {

src/libsyntax/ext/tt/macro_parser.rs

+1
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
530530
},
531531
"meta" => token::NtMeta(panictry!(p.parse_meta_item())),
532532
"vis" => token::NtVis(panictry!(p.parse_visibility(true))),
533+
"lifetime" => token::NtLifetime(panictry!(p.parse_lifetime())),
533534
// this is not supposed to happen, since it has been checked
534535
// when compiling the macro.
535536
_ => p.span_bug(sp, "invalid fragment specifier")

src/libsyntax/ext/tt/macro_rules.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,11 @@ fn token_can_be_followed_by_any(tok: &quoted::TokenTree) -> bool {
723723
/// ANYTHING without fear of future compatibility hazards).
724724
fn frag_can_be_followed_by_any(frag: &str) -> bool {
725725
match frag {
726-
"item" | // always terminated by `}` or `;`
727-
"block" | // exactly one token tree
728-
"ident" | // exactly one token tree
729-
"meta" | // exactly one token tree
726+
"item" | // always terminated by `}` or `;`
727+
"block" | // exactly one token tree
728+
"ident" | // exactly one token tree
729+
"meta" | // exactly one token tree
730+
"lifetime" | // exactly one token tree
730731
"tt" => // exactly one token tree
731732
true,
732733

@@ -787,8 +788,8 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> Result<bool, (String, &'
787788
TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => Ok(true),
788789
_ => Ok(false),
789790
},
790-
"ident" => {
791-
// being a single token, idents are harmless
791+
"ident" | "lifetime" => {
792+
// being a single token, idents and lifetimes are harmless
792793
Ok(true)
793794
},
794795
"meta" | "tt" => {
@@ -838,7 +839,7 @@ fn is_legal_fragment_specifier(sess: &ParseSess,
838839
frag_name: &str,
839840
frag_span: Span) -> bool {
840841
match frag_name {
841-
"item" | "block" | "stmt" | "expr" | "pat" |
842+
"item" | "block" | "stmt" | "expr" | "pat" | "lifetime" |
842843
"path" | "ty" | "ident" | "meta" | "tt" | "" => true,
843844
"vis" => {
844845
if !features.borrow().macro_vis_matcher {

src/libsyntax/fold.rs

+1
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
637637
token::NtWhereClause(fld.fold_where_clause(where_clause)),
638638
token::NtArg(arg) => token::NtArg(fld.fold_arg(arg)),
639639
token::NtVis(vis) => token::NtVis(fld.fold_vis(vis)),
640+
token::NtLifetime(lifetime) => token::NtLifetime(fld.fold_lifetime(lifetime)),
640641
}
641642
}
642643

src/libsyntax/parse/token.rs

+2
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ pub enum Nonterminal {
372372
NtGenerics(ast::Generics),
373373
NtWhereClause(ast::WhereClause),
374374
NtArg(ast::Arg),
375+
NtLifetime(ast::Lifetime),
375376
}
376377

377378
impl fmt::Debug for Nonterminal {
@@ -394,6 +395,7 @@ impl fmt::Debug for Nonterminal {
394395
NtWhereClause(..) => f.pad("NtWhereClause(..)"),
395396
NtArg(..) => f.pad("NtArg(..)"),
396397
NtVis(..) => f.pad("NtVis(..)"),
398+
NtLifetime(..) => f.pad("NtLifetime(..)"),
397399
}
398400
}
399401
}

src/libsyntax/print/pprust.rs

+1
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ pub fn token_to_string(tok: &Token) -> String {
294294
token::NtWhereClause(ref e) => where_clause_to_string(&e),
295295
token::NtArg(ref e) => arg_to_string(&e),
296296
token::NtVis(ref e) => vis_to_string(&e),
297+
token::NtLifetime(ref e) => lifetime_to_string(&e),
297298
}
298299
}
299300
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! foo {
12+
($l:lifetime, $l2:lifetime) => {
13+
fn f<$l: $l2, $l2>(arg: &$l str, arg2: &$l2 str) -> &$l str {
14+
arg
15+
}
16+
}
17+
}
18+
19+
pub fn main() {
20+
foo!('a, 'b);
21+
let x: &'static str = f("hi", "there");
22+
assert_eq!("hi", x);
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! foo {
12+
($l:lifetime) => {
13+
fn f(arg: &$l str) -> &$l str {
14+
arg
15+
}
16+
}
17+
}
18+
19+
pub fn main() {
20+
foo!('static);
21+
let x: &'static str = f("hi");
22+
assert_eq!("hi", x);
23+
}

src/test/run-pass/macro-lifetime.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! foo {
12+
($l:lifetime) => {
13+
fn f<$l>(arg: &$l str) -> &$l str {
14+
arg
15+
}
16+
}
17+
}
18+
19+
pub fn main() {
20+
foo!('a);
21+
let x: &'static str = f("hi");
22+
assert_eq!("hi", x);
23+
}

0 commit comments

Comments
 (0)