diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 58d92f5001a..7b2b2c90126 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -28,7 +28,6 @@ pub use self::Item_::*; 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 type Mac = Spanned; /// 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, SyntaxContext), // new macro-invocation +pub struct Mac_ { + pub path: Path, + pub tts: Vec, + pub ctxt: SyntaxContext, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ffbb7edd385..6e0fbbec770 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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(mac: ast::Mac, F: for<'a> FnOnce(Box) -> Option, 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 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); + 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)); - // 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 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); - 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)) - } - _ => { + // 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, fld: &mut MacroExpander) -> SmallVector> { - 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, fld: &mut MacroExpander) -> P { } 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 @@ impl Folder for Marker { } 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, } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 16d44e5046c..be95b58bf88 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -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 diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index a73cc420eeb..e97c763ca4c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -567,10 +567,10 @@ pub fn noop_fold_explicit_self(Spanned {span, node}: ExplicitSelf, fl pub fn noop_fold_mac(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) } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 269f8bdd98a..279c987fcba 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -1090,10 +1090,7 @@ mod tests { "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"), }; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 581c28a44fd..6220bd6fa6f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -37,7 +37,7 @@ use ast::{LifetimeDef, Lit, Lit_}; 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { 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) }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6de6d32dfb3..915abd4c0eb 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1307,16 +1307,14 @@ impl<'a> State<'a> { } 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 @@ impl<'a> State<'a> { 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 @@ impl<'a> State<'a> { 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), } }