Skip to content

Commit

Permalink
Add macro lifetime specifier
Browse files Browse the repository at this point in the history
Allows accepting a lifetime as a parameter to a macro
  • Loading branch information
Diggsey committed May 16, 2015
1 parent 6403a2f commit 68c41a1
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 5 deletions.
8 changes: 8 additions & 0 deletions src/libsyntax/ext/tt/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,14 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
&token_str[..])))
}
},
"lifetime" => match p.token {
token::Lifetime(sn) => { panictry!(p.bump()); token::NtLifetime(Box::new(sn)) }
_ => {
let token_str = pprust::token_to_string(&p.token);
panic!(p.fatal(&format!("expected lifetime, found {}",
&token_str[..])))
}
},
"path" => {
token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
}
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ext/tt/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,8 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> {
_ => Ok(false)
}
},
"ident" => {
// being a single token, idents are harmless
"ident" | "lifetime" => {
// being a single token, idents and lifetimes are harmless
Ok(true)
},
"meta" | "tt" => {
Expand Down
7 changes: 6 additions & 1 deletion src/libsyntax/ext/tt/transcribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use codemap::{Span, DUMMY_SP};
use diagnostic::SpanHandler;
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
use parse::token::{Eof, DocComment, Interpolated, MatchNt, SubstNt};
use parse::token::{Token, NtIdent, SpecialMacroVar};
use parse::token::{Token, NtIdent, NtLifetime, SpecialMacroVar};
use parse::token;
use parse::lexer::TokenAndSpan;

Expand Down Expand Up @@ -299,6 +299,11 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
r.cur_tok = token::Ident(**sn, b);
return ret_val;
}
MatchedNonterminal(NtLifetime(ref sn)) => {
r.cur_span = sp;
r.cur_tok = token::Lifetime(**sn);
return ret_val;
}
MatchedNonterminal(ref other_whole_nt) => {
// FIXME(pcwalton): Bad copy.
r.cur_span = sp;
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,8 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
token::NtIdent(id, is_mod_name) =>
token::NtIdent(Box::new(fld.fold_ident(*id)), is_mod_name),
token::NtLifetime(id) => token::NtLifetime(Box::new(
fld.fold_lifetime(ast_util::name_to_dummy_lifetime(id.name)).name.ident())),
token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))),
token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&*tt))),
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ impl<'a> Parser<'a> {
token::Interpolated(token::NtIdent(..)) => {
self.bug("ident interpolation not converted to real token");
}
token::Interpolated(token::NtLifetime(..)) => {
self.bug("lifetime interpolation not converted to real token");
}
_ => {
let token_str = self.this_token_to_string();
Err(self.fatal(&format!("expected ident, found `{}`",
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ pub enum Nonterminal {
NtExpr(P<ast::Expr>),
NtTy(P<ast::Ty>),
NtIdent(Box<ast::Ident>, IdentStyle),
NtLifetime(Box<ast::Ident>),
/// Stuff inside brackets for attributes
NtMeta(P<ast::MetaItem>),
NtPath(Box<ast::Path>),
Expand All @@ -399,6 +400,7 @@ impl fmt::Debug for Nonterminal {
NtExpr(..) => f.pad("NtExpr(..)"),
NtTy(..) => f.pad("NtTy(..)"),
NtIdent(..) => f.pad("NtIdent(..)"),
NtLifetime(..) => f.pad("NtLifetime(..)"),
NtMeta(..) => f.pad("NtMeta(..)"),
NtPath(..) => f.pad("NtPath(..)"),
NtTT(..) => f.pad("NtTT(..)"),
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ pub fn token_to_string(tok: &Token) -> String {
token::NtStmt(ref e) => stmt_to_string(&**e),
token::NtPat(ref e) => pat_to_string(&**e),
token::NtIdent(ref e, _) => ident_to_string(&**e),
token::NtLifetime(ref e) => lifetime_to_string(&ast_util::name_to_dummy_lifetime(e.name)),
token::NtTT(ref e) => tt_to_string(&**e),
token::NtArm(ref e) => arm_to_string(&*e),
token::NtImplItem(ref e) => impl_item_to_string(&**e),
Expand Down
5 changes: 3 additions & 2 deletions src/test/run-pass/macro-interpolation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@


macro_rules! overly_complicated {
($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path) =>
($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path, $label:lifetime) =>
({
$label: loop { break $label; }
fn $fnname($arg: $ty) -> Option<$ty> $body
match $fnname($val) {
Some($pat) => {
Expand All @@ -25,6 +26,6 @@ macro_rules! overly_complicated {

pub fn main() {
assert!(overly_complicated!(f, x, Option<usize>, { return Some(x); },
Some(8), Some(y), y) == 8)
Some(8), Some(y), y, 'test) == 8)

}

0 comments on commit 68c41a1

Please sign in to comment.