提交 85b8b447 编写于 作者: A Andrew Paseltiner

Replace `ast::Mac_` enum with struct

Closes #28527.
上级 f5a64a67
......@@ -28,7 +28,6 @@
pub use self::KleeneOp::*;
pub use self::Lit_::*;
pub use self::LitIntType::*;
pub use self::Mac_::*;
pub use self::MacStmtStyle::*;
pub use self::MetaItem_::*;
pub use self::Mutability::*;
......@@ -1132,12 +1131,13 @@ pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
/// is being invoked, and the vector of token-trees contains the source
/// of the macro invocation.
///
/// There's only one flavor, now, so this could presumably be simplified.
/// NB: the additional ident for a macro_rules-style macro is actually
/// stored in the enclosing item. Oog.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Mac_ {
// NB: the additional ident for a macro_rules-style macro is actually
// stored in the enclosing item. Oog.
MacInvocTT(Path, Vec<TokenTree>, SyntaxContext), // new macro-invocation
pub struct Mac_ {
pub path: Path,
pub tts: Vec<TokenTree>,
pub ctxt: SyntaxContext,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
......
......@@ -9,7 +9,7 @@
// except according to those terms.
use ast::{Block, Crate, DeclLocal, ExprMac, PatMac};
use ast::{Local, Ident, MacInvocTT};
use ast::{Local, Ident, Mac_};
use ast::{ItemMac, MacStmtWithSemicolon, Mrk, Stmt, StmtDecl, StmtMac};
use ast::{StmtExpr, StmtSemi};
use ast::TokenTree;
......@@ -509,78 +509,75 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
F: for<'a> FnOnce(Box<MacResult+'a>) -> Option<T>,
G: FnOnce(T, Mrk) -> T,
{
match mac.node {
// it would almost certainly be cleaner to pass the whole
// macro invocation in, rather than pulling it apart and
// marking the tts and the ctxt separately. This also goes
// for the other three macro invocation chunks of code
// in this file.
// Token-tree macros:
MacInvocTT(pth, tts, _) => {
if pth.segments.len() > 1 {
fld.cx.span_err(pth.span,
"expected macro name without module \
separators");
// let compilation continue
return None;
}
let extname = pth.segments[0].identifier.name;
match fld.cx.syntax_env.find(&extname) {
None => {
fld.cx.span_err(
pth.span,
&format!("macro undefined: '{}!'",
&extname));
// it would almost certainly be cleaner to pass the whole
// macro invocation in, rather than pulling it apart and
// marking the tts and the ctxt separately. This also goes
// for the other three macro invocation chunks of code
// in this file.
let Mac_ { path: pth, tts, .. } = mac.node;
if pth.segments.len() > 1 {
fld.cx.span_err(pth.span,
"expected macro name without module \
separators");
// let compilation continue
return None;
}
let extname = pth.segments[0].identifier.name;
match fld.cx.syntax_env.find(&extname) {
None => {
fld.cx.span_err(
pth.span,
&format!("macro undefined: '{}!'",
&extname));
// let compilation continue
None
}
Some(rc) => match *rc {
NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
fld.cx.bt_push(ExpnInfo {
call_site: span,
callee: NameAndSpan {
format: MacroBang(extname),
span: exp_span,
allow_internal_unstable: allow_internal_unstable,
},
});
let fm = fresh_mark();
let marked_before = mark_tts(&tts[..], fm);
// The span that we pass to the expanders we want to
// be the root of the call stack. That's the most
// relevant span and it's the actual invocation of
// the macro.
let mac_span = fld.cx.original_span();
let opt_parsed = {
let expanded = expandfun.expand(fld.cx,
mac_span,
&marked_before[..]);
parse_thunk(expanded)
};
let parsed = match opt_parsed {
Some(e) => e,
None => {
fld.cx.span_err(
pth.span,
&format!("non-expression macro in expression position: {}",
extname
));
return None;
}
};
Some(mark_thunk(parsed,fm))
}
_ => {
// let compilation continue
None
}
Some(rc) => match *rc {
NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
fld.cx.bt_push(ExpnInfo {
call_site: span,
callee: NameAndSpan {
format: MacroBang(extname),
span: exp_span,
allow_internal_unstable: allow_internal_unstable,
},
});
let fm = fresh_mark();
let marked_before = mark_tts(&tts[..], fm);
// The span that we pass to the expanders we want to
// be the root of the call stack. That's the most
// relevant span and it's the actual invocation of
// the macro.
let mac_span = fld.cx.original_span();
let opt_parsed = {
let expanded = expandfun.expand(fld.cx,
mac_span,
&marked_before[..]);
parse_thunk(expanded)
};
let parsed = match opt_parsed {
Some(e) => e,
None => {
fld.cx.span_err(
pth.span,
&format!("'{}' is not a tt-style macro",
extname));
None
&format!("non-expression macro in expression position: {}",
extname
));
return None;
}
}
};
Some(mark_thunk(parsed,fm))
}
_ => {
fld.cx.span_err(
pth.span,
&format!("'{}' is not a tt-style macro",
extname));
None
}
}
}
......@@ -684,15 +681,11 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool
// logic as for expression-position macro invocations.
pub fn expand_item_mac(it: P<ast::Item>,
fld: &mut MacroExpander) -> SmallVector<P<ast::Item>> {
let (extname, path_span, tts, span, attrs, ident) = it.and_then(|it| { match it.node {
ItemMac(codemap::Spanned {
node: MacInvocTT(pth, tts, _),
..
}) => {
(pth.segments[0].identifier.name, pth.span, tts, it.span, it.attrs, it.ident)
}
let (extname, path_span, tts, span, attrs, ident) = it.and_then(|it| match it.node {
ItemMac(codemap::Spanned { node: Mac_ { path, tts, .. }, .. }) =>
(path.segments[0].identifier.name, path.span, tts, it.span, it.attrs, it.ident),
_ => fld.cx.span_bug(it.span, "invalid item macro invocation")
}});
});
let fm = fresh_mark();
let items = {
......@@ -1060,11 +1053,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
}
p.map(|ast::Pat {node, span, ..}| {
let (pth, tts) = match node {
PatMac(mac) => match mac.node {
MacInvocTT(pth, tts, _) => {
(pth, tts)
}
},
PatMac(mac) => (mac.node.path, mac.node.tts),
_ => unreachable!()
};
if pth.segments.len() > 1 {
......@@ -1646,12 +1635,10 @@ fn fold_ident(&mut self, id: Ident) -> Ident {
}
fn fold_mac(&mut self, Spanned {node, span}: ast::Mac) -> ast::Mac {
Spanned {
node: match node {
MacInvocTT(path, tts, ctxt) => {
MacInvocTT(self.fold_path(path),
self.fold_tts(&tts[..]),
mtwt::apply_mark(self.mark, ctxt))
}
node: Mac_ {
path: self.fold_path(node.path),
tts: self.fold_tts(&node.tts),
ctxt: mtwt::apply_mark(self.mark, node.ctxt),
},
span: span,
}
......
......@@ -666,7 +666,7 @@ struct MacroVisitor<'a> {
impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
fn visit_mac(&mut self, mac: &ast::Mac) {
let ast::MacInvocTT(ref path, _, _) = mac.node;
let path = &mac.node.path;
let id = path.segments.last().unwrap().identifier;
// Issue 22234: If you add a new case here, make sure to also
......
......@@ -567,10 +567,10 @@ pub fn noop_fold_explicit_self<T: Folder>(Spanned {span, node}: ExplicitSelf, fl
pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac {
Spanned {
node: match node {
MacInvocTT(p, tts, ctxt) => {
MacInvocTT(fld.fold_path(p), fld.fold_tts(&tts), ctxt)
}
node: Mac_ {
path: fld.fold_path(node.path),
tts: fld.fold_tts(&node.tts),
ctxt: node.ctxt,
},
span: fld.new_span(span)
}
......
......@@ -1090,10 +1090,7 @@ fn ttdelim_span() {
"foo!( fn main() { body } )".to_string(), vec![], &sess);
let tts = match expr.node {
ast::ExprMac(ref mac) => {
let ast::MacInvocTT(_, ref tts, _) = mac.node;
tts.clone()
}
ast::ExprMac(ref mac) => mac.node.tts.clone(),
_ => panic!("not a macro"),
};
......
......@@ -37,7 +37,7 @@
use ast::{LitBool, LitChar, LitByte, LitByteStr};
use ast::{LitStr, LitInt, Local};
use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces};
use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource};
use ast::{MutImmutable, MutMutable, Mac_, MatchSource};
use ast::{MutTy, BiMul, Mutability};
use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange};
......@@ -1381,7 +1381,7 @@ pub fn parse_ty_nopanic(&mut self) -> PResult<P<Ty>> {
seq_sep_none(),
|p| p.parse_token_tree()));
let hi = self.span.hi;
TyMac(spanned(lo, hi, MacInvocTT(path, tts, EMPTY_CTXT)))
TyMac(spanned(lo, hi, Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT }))
} else {
// NAMED TYPE
TyPath(None, path)
......@@ -2203,9 +2203,7 @@ pub fn parse_bottom_expr(&mut self) -> PResult<P<Expr>> {
return Ok(self.mk_mac_expr(lo,
hi,
MacInvocTT(pth,
tts,
EMPTY_CTXT)));
Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT }));
}
if self.check(&token::OpenDelim(token::Brace)) {
// This is a struct literal, unless we're prohibited
......@@ -3289,7 +3287,7 @@ pub fn parse_pat_nopanic(&mut self) -> PResult<P<Pat>> {
let delim = try!(self.expect_open_delim());
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
seq_sep_none(), |p| p.parse_token_tree()));
let mac = MacInvocTT(path, tts, EMPTY_CTXT);
let mac = Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT };
pat = PatMac(codemap::Spanned {node: mac, span: self.span});
} else {
// Parse ident @ pat
......@@ -3557,7 +3555,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
spanned(lo, hi,
StmtMac(P(spanned(lo,
hi,
MacInvocTT(pth, tts, EMPTY_CTXT))),
Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })),
style))
} else {
// if it has a special ident, it's definitely an item
......@@ -3576,7 +3574,8 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
P(spanned(lo, hi, DeclItem(
self.mk_item(
lo, hi, id /*id is good here*/,
ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
ItemMac(spanned(lo, hi,
Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })),
Inherited, Vec::new(/*no attrs*/))))),
ast::DUMMY_NODE_ID))
}
......@@ -4524,7 +4523,7 @@ fn parse_impl_method(&mut self, vis: Visibility)
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
seq_sep_none(),
|p| p.parse_token_tree()));
let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
let m: ast::Mac = codemap::Spanned { node: m_,
span: mk_sp(self.span.lo,
self.span.hi) };
......@@ -5606,7 +5605,7 @@ fn parse_macro_use_or_failure(
seq_sep_none(),
|p| p.parse_token_tree()));
// single-variant-enum... :
let m = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
let m = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
let m: ast::Mac = codemap::Spanned { node: m,
span: mk_sp(self.span.lo,
self.span.hi) };
......
......@@ -1307,16 +1307,14 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
}
try!(self.bclose(item.span));
}
// I think it's reasonable to hide the context here:
ast::ItemMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
..}) => {
ast::ItemMac(codemap::Spanned { ref node, .. }) => {
try!(self.print_visibility(item.vis));
try!(self.print_path(pth, false, 0));
try!(self.print_path(&node.path, false, 0));
try!(word(&mut self.s, "! "));
try!(self.print_ident(item.ident));
try!(self.cbox(indent_unit));
try!(self.popen());
try!(self.print_tts(&tts[..]));
try!(self.print_tts(&node.tts[..]));
try!(self.pclose());
try!(word(&mut self.s, ";"));
try!(self.end());
......@@ -1599,14 +1597,13 @@ pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
ast::TypeImplItem(ref ty) => {
try!(self.print_associated_type(ii.ident, None, Some(ty)));
}
ast::MacImplItem(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
..}) => {
ast::MacImplItem(codemap::Spanned { ref node, .. }) => {
// code copied from ItemMac:
try!(self.print_path(pth, false, 0));
try!(self.print_path(&node.path, false, 0));
try!(word(&mut self.s, "! "));
try!(self.cbox(indent_unit));
try!(self.popen());
try!(self.print_tts(&tts[..]));
try!(self.print_tts(&node.tts[..]));
try!(self.pclose());
try!(word(&mut self.s, ";"));
try!(self.end())
......@@ -1765,23 +1762,18 @@ pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Bloc
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
-> io::Result<()> {
match m.node {
// I think it's reasonable to hide the ctxt here:
ast::MacInvocTT(ref pth, ref tts, _) => {
try!(self.print_path(pth, false, 0));
try!(word(&mut self.s, "!"));
match delim {
token::Paren => try!(self.popen()),
token::Bracket => try!(word(&mut self.s, "[")),
token::Brace => try!(self.bopen()),
}
try!(self.print_tts(tts));
match delim {
token::Paren => self.pclose(),
token::Bracket => word(&mut self.s, "]"),
token::Brace => self.bclose(m.span),
}
}
try!(self.print_path(&m.node.path, false, 0));
try!(word(&mut self.s, "!"));
match delim {
token::Paren => try!(self.popen()),
token::Bracket => try!(word(&mut self.s, "[")),
token::Brace => try!(self.bopen()),
}
try!(self.print_tts(&m.node.tts));
match delim {
token::Paren => self.pclose(),
token::Bracket => word(&mut self.s, "]"),
token::Brace => self.bclose(m.span),
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册