Skip to content

Commit 68c41a1

Browse files
committed
Add macro lifetime specifier
Allows accepting a lifetime as a parameter to a macro
1 parent 6403a2f commit 68c41a1

File tree

8 files changed

+27
-5
lines changed

8 files changed

+27
-5
lines changed

src/libsyntax/ext/tt/macro_parser.rs

+8
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,14 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
540540
&token_str[..])))
541541
}
542542
},
543+
"lifetime" => match p.token {
544+
token::Lifetime(sn) => { panictry!(p.bump()); token::NtLifetime(Box::new(sn)) }
545+
_ => {
546+
let token_str = pprust::token_to_string(&p.token);
547+
panic!(p.fatal(&format!("expected lifetime, found {}",
548+
&token_str[..])))
549+
}
550+
},
543551
"path" => {
544552
token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
545553
}

src/libsyntax/ext/tt/macro_rules.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,8 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> {
505505
_ => Ok(false)
506506
}
507507
},
508-
"ident" => {
509-
// being a single token, idents are harmless
508+
"ident" | "lifetime" => {
509+
// being a single token, idents and lifetimes are harmless
510510
Ok(true)
511511
},
512512
"meta" | "tt" => {

src/libsyntax/ext/tt/transcribe.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use codemap::{Span, DUMMY_SP};
1515
use diagnostic::SpanHandler;
1616
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
1717
use parse::token::{Eof, DocComment, Interpolated, MatchNt, SubstNt};
18-
use parse::token::{Token, NtIdent, SpecialMacroVar};
18+
use parse::token::{Token, NtIdent, NtLifetime, SpecialMacroVar};
1919
use parse::token;
2020
use parse::lexer::TokenAndSpan;
2121

@@ -299,6 +299,11 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
299299
r.cur_tok = token::Ident(**sn, b);
300300
return ret_val;
301301
}
302+
MatchedNonterminal(NtLifetime(ref sn)) => {
303+
r.cur_span = sp;
304+
r.cur_tok = token::Lifetime(**sn);
305+
return ret_val;
306+
}
302307
MatchedNonterminal(ref other_whole_nt) => {
303308
// FIXME(pcwalton): Bad copy.
304309
r.cur_span = sp;

src/libsyntax/fold.rs

+2
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,8 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
679679
token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
680680
token::NtIdent(id, is_mod_name) =>
681681
token::NtIdent(Box::new(fld.fold_ident(*id)), is_mod_name),
682+
token::NtLifetime(id) => token::NtLifetime(Box::new(
683+
fld.fold_lifetime(ast_util::name_to_dummy_lifetime(id.name)).name.ident())),
682684
token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
683685
token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))),
684686
token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&*tt))),

src/libsyntax/parse/parser.rs

+3
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,9 @@ impl<'a> Parser<'a> {
537537
token::Interpolated(token::NtIdent(..)) => {
538538
self.bug("ident interpolation not converted to real token");
539539
}
540+
token::Interpolated(token::NtLifetime(..)) => {
541+
self.bug("lifetime interpolation not converted to real token");
542+
}
540543
_ => {
541544
let token_str = self.this_token_to_string();
542545
Err(self.fatal(&format!("expected ident, found `{}`",

src/libsyntax/parse/token.rs

+2
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ pub enum Nonterminal {
377377
NtExpr(P<ast::Expr>),
378378
NtTy(P<ast::Ty>),
379379
NtIdent(Box<ast::Ident>, IdentStyle),
380+
NtLifetime(Box<ast::Ident>),
380381
/// Stuff inside brackets for attributes
381382
NtMeta(P<ast::MetaItem>),
382383
NtPath(Box<ast::Path>),
@@ -399,6 +400,7 @@ impl fmt::Debug for Nonterminal {
399400
NtExpr(..) => f.pad("NtExpr(..)"),
400401
NtTy(..) => f.pad("NtTy(..)"),
401402
NtIdent(..) => f.pad("NtIdent(..)"),
403+
NtLifetime(..) => f.pad("NtLifetime(..)"),
402404
NtMeta(..) => f.pad("NtMeta(..)"),
403405
NtPath(..) => f.pad("NtPath(..)"),
404406
NtTT(..) => f.pad("NtTT(..)"),

src/libsyntax/print/pprust.rs

+1
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ pub fn token_to_string(tok: &Token) -> String {
296296
token::NtStmt(ref e) => stmt_to_string(&**e),
297297
token::NtPat(ref e) => pat_to_string(&**e),
298298
token::NtIdent(ref e, _) => ident_to_string(&**e),
299+
token::NtLifetime(ref e) => lifetime_to_string(&ast_util::name_to_dummy_lifetime(e.name)),
299300
token::NtTT(ref e) => tt_to_string(&**e),
300301
token::NtArm(ref e) => arm_to_string(&*e),
301302
token::NtImplItem(ref e) => impl_item_to_string(&**e),

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010

1111

1212
macro_rules! overly_complicated {
13-
($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path) =>
13+
($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path, $label:lifetime) =>
1414
({
15+
$label: loop { break $label; }
1516
fn $fnname($arg: $ty) -> Option<$ty> $body
1617
match $fnname($val) {
1718
Some($pat) => {
@@ -25,6 +26,6 @@ macro_rules! overly_complicated {
2526

2627
pub fn main() {
2728
assert!(overly_complicated!(f, x, Option<usize>, { return Some(x); },
28-
Some(8), Some(y), y) == 8)
29+
Some(8), Some(y), y, 'test) == 8)
2930

3031
}

0 commit comments

Comments
 (0)