diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2016-12-20 11:16:23 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-12-20 11:16:23 -0800 |
| commit | 551cb0646ff430f6bf80d1e5f331f8218c1c09b6 (patch) | |
| tree | 9c5568385abc1c56544b97bc579544b7e258524b /src/libsyntax/ext | |
| parent | 58d58c24dc9139004ff7679e84958fbecd05d59a (diff) | |
| parent | f705c69bf641b271828f37adb525cafc618237d8 (diff) | |
| download | rust-551cb0646ff430f6bf80d1e5f331f8218c1c09b6.tar.gz rust-551cb0646ff430f6bf80d1e5f331f8218c1c09b6.zip | |
Rollup merge of #38171 - jseyfried:cleanup, r=nrc
Miscellaneous cleanup/refactoring in `resolve` and `syntax::ext` r? @nrc
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 31 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 79 | ||||
| -rw-r--r-- | src/libsyntax/ext/hygiene.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/ext/placeholders.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 39 |
6 files changed, 85 insertions, 140 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index ddbca47429d..8e63f73fdaa 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -217,8 +217,7 @@ pub trait IdentMacroExpander { cx: &'cx mut ExtCtxt, sp: Span, ident: ast::Ident, - token_tree: Vec<tokenstream::TokenTree>, - attrs: Vec<ast::Attribute>) + token_tree: Vec<tokenstream::TokenTree>) -> Box<MacResult+'cx>; } @@ -234,8 +233,7 @@ impl<F> IdentMacroExpander for F cx: &'cx mut ExtCtxt, sp: Span, ident: ast::Ident, - token_tree: Vec<tokenstream::TokenTree>, - _attrs: Vec<ast::Attribute>) + token_tree: Vec<tokenstream::TokenTree>) -> Box<MacResult+'cx> { (*self)(cx, sp, ident, token_tree) @@ -520,7 +518,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, export: bool); 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 +541,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, _export: bool) {} 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/build.rs b/src/libsyntax/ext/build.rs index 6c0d40b69d3..c3dc64f9124 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -322,21 +322,17 @@ impl<'a> AstBuilder for ExtCtxt<'a> { bindings: Vec<ast::TypeBinding> ) -> ast::Path { let last_identifier = idents.pop().unwrap(); - let mut segments: Vec<ast::PathSegment> = idents.into_iter() - .map(|ident| { - ast::PathSegment { - identifier: ident, - parameters: ast::PathParameters::none(), - } - }).collect(); - segments.push(ast::PathSegment { - identifier: last_identifier, - parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData { + let mut segments: Vec<ast::PathSegment> = idents.into_iter().map(Into::into).collect(); + let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() { + None + } else { + Some(P(ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData { lifetimes: lifetimes, types: P::from_vec(types), bindings: P::from_vec(bindings), - }) - }); + }))) + }; + segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters }); ast::Path { span: sp, global: global, @@ -367,13 +363,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { bindings: Vec<ast::TypeBinding>) -> (ast::QSelf, ast::Path) { let mut path = trait_path; + let parameters = ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: P::from_vec(types), + bindings: P::from_vec(bindings), + }; path.segments.push(ast::PathSegment { identifier: ident, - parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData { - lifetimes: lifetimes, - types: P::from_vec(types), - bindings: P::from_vec(bindings), - }) + parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))), }); (ast::QSelf { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 19545e2e642..5d62175fbf2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -158,7 +158,6 @@ pub struct Invocation { pub enum InvocationKind { Bang { - attrs: Vec<ast::Attribute>, mac: ast::Mac, ident: Option<Ident>, span: Span, @@ -276,7 +275,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if expansions.len() < depth { expansions.push(Vec::new()); } - expansions[depth - 1].push((mark.as_u32(), expansion)); + expansions[depth - 1].push((mark, expansion)); if !self.cx.ecfg.single_step { invocations.extend(new_invocations.into_iter().rev()); } @@ -287,7 +286,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic); while let Some(expansions) = expansions.pop() { for (mark, expansion) in expansions.into_iter().rev() { - placeholder_expander.add(ast::NodeId::from_u32(mark), expansion); + placeholder_expander.add(mark.as_placeholder_id(), expansion); } } @@ -386,20 +385,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { /// Expand a macro invocation. Returns the result of expansion. fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> Expansion { let (mark, kind) = (invoc.expansion_data.mark, invoc.expansion_kind); - let (attrs, mac, ident, span) = match invoc.kind { - InvocationKind::Bang { attrs, mac, ident, span } => (attrs, mac, ident, span), + let (mac, ident, span) = match invoc.kind { + InvocationKind::Bang { mac, ident, span } => (mac, ident, span), _ => unreachable!(), }; 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); @@ -440,7 +431,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } }); - kind.make_from(expander.expand(self.cx, span, ident, marked_tts, attrs)) + kind.make_from(expander.expand(self.cx, span, ident, marked_tts)) } MultiDecorator(..) | MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => { @@ -595,13 +586,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { ..self.cx.current_expansion.clone() }, }); - placeholder(expansion_kind, ast::NodeId::from_u32(mark.as_u32())) + placeholder(expansion_kind, mark.as_placeholder_id()) } - fn collect_bang( - &mut self, mac: ast::Mac, attrs: Vec<ast::Attribute>, span: Span, kind: ExpansionKind, - ) -> Expansion { - self.collect(kind, InvocationKind::Bang { attrs: attrs, mac: mac, ident: None, span: span }) + fn collect_bang(&mut self, mac: ast::Mac, span: Span, kind: ExpansionKind) -> Expansion { + self.collect(kind, InvocationKind::Bang { mac: mac, ident: None, span: span }) } fn collect_attr(&mut self, attr: ast::Attribute, item: Annotatable, kind: ExpansionKind) @@ -622,6 +611,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 @@ -660,7 +659,8 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { expr.node = self.cfg.configure_expr_kind(expr.node); if let ast::ExprKind::Mac(mac) = expr.node { - self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr).make_expr() + self.check_attributes(&expr.attrs); + self.collect_bang(mac, expr.span, ExpansionKind::Expr).make_expr() } else { P(noop_fold_expr(expr, self)) } @@ -671,8 +671,8 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { expr.node = self.cfg.configure_expr_kind(expr.node); if let ast::ExprKind::Mac(mac) = expr.node { - self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr) - .make_opt_expr() + self.check_attributes(&expr.attrs); + self.collect_bang(mac, expr.span, ExpansionKind::OptExpr).make_opt_expr() } else { Some(P(noop_fold_expr(expr, self))) } @@ -685,8 +685,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } pat.and_then(|pat| match pat.node { - PatKind::Mac(mac) => - self.collect_bang(mac, Vec::new(), pat.span, ExpansionKind::Pat).make_pat(), + PatKind::Mac(mac) => self.collect_bang(mac, pat.span, ExpansionKind::Pat).make_pat(), _ => unreachable!(), }) } @@ -707,8 +706,8 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { }).collect() }; - let mut placeholder = - self.collect_bang(mac, attrs.into(), stmt.span, ExpansionKind::Stmts).make_stmts(); + self.check_attributes(&attrs); + let mut placeholder = self.collect_bang(mac, stmt.span, ExpansionKind::Stmts).make_stmts(); // If this is a macro invocation with a semicolon, then apply that // semicolon to the final statement produced by expansion. @@ -740,18 +739,21 @@ 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 = Mark::fresh().as_placeholder_id(); + SmallVector::one(P(item)) + } ItemKind::Mac(mac) => { self.collect(ExpansionKind::Items, InvocationKind::Bang { mac: mac, - attrs: item.attrs, ident: Some(item.ident), span: item.span, }).make_items() @@ -823,7 +825,8 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { match item.node { ast::TraitItemKind::Macro(mac) => { let ast::TraitItem { attrs, span, .. } = item; - self.collect_bang(mac, attrs, span, ExpansionKind::TraitItems).make_trait_items() + self.check_attributes(&attrs); + self.collect_bang(mac, span, ExpansionKind::TraitItems).make_trait_items() } _ => fold::noop_fold_trait_item(item, self), } @@ -841,7 +844,8 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { match item.node { ast::ImplItemKind::Macro(mac) => { let ast::ImplItem { attrs, span, .. } = item; - self.collect_bang(mac, attrs, span, ExpansionKind::ImplItems).make_impl_items() + self.check_attributes(&attrs); + self.collect_bang(mac, span, ExpansionKind::ImplItems).make_impl_items() } _ => fold::noop_fold_impl_item(item, self), } @@ -854,8 +858,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { }; match ty.node { - ast::TyKind::Mac(mac) => - self.collect_bang(mac, Vec::new(), ty.span, ExpansionKind::Ty).make_ty(), + ast::TyKind::Mac(mac) => self.collect_bang(mac, ty.span, ExpansionKind::Ty).make_ty(), _ => unreachable!(), } } diff --git a/src/libsyntax/ext/hygiene.rs b/src/libsyntax/ext/hygiene.rs index 0fd72277cca..2af5c2ea999 100644 --- a/src/libsyntax/ext/hygiene.rs +++ b/src/libsyntax/ext/hygiene.rs @@ -51,7 +51,11 @@ impl Mark { Mark(id.as_u32()) } - pub fn as_u32(&self) -> u32 { + pub fn as_placeholder_id(self) -> NodeId { + NodeId::from_u32(self.0) + } + + pub fn as_u32(self) -> u32 { self.0 } } @@ -115,12 +119,12 @@ impl SyntaxContext { }) } - /// If `ident` is macro expanded, return the source ident from the macro definition - /// and the mark of the expansion that created the macro definition. - pub fn source(self) -> (Self /* source context */, Mark /* source macro */) { - let macro_def_ctxt = self.data().prev_ctxt.data(); - (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark) - } + /// If `ident` is macro expanded, return the source ident from the macro definition + /// and the mark of the expansion that created the macro definition. + pub fn source(self) -> (Self /* source context */, Mark /* source macro */) { + let macro_def_ctxt = self.data().prev_ctxt.data(); + (macro_def_ctxt.prev_ctxt, macro_def_ctxt.outer_mark) + } } impl fmt::Debug for SyntaxContext { 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 ca18e580ecd..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,38 +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 export = attr::contains_name(&attrs, "macro_export"); - let def = ast::MacroDef { - ident: ident, - id: ast::DUMMY_NODE_ID, - span: span, - imported_from: None, - body: tts, - allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"), - 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, export); - result - } -} - // Note that macro-by-example's input is also matched against a token tree: // $( $lhs:tt => $rhs:tt );+ // @@ -282,7 +249,7 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension { valid: valid, }); - NormalTT(exp, Some(def.span), def.allow_internal_unstable) + NormalTT(exp, Some(def.span), attr::contains_name(&def.attrs, "allow_internal_unstable")) } fn check_lhs_nt_follows(sess: &ParseSess, lhs: &TokenTree) -> bool { |
