1
Fork 0

Replace ast::Mac_ enum with struct

Closes #28527.
This commit is contained in:
Andrew Paseltiner 2015-09-20 16:15:37 -04:00
parent f5a64a678f
commit 85b8b447fa
7 changed files with 112 additions and 137 deletions

View file

@ -28,7 +28,6 @@ pub use self::Item_::*;
pub use self::KleeneOp::*; pub use self::KleeneOp::*;
pub use self::Lit_::*; pub use self::Lit_::*;
pub use self::LitIntType::*; pub use self::LitIntType::*;
pub use self::Mac_::*;
pub use self::MacStmtStyle::*; pub use self::MacStmtStyle::*;
pub use self::MetaItem_::*; pub use self::MetaItem_::*;
pub use self::Mutability::*; pub use self::Mutability::*;
@ -1132,12 +1131,13 @@ pub type Mac = Spanned<Mac_>;
/// is being invoked, and the vector of token-trees contains the source /// is being invoked, and the vector of token-trees contains the source
/// of the macro invocation. /// 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)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Mac_ { pub struct Mac_ {
// NB: the additional ident for a macro_rules-style macro is actually pub path: Path,
// stored in the enclosing item. Oog. pub tts: Vec<TokenTree>,
MacInvocTT(Path, Vec<TokenTree>, SyntaxContext), // new macro-invocation pub ctxt: SyntaxContext,
} }
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use ast::{Block, Crate, DeclLocal, ExprMac, PatMac}; 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::{ItemMac, MacStmtWithSemicolon, Mrk, Stmt, StmtDecl, StmtMac};
use ast::{StmtExpr, StmtSemi}; use ast::{StmtExpr, StmtSemi};
use ast::TokenTree; 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>, F: for<'a> FnOnce(Box<MacResult+'a>) -> Option<T>,
G: FnOnce(T, Mrk) -> T, G: FnOnce(T, Mrk) -> T,
{ {
match mac.node { // it would almost certainly be cleaner to pass the whole
// it would almost certainly be cleaner to pass the whole // macro invocation in, rather than pulling it apart and
// macro invocation in, rather than pulling it apart and // marking the tts and the ctxt separately. This also goes
// marking the tts and the ctxt separately. This also goes // for the other three macro invocation chunks of code
// for the other three macro invocation chunks of code // in this file.
// 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));
// let compilation continue let Mac_ { path: pth, tts, .. } = mac.node;
None if pth.segments.len() > 1 {
} fld.cx.span_err(pth.span,
Some(rc) => match *rc { "expected macro name without module \
NormalTT(ref expandfun, exp_span, allow_internal_unstable) => { separators");
fld.cx.bt_push(ExpnInfo { // let compilation continue
call_site: span, return None;
callee: NameAndSpan { }
format: MacroBang(extname), let extname = pth.segments[0].identifier.name;
span: exp_span, match fld.cx.syntax_env.find(&extname) {
allow_internal_unstable: allow_internal_unstable, None => {
}, fld.cx.span_err(
}); pth.span,
let fm = fresh_mark(); &format!("macro undefined: '{}!'",
let marked_before = mark_tts(&tts[..], fm); &extname));
// The span that we pass to the expanders we want to // let compilation continue
// be the root of the call stack. That's the most None
// relevant span and it's the actual invocation of }
// the macro. Some(rc) => match *rc {
let mac_span = fld.cx.original_span(); 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);
let opt_parsed = { // The span that we pass to the expanders we want to
let expanded = expandfun.expand(fld.cx, // be the root of the call stack. That's the most
mac_span, // relevant span and it's the actual invocation of
&marked_before[..]); // the macro.
parse_thunk(expanded) let mac_span = fld.cx.original_span();
};
let parsed = match opt_parsed { let opt_parsed = {
Some(e) => e, let expanded = expandfun.expand(fld.cx,
None => { mac_span,
fld.cx.span_err( &marked_before[..]);
pth.span, parse_thunk(expanded)
&format!("non-expression macro in expression position: {}", };
extname let parsed = match opt_parsed {
)); Some(e) => e,
return None; None => {
}
};
Some(mark_thunk(parsed,fm))
}
_ => {
fld.cx.span_err( fld.cx.span_err(
pth.span, pth.span,
&format!("'{}' is not a tt-style macro", &format!("non-expression macro in expression position: {}",
extname)); extname
None ));
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. // logic as for expression-position macro invocations.
pub fn expand_item_mac(it: P<ast::Item>, pub fn expand_item_mac(it: P<ast::Item>,
fld: &mut MacroExpander) -> SmallVector<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 { let (extname, path_span, tts, span, attrs, ident) = it.and_then(|it| match it.node {
ItemMac(codemap::Spanned { ItemMac(codemap::Spanned { node: Mac_ { path, tts, .. }, .. }) =>
node: MacInvocTT(pth, tts, _), (path.segments[0].identifier.name, path.span, tts, it.span, it.attrs, it.ident),
..
}) => {
(pth.segments[0].identifier.name, pth.span, tts, it.span, it.attrs, it.ident)
}
_ => fld.cx.span_bug(it.span, "invalid item macro invocation") _ => fld.cx.span_bug(it.span, "invalid item macro invocation")
}}); });
let fm = fresh_mark(); let fm = fresh_mark();
let items = { 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, ..}| { p.map(|ast::Pat {node, span, ..}| {
let (pth, tts) = match node { let (pth, tts) = match node {
PatMac(mac) => match mac.node { PatMac(mac) => (mac.node.path, mac.node.tts),
MacInvocTT(pth, tts, _) => {
(pth, tts)
}
},
_ => unreachable!() _ => unreachable!()
}; };
if pth.segments.len() > 1 { if pth.segments.len() > 1 {
@ -1646,12 +1635,10 @@ impl Folder for Marker {
} }
fn fold_mac(&mut self, Spanned {node, span}: ast::Mac) -> ast::Mac { fn fold_mac(&mut self, Spanned {node, span}: ast::Mac) -> ast::Mac {
Spanned { Spanned {
node: match node { node: Mac_ {
MacInvocTT(path, tts, ctxt) => { path: self.fold_path(node.path),
MacInvocTT(self.fold_path(path), tts: self.fold_tts(&node.tts),
self.fold_tts(&tts[..]), ctxt: mtwt::apply_mark(self.mark, node.ctxt),
mtwt::apply_mark(self.mark, ctxt))
}
}, },
span: span, span: span,
} }

View file

@ -666,7 +666,7 @@ struct MacroVisitor<'a> {
impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> { impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
fn visit_mac(&mut self, mac: &ast::Mac) { 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; let id = path.segments.last().unwrap().identifier;
// Issue 22234: If you add a new case here, make sure to also // Issue 22234: If you add a new case here, make sure to also

View file

@ -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 { pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac {
Spanned { Spanned {
node: match node { node: Mac_ {
MacInvocTT(p, tts, ctxt) => { path: fld.fold_path(node.path),
MacInvocTT(fld.fold_path(p), fld.fold_tts(&tts), ctxt) tts: fld.fold_tts(&node.tts),
} ctxt: node.ctxt,
}, },
span: fld.new_span(span) span: fld.new_span(span)
} }

View file

@ -1090,10 +1090,7 @@ mod tests {
"foo!( fn main() { body } )".to_string(), vec![], &sess); "foo!( fn main() { body } )".to_string(), vec![], &sess);
let tts = match expr.node { let tts = match expr.node {
ast::ExprMac(ref mac) => { ast::ExprMac(ref mac) => mac.node.tts.clone(),
let ast::MacInvocTT(_, ref tts, _) = mac.node;
tts.clone()
}
_ => panic!("not a macro"), _ => panic!("not a macro"),
}; };

View file

@ -37,7 +37,7 @@ use ast::{LifetimeDef, Lit, Lit_};
use ast::{LitBool, LitChar, LitByte, LitByteStr}; use ast::{LitBool, LitChar, LitByte, LitByteStr};
use ast::{LitStr, LitInt, Local}; use ast::{LitStr, LitInt, Local};
use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; 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::{MutTy, BiMul, Mutability};
use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot}; use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange}; use ast::{Pat, PatBox, PatEnum, PatIdent, PatLit, PatQPath, PatMac, PatRange};
@ -1381,7 +1381,7 @@ impl<'a> Parser<'a> {
seq_sep_none(), seq_sep_none(),
|p| p.parse_token_tree())); |p| p.parse_token_tree()));
let hi = self.span.hi; 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 { } else {
// NAMED TYPE // NAMED TYPE
TyPath(None, path) TyPath(None, path)
@ -2203,9 +2203,7 @@ impl<'a> Parser<'a> {
return Ok(self.mk_mac_expr(lo, return Ok(self.mk_mac_expr(lo,
hi, hi,
MacInvocTT(pth, Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT }));
tts,
EMPTY_CTXT)));
} }
if self.check(&token::OpenDelim(token::Brace)) { if self.check(&token::OpenDelim(token::Brace)) {
// This is a struct literal, unless we're prohibited // This is a struct literal, unless we're prohibited
@ -3289,7 +3287,7 @@ impl<'a> Parser<'a> {
let delim = try!(self.expect_open_delim()); let delim = try!(self.expect_open_delim());
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim), let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
seq_sep_none(), |p| p.parse_token_tree())); 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}); pat = PatMac(codemap::Spanned {node: mac, span: self.span});
} else { } else {
// Parse ident @ pat // Parse ident @ pat
@ -3557,7 +3555,7 @@ impl<'a> Parser<'a> {
spanned(lo, hi, spanned(lo, hi,
StmtMac(P(spanned(lo, StmtMac(P(spanned(lo,
hi, hi,
MacInvocTT(pth, tts, EMPTY_CTXT))), Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })),
style)) style))
} else { } else {
// if it has a special ident, it's definitely an item // if it has a special ident, it's definitely an item
@ -3576,7 +3574,8 @@ impl<'a> Parser<'a> {
P(spanned(lo, hi, DeclItem( P(spanned(lo, hi, DeclItem(
self.mk_item( self.mk_item(
lo, hi, id /*id is good here*/, 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*/))))), Inherited, Vec::new(/*no attrs*/))))),
ast::DUMMY_NODE_ID)) ast::DUMMY_NODE_ID))
} }
@ -4524,7 +4523,7 @@ impl<'a> Parser<'a> {
let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim), let tts = try!(self.parse_seq_to_end(&token::CloseDelim(delim),
seq_sep_none(), seq_sep_none(),
|p| p.parse_token_tree())); |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_, let m: ast::Mac = codemap::Spanned { node: m_,
span: mk_sp(self.span.lo, span: mk_sp(self.span.lo,
self.span.hi) }; self.span.hi) };
@ -5606,7 +5605,7 @@ impl<'a> Parser<'a> {
seq_sep_none(), seq_sep_none(),
|p| p.parse_token_tree())); |p| p.parse_token_tree()));
// single-variant-enum... : // 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, let m: ast::Mac = codemap::Spanned { node: m,
span: mk_sp(self.span.lo, span: mk_sp(self.span.lo,
self.span.hi) }; self.span.hi) };

View file

@ -1307,16 +1307,14 @@ impl<'a> State<'a> {
} }
try!(self.bclose(item.span)); try!(self.bclose(item.span));
} }
// I think it's reasonable to hide the context here: ast::ItemMac(codemap::Spanned { ref node, .. }) => {
ast::ItemMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
..}) => {
try!(self.print_visibility(item.vis)); 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!(word(&mut self.s, "! "));
try!(self.print_ident(item.ident)); try!(self.print_ident(item.ident));
try!(self.cbox(indent_unit)); try!(self.cbox(indent_unit));
try!(self.popen()); try!(self.popen());
try!(self.print_tts(&tts[..])); try!(self.print_tts(&node.tts[..]));
try!(self.pclose()); try!(self.pclose());
try!(word(&mut self.s, ";")); try!(word(&mut self.s, ";"));
try!(self.end()); try!(self.end());
@ -1599,14 +1597,13 @@ impl<'a> State<'a> {
ast::TypeImplItem(ref ty) => { ast::TypeImplItem(ref ty) => {
try!(self.print_associated_type(ii.ident, None, Some(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: // 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!(word(&mut self.s, "! "));
try!(self.cbox(indent_unit)); try!(self.cbox(indent_unit));
try!(self.popen()); try!(self.popen());
try!(self.print_tts(&tts[..])); try!(self.print_tts(&node.tts[..]));
try!(self.pclose()); try!(self.pclose());
try!(word(&mut self.s, ";")); try!(word(&mut self.s, ";"));
try!(self.end()) try!(self.end())
@ -1765,23 +1762,18 @@ impl<'a> State<'a> {
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken) pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
-> io::Result<()> { -> io::Result<()> {
match m.node { try!(self.print_path(&m.node.path, false, 0));
// I think it's reasonable to hide the ctxt here: try!(word(&mut self.s, "!"));
ast::MacInvocTT(ref pth, ref tts, _) => { match delim {
try!(self.print_path(pth, false, 0)); token::Paren => try!(self.popen()),
try!(word(&mut self.s, "!")); token::Bracket => try!(word(&mut self.s, "[")),
match delim { token::Brace => try!(self.bopen()),
token::Paren => try!(self.popen()), }
token::Bracket => try!(word(&mut self.s, "[")), try!(self.print_tts(&m.node.tts));
token::Brace => try!(self.bopen()), match delim {
} token::Paren => self.pclose(),
try!(self.print_tts(tts)); token::Bracket => word(&mut self.s, "]"),
match delim { token::Brace => self.bclose(m.span),
token::Paren => self.pclose(),
token::Bracket => word(&mut self.s, "]"),
token::Brace => self.bclose(m.span),
}
}
} }
} }