diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-12-01 11:20:04 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-12-18 23:26:30 +0000 |
| commit | 421c5d11c1b4bb591bb429577c7b89cba59acefa (patch) | |
| tree | 355c3ca1ff8926f985ce2dbce5cb8b2e8df85b0c /src/libsyntax/ext | |
| parent | e80d1a8faf2da8df494828e2772e2d2043282fed (diff) | |
| download | rust-421c5d11c1b4bb591bb429577c7b89cba59acefa.tar.gz rust-421c5d11c1b4bb591bb429577c7b89cba59acefa.zip | |
Remove scope placeholders, remove method `add_macro` of `ext::base::Resolver`.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/ext/placeholders.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 34 |
4 files changed, 38 insertions, 85 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 508c5eaed8c..f9364f39ab7 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -520,7 +520,6 @@ pub trait Resolver { fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item>; fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion); - fn add_macro(&mut self, scope: Mark, def: ast::MacroDef); fn add_ext(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>); fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec<Mark>); @@ -544,7 +543,6 @@ impl Resolver for DummyResolver { fn eliminate_crate_var(&mut self, item: P<ast::Item>) -> P<ast::Item> { item } fn visit_expansion(&mut self, _invoc: Mark, _expansion: &Expansion) {} - fn add_macro(&mut self, _scope: Mark, _def: ast::MacroDef) {} fn add_ext(&mut self, _ident: ast::Ident, _ext: Rc<SyntaxExtension>) {} fn add_expansions_at_stmt(&mut self, _id: ast::NodeId, _macros: Vec<Mark>) {} diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 19545e2e642..05501b5434a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -392,14 +392,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let Mac_ { path, tts, .. } = mac.node; - // Detect use of feature-gated or invalid attributes on macro invoations - // since they will not be detected after macro expansion. - for attr in attrs.iter() { - feature_gate::check_attribute(&attr, &self.cx.parse_sess, - &self.cx.parse_sess.codemap(), - &self.cx.ecfg.features.unwrap()); - } - let extname = path.segments.last().unwrap().identifier.name; let ident = ident.unwrap_or(keywords::Invalid.ident()); let marked_tts = mark_tts(&tts, mark); @@ -601,6 +593,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect_bang( &mut self, mac: ast::Mac, attrs: Vec<ast::Attribute>, span: Span, kind: ExpansionKind, ) -> Expansion { + self.check_attributes(&attrs); self.collect(kind, InvocationKind::Bang { attrs: attrs, mac: mac, ident: None, span: span }) } @@ -622,6 +615,16 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> { self.cfg.configure(node) } + + // Detect use of feature-gated or invalid attributes on macro invocations + // since they will not be detected after macro expansion. + fn check_attributes(&mut self, attrs: &[ast::Attribute]) { + let codemap = &self.cx.parse_sess.codemap(); + let features = self.cx.ecfg.features.unwrap(); + for attr in attrs.iter() { + feature_gate::check_attribute(&attr, &self.cx.parse_sess, codemap, features); + } + } } // These are pretty nasty. Ideally, we would keep the tokens around, linked from @@ -740,14 +743,18 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { match item.node { ast::ItemKind::Mac(..) => { - if match item.node { - ItemKind::Mac(ref mac) => mac.node.path.segments.is_empty(), - _ => unreachable!(), - } { - return SmallVector::one(item); - } + self.check_attributes(&item.attrs); + let is_macro_def = if let ItemKind::Mac(ref mac) = item.node { + mac.node.path.segments[0].identifier.name == "macro_rules" + } else { + unreachable!() + }; - item.and_then(|item| match item.node { + item.and_then(|mut item| match item.node { + ItemKind::Mac(_) if is_macro_def => { + item.id = ast::NodeId::from_u32(Mark::fresh().as_u32()); + SmallVector::one(P(item)) + } ItemKind::Mac(mac) => { self.collect(ExpansionKind::Items, InvocationKind::Bang { mac: mac, diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 4fe57a8345e..eb4b6144c8d 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -12,9 +12,10 @@ use ast; use codemap::{DUMMY_SP, dummy_spanned}; use ext::base::ExtCtxt; use ext::expand::{Expansion, ExpansionKind}; +use ext::hygiene::Mark; use fold::*; use ptr::P; -use symbol::{Symbol, keywords}; +use symbol::keywords; use util::move_map::MoveMap; use util::small_vector::SmallVector; @@ -68,10 +69,6 @@ pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion { } } -pub fn macro_scope_placeholder() -> Expansion { - placeholder(ExpansionKind::Items, ast::DUMMY_NODE_ID) -} - pub struct PlaceholderExpander<'a, 'b: 'a> { expansions: HashMap<ast::NodeId, Expansion>, cx: &'a mut ExtCtxt<'b>, @@ -100,11 +97,12 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> { impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> { fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> { match item.node { - // Scope placeholder - ast::ItemKind::Mac(_) if item.id == ast::DUMMY_NODE_ID => SmallVector::one(item), - ast::ItemKind::Mac(_) => self.remove(item.id).make_items(), - _ => noop_fold_item(item, self), + ast::ItemKind::Mac(ref mac) if !mac.node.path.segments.is_empty() => {} + ast::ItemKind::Mac(_) => return self.remove(item.id).make_items(), + _ => {} } + + noop_fold_item(item, self) } fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> { @@ -172,10 +170,10 @@ impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> { block.stmts = block.stmts.move_flat_map(|mut stmt| { remaining_stmts -= 1; - // Scope placeholder + // `macro_rules!` macro definition if let ast::StmtKind::Item(ref item) = stmt.node { - if let ast::ItemKind::Mac(..) = item.node { - macros.push(item.ident.ctxt.data().outer_mark); + if let ast::ItemKind::Mac(_) = item.node { + macros.push(Mark::from_placeholder_id(item.id)); return None; } } @@ -208,33 +206,13 @@ impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> { fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod { let mut module = noop_fold_mod(module, self); module.items = module.items.move_flat_map(|item| match item.node { - ast::ItemKind::Mac(_) => None, // remove scope placeholders from modules + ast::ItemKind::Mac(_) if !self.cx.ecfg.keep_macs => None, // remove macro definitions _ => Some(item), }); module } -} -pub fn reconstructed_macro_rules(def: &ast::MacroDef) -> Expansion { - Expansion::Items(SmallVector::one(P(ast::Item { - ident: def.ident, - attrs: def.attrs.clone(), - id: ast::DUMMY_NODE_ID, - node: ast::ItemKind::Mac(ast::Mac { - span: def.span, - node: ast::Mac_ { - path: ast::Path { - span: DUMMY_SP, - global: false, - segments: vec![ast::PathSegment { - identifier: ast::Ident::with_empty_ctxt(Symbol::intern("macro_rules")), - parameters: ast::PathParameters::none(), - }], - }, - tts: def.body.clone(), - } - }), - vis: ast::Visibility::Inherited, - span: def.span, - }))) + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + mac + } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 5a028594a21..3abd24b50ba 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -10,10 +10,9 @@ use {ast, attr}; use syntax_pos::{Span, DUMMY_SP}; -use ext::base::{DummyResult, ExtCtxt, MacEager, MacResult, SyntaxExtension}; -use ext::base::{IdentMacroExpander, NormalTT, TTMacroExpander}; +use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension}; +use ext::base::{NormalTT, TTMacroExpander}; use ext::expand::{Expansion, ExpansionKind}; -use ext::placeholders; use ext::tt::macro_parser::{Success, Error, Failure}; use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use ext::tt::macro_parser::{parse, parse_failure_msg}; @@ -151,35 +150,6 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg); } -pub struct MacroRulesExpander; -impl IdentMacroExpander for MacroRulesExpander { - fn expand(&self, - cx: &mut ExtCtxt, - span: Span, - ident: ast::Ident, - tts: Vec<tokenstream::TokenTree>, - attrs: Vec<ast::Attribute>) - -> Box<MacResult> { - let def = ast::MacroDef { - ident: ident, - id: ast::DUMMY_NODE_ID, - span: span, - body: tts, - attrs: attrs, - }; - - // If keep_macs is true, expands to a MacEager::items instead. - let result = if cx.ecfg.keep_macs { - MacEager::items(placeholders::reconstructed_macro_rules(&def).make_items()) - } else { - MacEager::items(placeholders::macro_scope_placeholder().make_items()) - }; - - cx.resolver.add_macro(cx.current_expansion.mark, def); - result - } -} - // Note that macro-by-example's input is also matched against a token tree: // $( $lhs:tt => $rhs:tt );+ // |
