From 313cb8acaea05e703441bd5adb92aacce5bf6411 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 9 Sep 2014 23:57:14 -0700 Subject: [PATCH 1/2] Change ItemModifier and ItemDecorator to traits For convenience, the traits are implemented for the respective bare functions. Change code from this: ```rust ItemDecorator(some_function) // or ItemModifier(some_other_function) ``` to ```rust ItemDecorator(box some_function) // or ItemModifier(box some_other_function) ``` [breaking-change] --- src/libsyntax/ext/base.rs | 48 ++++++++++++++++++++++---- src/libsyntax/ext/expand.rs | 9 +++-- src/test/auxiliary/macro_crate_test.rs | 2 +- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index d59b20dfc4c..43be3c227ac 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -39,11 +39,45 @@ pub struct MacroDef { pub ext: SyntaxExtension } -pub type ItemDecorator = - fn(&mut ExtCtxt, Span, Gc, Gc, |Gc|); +pub trait ItemDecorator { + fn expand(&self, + ecx: &mut ExtCtxt, + sp: Span, + meta_item: Gc, + item: Gc, + push: |Gc|); +} -pub type ItemModifier = - fn(&mut ExtCtxt, Span, Gc, Gc) -> Gc; +impl ItemDecorator for fn(&mut ExtCtxt, Span, Gc, Gc, |Gc|) { + fn expand(&self, + ecx: &mut ExtCtxt, + sp: Span, + meta_item: Gc, + item: Gc, + push: |Gc|) { + (*self)(ecx, sp, meta_item, item, push) + } +} + +pub trait ItemModifier { + fn expand(&self, + ecx: &mut ExtCtxt, + span: Span, + meta_item: Gc, + item: Gc) + -> Gc; +} + +impl ItemModifier for fn(&mut ExtCtxt, Span, Gc, Gc) -> Gc { + fn expand(&self, + ecx: &mut ExtCtxt, + span: Span, + meta_item: Gc, + item: Gc) + -> Gc { + (*self)(ecx, span, meta_item, item) + } +} pub struct BasicMacroExpander { pub expander: MacroExpanderFn, @@ -281,11 +315,11 @@ pub enum SyntaxExtension { /// based upon it. /// /// `#[deriving(...)]` is an `ItemDecorator`. - ItemDecorator(ItemDecorator), + ItemDecorator(Box), /// A syntax extension that is attached to an item and modifies it /// in-place. - ItemModifier(ItemModifier), + ItemModifier(Box), /// A normal, function-like syntax extension. /// @@ -371,7 +405,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv { builtin_normal_expander( ext::log_syntax::expand_syntax_ext)); syntax_expanders.insert(intern("deriving"), - ItemDecorator(ext::deriving::expand_meta_deriving)); + ItemDecorator(box ext::deriving::expand_meta_deriving)); // Quasi-quoting expanders syntax_expanders.insert(intern("quote_tokens"), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d0f3cf6f9d7..c531da0bd87 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -251,7 +251,7 @@ fn expand_item(it: Gc, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemDecorator(dec_fn) => { + ItemDecorator(ref dec) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { @@ -266,8 +266,7 @@ fn expand_item(it: Gc, fld: &mut MacroExpander) // we'd ideally decorator_items.push_all(expand_item(item, fld)), // but that double-mut-borrows fld let mut items: SmallVector> = SmallVector::zero(); - dec_fn(fld.cx, attr.span, attr.node.value, it, - |item| items.push(item)); + dec.expand(fld.cx, attr.span, attr.node.value, it, |item| items.push(item)); decorator_items.extend(items.move_iter() .flat_map(|item| expand_item(item, fld).move_iter())); @@ -328,7 +327,7 @@ fn expand_item_modifiers(mut it: Gc, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemModifier(dec_fn) => { + ItemModifier(ref mac) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { call_site: attr.span, @@ -338,7 +337,7 @@ fn expand_item_modifiers(mut it: Gc, fld: &mut MacroExpander) span: None, } }); - it = dec_fn(fld.cx, attr.span, attr.node.value, it); + it = mac.expand(fld.cx, attr.span, attr.node.value, it); fld.cx.bt_pop(); } _ => unreachable!() diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs index 0a9cfb5884f..fbbee2e625a 100644 --- a/src/test/auxiliary/macro_crate_test.rs +++ b/src/test/auxiliary/macro_crate_test.rs @@ -36,7 +36,7 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_macro("identity", expand_identity); reg.register_syntax_extension( token::intern("into_foo"), - ItemModifier(expand_into_foo)); + ItemModifier(box expand_into_foo)); } fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) From 200a08fc212374f5650c54489ae26f995c60bad9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 10 Sep 2014 20:59:26 -0700 Subject: [PATCH 2/2] Remove BasicMacroExpander and BasicIdentMacroExpander The spans inside of these types were always None and never used. Pass the expander function directly instead of wrapping it in one of these types. [breaking-change] --- src/librustc/plugin/registry.rs | 11 +++------- src/libsyntax/ext/base.rs | 39 +++++++++------------------------ 2 files changed, 13 insertions(+), 37 deletions(-) diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs index 7fa3ee0ac63..2b2fc8c94d4 100644 --- a/src/librustc/plugin/registry.rs +++ b/src/librustc/plugin/registry.rs @@ -13,7 +13,7 @@ use lint::{LintPassObject, LintId, Lint}; use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; -use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier, BasicMacroExpander}; +use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier}; use syntax::ext::base::{MacroExpanderFn}; use syntax::codemap::Span; use syntax::parse::token; @@ -71,15 +71,10 @@ impl Registry { /// Register a macro of the usual kind. /// /// This is a convenience wrapper for `register_syntax_extension`. - /// It builds for you a `NormalTT` with a `BasicMacroExpander`, + /// It builds for you a `NormalTT` that calls `expander`, /// and also takes care of interning the macro's name. pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) { - self.register_syntax_extension( - token::intern(name), - NormalTT(box BasicMacroExpander { - expander: expander, - span: None, - }, None)); + self.register_syntax_extension(token::intern(name), NormalTT(box expander, None)); } /// Register a compiler lint pass. diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 43be3c227ac..4976e68cc64 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -79,11 +79,6 @@ impl ItemModifier for fn(&mut ExtCtxt, Span, Gc, Gc) - } } -pub struct BasicMacroExpander { - pub expander: MacroExpanderFn, - pub span: Option -} - /// Represents a thing that maps token trees to Macro Results pub trait TTMacroExpander { fn expand<'cx>(&self, @@ -94,24 +89,18 @@ pub trait TTMacroExpander { } pub type MacroExpanderFn = - fn<'cx>(ecx: &'cx mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree]) - -> Box; + fn<'cx>(&'cx mut ExtCtxt, Span, &[ast::TokenTree]) -> Box; -impl TTMacroExpander for BasicMacroExpander { +impl TTMacroExpander for MacroExpanderFn { fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, token_tree: &[ast::TokenTree]) -> Box { - (self.expander)(ecx, span, token_tree) + (*self)(ecx, span, token_tree) } } -pub struct BasicIdentMacroExpander { - pub expander: IdentMacroExpanderFn, - pub span: Option -} - pub trait IdentMacroExpander { fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, @@ -121,20 +110,20 @@ pub trait IdentMacroExpander { -> Box; } -impl IdentMacroExpander for BasicIdentMacroExpander { +pub type IdentMacroExpanderFn = + fn<'cx>(&'cx mut ExtCtxt, Span, ast::Ident, Vec) -> Box; + +impl IdentMacroExpander for IdentMacroExpanderFn { fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, sp: Span, ident: ast::Ident, token_tree: Vec ) -> Box { - (self.expander)(cx, sp, ident, token_tree) + (*self)(cx, sp, ident, token_tree) } } -pub type IdentMacroExpanderFn = - fn<'cx>(&'cx mut ExtCtxt, Span, ast::Ident, Vec) -> Box; - /// The result of a macro expansion. The return values of the various /// methods are spliced into the AST at the callsite of the macro (or /// just into the compiler's internal macro table, for `make_def`). @@ -363,20 +352,12 @@ impl BlockInfo { fn initial_syntax_expander_table() -> SyntaxEnv { // utility function to simplify creating NormalTT syntax extensions fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension { - NormalTT(box BasicMacroExpander { - expander: f, - span: None, - }, - None) + NormalTT(box f, None) } let mut syntax_expanders = SyntaxEnv::new(); syntax_expanders.insert(intern("macro_rules"), - LetSyntaxTT(box BasicIdentMacroExpander { - expander: ext::tt::macro_rules::add_new_extension, - span: None, - }, - None)); + LetSyntaxTT(box ext::tt::macro_rules::add_new_extension, None)); syntax_expanders.insert(intern("fmt"), builtin_normal_expander( ext::fmt::expand_syntax_ext));