Auto merge of #34925 - jseyfried:nested_macros, r=eddyb
Support nested `macro_rules!` Fixes #6994. r? @eddyb
This commit is contained in:
commit
fd1d3603d4
2 changed files with 14 additions and 1 deletions
|
@ -258,6 +258,7 @@ pub struct Parser<'a> {
|
||||||
pub tokens_consumed: usize,
|
pub tokens_consumed: usize,
|
||||||
pub restrictions: Restrictions,
|
pub restrictions: Restrictions,
|
||||||
pub quote_depth: usize, // not (yet) related to the quasiquoter
|
pub quote_depth: usize, // not (yet) related to the quasiquoter
|
||||||
|
parsing_token_tree: bool,
|
||||||
pub reader: Box<Reader+'a>,
|
pub reader: Box<Reader+'a>,
|
||||||
/// The set of seen errors about obsolete syntax. Used to suppress
|
/// The set of seen errors about obsolete syntax. Used to suppress
|
||||||
/// extra detail when the same error is seen twice
|
/// extra detail when the same error is seen twice
|
||||||
|
@ -374,6 +375,7 @@ impl<'a> Parser<'a> {
|
||||||
tokens_consumed: 0,
|
tokens_consumed: 0,
|
||||||
restrictions: Restrictions::empty(),
|
restrictions: Restrictions::empty(),
|
||||||
quote_depth: 0,
|
quote_depth: 0,
|
||||||
|
parsing_token_tree: false,
|
||||||
obsolete_set: HashSet::new(),
|
obsolete_set: HashSet::new(),
|
||||||
mod_path_stack: Vec::new(),
|
mod_path_stack: Vec::new(),
|
||||||
filename: filename,
|
filename: filename,
|
||||||
|
@ -2663,7 +2665,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_unknown_macro_variable(&mut self) {
|
pub fn check_unknown_macro_variable(&mut self) {
|
||||||
if self.quote_depth == 0 {
|
if self.quote_depth == 0 && !self.parsing_token_tree {
|
||||||
match self.token {
|
match self.token {
|
||||||
token::SubstNt(name) =>
|
token::SubstNt(name) =>
|
||||||
self.fatal(&format!("unknown macro variable `{}`", name)).emit(),
|
self.fatal(&format!("unknown macro variable `{}`", name)).emit(),
|
||||||
|
@ -2723,6 +2725,7 @@ impl<'a> Parser<'a> {
|
||||||
Err(err)
|
Err(err)
|
||||||
},
|
},
|
||||||
token::OpenDelim(delim) => {
|
token::OpenDelim(delim) => {
|
||||||
|
let parsing_token_tree = ::std::mem::replace(&mut self.parsing_token_tree, true);
|
||||||
// The span for beginning of the delimited section
|
// The span for beginning of the delimited section
|
||||||
let pre_span = self.span;
|
let pre_span = self.span;
|
||||||
|
|
||||||
|
@ -2787,6 +2790,7 @@ impl<'a> Parser<'a> {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.parsing_token_tree = parsing_token_tree;
|
||||||
Ok(TokenTree::Delimited(span, Rc::new(Delimited {
|
Ok(TokenTree::Delimited(span, Rc::new(Delimited {
|
||||||
delim: delim,
|
delim: delim,
|
||||||
open_span: open_span,
|
open_span: open_span,
|
||||||
|
|
|
@ -16,7 +16,16 @@ macro_rules! higher_order {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! outer {
|
||||||
|
($x:expr; $fragment:ident) => {
|
||||||
|
macro_rules! inner { ($y:$fragment) => { $x + $y } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let val = higher_order!(subst ($x:expr, $y:expr, $foo:expr) => (($x + $y, $foo)));
|
let val = higher_order!(subst ($x:expr, $y:expr, $foo:expr) => (($x + $y, $foo)));
|
||||||
assert_eq!(val, (3, "foo"));
|
assert_eq!(val, (3, "foo"));
|
||||||
|
|
||||||
|
outer!(2; expr);
|
||||||
|
assert_eq!(inner!(3), 5);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue