diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2015-03-10 12:28:44 +0200 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2015-03-11 23:39:16 +0200 |
| commit | f98b1763140e4c9b0f122bde2f5cbd24227554a2 (patch) | |
| tree | 70e9da4c25e7f110b2ac58f3c6500dbb309bf772 /src/libsyntax/ext | |
| parent | 98491827b920884e4ea1182dcacce2a650dde861 (diff) | |
| download | rust-f98b1763140e4c9b0f122bde2f5cbd24227554a2.tar.gz rust-f98b1763140e4c9b0f122bde2f5cbd24227554a2.zip | |
syntax: gather common fields of impl & trait items into their respective types.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 46 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 145 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 3 |
5 files changed, 108 insertions, 147 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b999680ff1a..cad5f97a4a5 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -77,23 +77,16 @@ impl<F> ItemModifier for F #[derive(Debug,Clone)] pub enum Annotatable { Item(P<ast::Item>), - TraitItem(ast::TraitItem), - ImplItem(ast::ImplItem), + TraitItem(P<ast::TraitItem>), + ImplItem(P<ast::ImplItem>), } impl Annotatable { pub fn attrs(&self) -> &[ast::Attribute] { match *self { Annotatable::Item(ref i) => &i.attrs, - Annotatable::TraitItem(ref i) => match *i { - ast::RequiredMethod(ref tm) => &tm.attrs, - ast::ProvidedMethod(ref m) => &m.attrs, - ast::TypeTraitItem(ref at) => &at.attrs, - }, - Annotatable::ImplItem(ref i) => match *i { - ast::MethodImplItem(ref m) => &m.attrs, - ast::TypeImplItem(ref t) => &t.attrs, - } + Annotatable::TraitItem(ref ti) => &ti.attrs, + Annotatable::ImplItem(ref ii) => &ii.attrs, } } @@ -103,20 +96,12 @@ impl Annotatable { attrs: attrs, ..i })), - Annotatable::TraitItem(i) => Annotatable::TraitItem(match i { - ast::RequiredMethod(tm) => - ast::RequiredMethod(ast::TypeMethod { attrs: attrs, ..tm }), - ast::ProvidedMethod(m) => - ast::ProvidedMethod(ast::Method { attrs: attrs, ..m }), - ast::TypeTraitItem(at) => - ast::TypeTraitItem(ast::AssociatedType { attrs: attrs, ..at }), - }), - Annotatable::ImplItem(i) => Annotatable::ImplItem(match i { - ast::MethodImplItem(m) => - ast::MethodImplItem(ast::Method { attrs: attrs, ..m }), - ast::TypeImplItem(t) => - ast::TypeImplItem(ast::Typedef { attrs: attrs, ..t }), - }) + Annotatable::TraitItem(i) => Annotatable::TraitItem(i.map(|ti| { + ast::TraitItem { attrs: attrs, ..ti } + })), + Annotatable::ImplItem(i) => Annotatable::ImplItem(i.map(|ii| { + ast::ImplItem { attrs: attrs, ..ii } + })), } } @@ -127,14 +112,14 @@ impl Annotatable { } } - pub fn expect_trait_item(self) -> ast::TraitItem { + pub fn expect_trait_item(self) -> P<ast::TraitItem> { match self { Annotatable::TraitItem(i) => i, _ => panic!("expected Item") } } - pub fn expect_impl_item(self) -> ast::ImplItem { + pub fn expect_impl_item(self) -> P<ast::ImplItem> { match self { Annotatable::ImplItem(i) => i, _ => panic!("expected Item") @@ -244,7 +229,7 @@ pub trait MacResult { } /// Create zero or more methods. - fn make_methods(self: Box<Self>) -> Option<SmallVector<ast::Method>> { + fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { None } @@ -290,7 +275,7 @@ make_MacEager! { expr: P<ast::Expr>, pat: P<ast::Pat>, items: SmallVector<P<ast::Item>>, - methods: SmallVector<ast::Method>, + methods: SmallVector<P<ast::ImplItem>>, stmt: P<ast::Stmt>, } @@ -303,7 +288,7 @@ impl MacResult for MacEager { self.items } - fn make_methods(self: Box<Self>) -> Option<SmallVector<ast::Method>> { + fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { self.methods } @@ -392,7 +377,7 @@ impl MacResult for DummyResult { Some(SmallVector::zero()) } } - fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<ast::Method>> { + fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> { if self.expr_only { None } else { @@ -500,9 +485,6 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>) syntax_expanders.insert(intern("quote_ty"), builtin_normal_expander( ext::quote::expand_quote_ty)); - syntax_expanders.insert(intern("quote_method"), - builtin_normal_expander( - ext::quote::expand_quote_method)); syntax_expanders.insert(intern("quote_item"), builtin_normal_expander( ext::quote::expand_quote_item)); diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 0573289150c..a4962afff3c 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -386,23 +386,23 @@ impl<'a> TraitDef<'a> { cx: &mut ExtCtxt, type_ident: Ident, generics: &Generics, - methods: Vec<ast::Method>) -> P<ast::Item> { + methods: Vec<P<ast::ImplItem>>) -> P<ast::Item> { let trait_path = self.path.to_path(cx, self.span, type_ident, generics); - // Transform associated types from `deriving::ty::Ty` into `ast::Typedef` + // Transform associated types from `deriving::ty::Ty` into `ast::ImplItem` let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| { - ast::Typedef { + P(ast::ImplItem { id: ast::DUMMY_NODE_ID, span: self.span, ident: ident, vis: ast::Inherited, attrs: Vec::new(), - typ: type_def.to_ty(cx, + node: ast::TypeImplItem(type_def.to_ty(cx, self.span, type_ident, generics - ), - } + )), + }) }); let Generics { mut lifetimes, ty_params, mut where_clause } = @@ -510,14 +510,7 @@ impl<'a> TraitDef<'a> { trait_generics, opt_trait_ref, self_type, - methods.into_iter() - .map(|method| { - ast::MethodImplItem(method) - }).chain( - associated_types.map(|type_| { - ast::TypeImplItem(type_) - }) - ).map(P).collect())) + methods.into_iter().chain(associated_types).collect())) } fn expand_struct_def(&self, @@ -702,7 +695,7 @@ impl<'a> MethodDef<'a> { abi: Abi, explicit_self: ast::ExplicitSelf, arg_types: Vec<(Ident, P<ast::Ty>)> , - body: P<Expr>) -> ast::Method { + body: P<Expr>) -> P<ast::ImplItem> { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); @@ -725,19 +718,20 @@ impl<'a> MethodDef<'a> { let body_block = cx.block_expr(body); // Create the method. - ast::Method { - attrs: self.attributes.clone(), + P(ast::ImplItem { id: ast::DUMMY_NODE_ID, + attrs: self.attributes.clone(), span: trait_.span, - node: ast::MethDecl(method_ident, - fn_generics, - abi, - explicit_self, - ast::Unsafety::Normal, - fn_decl, - body_block, - ast::Inherited) - } + vis: ast::Inherited, + ident: method_ident, + node: ast::MethodImplItem( + ast::MethDecl(fn_generics, + abi, + explicit_self, + ast::Unsafety::Normal, + fn_decl, + body_block)) + }) } /// ``` diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 96859b94f1d..5fb0126cdd0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -25,6 +25,7 @@ use ext::base::*; use feature_gate::{self, Features}; use fold; use fold::*; +use owned_slice::OwnedSlice; use parse; use parse::token::{fresh_mark, fresh_name, intern}; use parse::token; @@ -1174,29 +1175,42 @@ fn expand_annotatable(a: Annotatable, noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect() } }, - Annotatable::TraitItem(it) => match it { - ast::TraitItem::ProvidedMethod(m) => { - expand_method(m, fld).into_iter().map(|m| - Annotatable::TraitItem(ast::TraitItem::ProvidedMethod(m))).collect() - } - ast::TraitItem::RequiredMethod(m) => { - SmallVector::one(Annotatable::TraitItem( - ast::TraitItem::RequiredMethod(fld.fold_type_method(m)))) + Annotatable::TraitItem(it) => match it.node { + ast::ProvidedMethod(ast::MethMac(_)) => { + // HACK(eddyb): Expand method macros in a trait as if they were in an impl. + let ii = it.and_then(|ti| match ti.node { + ast::ProvidedMethod(m) => P(ast::ImplItem { + id: ti.id, + ident: ti.ident, + attrs: ti.attrs, + vis: ast::Inherited, + node: ast::MethodImplItem(m), + span: ti.span + }), + _ => unreachable!() + }); + expand_method(ii, fld).into_iter().map(|ii| { + Annotatable::TraitItem(ii.and_then(|ii| P(ast::TraitItem { + id: ii.id, + ident: ii.ident, + attrs: ii.attrs, + node: match ii.node { + ast::MethodImplItem(m) => ast::ProvidedMethod(m), + ast::TypeImplItem(ty) => { + ast::TypeTraitItem(OwnedSlice::empty(), Some(ty)) + } + }, + span: ii.span + }))) + }).collect() } - ast::TraitItem::TypeTraitItem(t) => { - SmallVector::one(Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(fld.fold_associated_type(t)))) + _ => { + fold::noop_fold_trait_item(it, fld).into_iter() + .map(|ti| Annotatable::TraitItem(ti)).collect() } }, - Annotatable::ImplItem(it) => match it { - ast::ImplItem::MethodImplItem(m) => { - expand_method(m, fld).into_iter().map(|m| - Annotatable::ImplItem(ast::ImplItem::MethodImplItem(m))).collect() - } - ast::ImplItem::TypeImplItem(t) => { - SmallVector::one(Annotatable::ImplItem( - ast::ImplItem::TypeImplItem(fld.fold_typedef(t)))) - } + Annotatable::ImplItem(ii) => { + expand_method(ii, fld).into_iter().map(Annotatable::ImplItem).collect() } }; @@ -1204,21 +1218,6 @@ fn expand_annotatable(a: Annotatable, new_items } -fn expand_trait_item(i: ast::TraitItem, - fld: &mut MacroExpander) - -> SmallVector<ast::TraitItem> { - expand_annotatable(Annotatable::TraitItem(i), fld) - .into_iter().map(|i| i.expect_trait_item()).collect() - -} - -fn expand_impl_item(i: ast::ImplItem, - fld: &mut MacroExpander) - -> SmallVector<ast::ImplItem> { - expand_annotatable(Annotatable::ImplItem(i), fld) - .into_iter().map(|i| i.expect_impl_item()).collect() -} - // partition the attributes into ItemModifiers and others fn modifiers(attrs: &Vec<ast::Attribute>, fld: &MacroExpander) @@ -1292,37 +1291,18 @@ fn expand_item_multi_modifier(mut it: Annotatable, expand_item_multi_modifier(it, fld) } -// expand a method -fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector<ast::Method> { - match m.node { - ast::MethDecl(ident, - generics, - abi, - explicit_self, - fn_style, - decl, - body, - vis) => { - let id = fld.new_id(m.id); - let (rewritten_fn_decl, rewritten_body) - = expand_and_rename_fn_decl_and_block(decl, body, fld); - SmallVector::one(ast::Method { - attrs: fold::fold_attrs(m.attrs, fld), - id: id, - span: fld.new_span(m.span), - node: ast::MethDecl(fld.fold_ident(ident), - noop_fold_generics(generics, fld), - abi, - fld.fold_explicit_self(explicit_self), - fn_style, - rewritten_fn_decl, - rewritten_body, - vis) - }) - }, - ast::MethMac(mac) => { +// expand an impl item if it's a method macro +fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander) + -> SmallVector<P<ast::ImplItem>> { + let ii = fold::noop_fold_impl_item(ii, fld).expect_one("expected one impl item"); + match ii.node { + ast::MethodImplItem(ast::MethMac(_)) => { + let (span, mac) = ii.and_then(|ii| match ii.node { + ast::MethodImplItem(ast::MethMac(mac)) => (ii.span, mac), + _ => unreachable!() + }); let maybe_new_methods = - expand_mac_invoc(mac, m.span, + expand_mac_invoc(mac, span, |r| r.make_methods(), |meths, mark| meths.move_map(|m| mark_method(m, mark)), fld); @@ -1331,7 +1311,7 @@ fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector<ast::Me Some(methods) => { // expand again if necessary let new_methods = methods.into_iter() - .flat_map(|m| fld.fold_method(m).into_iter()) + .flat_map(|m| expand_method(m, fld).into_iter()) .collect(); fld.cx.bt_pop(); new_methods @@ -1339,6 +1319,7 @@ fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector<ast::Me None => SmallVector::zero() } } + _ => SmallVector::one(ii) } } @@ -1410,16 +1391,30 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_arm(arm, self) } - fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem> { - expand_trait_item(i, self) + fn fold_method(&mut self, m: ast::Method) -> ast::Method { + match m { + ast::MethDecl(generics, abi, explicit_self, fn_style, decl, body) => { + let (rewritten_fn_decl, rewritten_body) + = expand_and_rename_fn_decl_and_block(decl, body, self); + ast::MethDecl(self.fold_generics(generics), + abi, + self.fold_explicit_self(explicit_self), + fn_style, + rewritten_fn_decl, + rewritten_body) + } + ast::MethMac(mac) => ast::MethMac(mac) + } } - fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector<ast::ImplItem> { - expand_impl_item(i, self) + fn fold_trait_item(&mut self, i: P<ast::TraitItem>) -> SmallVector<P<ast::TraitItem>> { + expand_annotatable(Annotatable::TraitItem(i), self) + .into_iter().map(|i| i.expect_trait_item()).collect() } - fn fold_method(&mut self, method: ast::Method) -> SmallVector<ast::Method> { - expand_method(method, self) + fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem>> { + expand_annotatable(Annotatable::ImplItem(i), self) + .into_iter().map(|i| i.expect_impl_item()).collect() } fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> { @@ -1565,9 +1560,9 @@ fn mark_item(expr: P<ast::Item>, m: Mrk) -> P<ast::Item> { } // apply a given mark to the given item. Used following the expansion of a macro. -fn mark_method(expr: ast::Method, m: Mrk) -> ast::Method { - Marker{mark:m}.fold_method(expr) - .expect_one("marking an item didn't return exactly one method") +fn mark_method(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> { + Marker{mark:m}.fold_impl_item(ii) + .expect_one("marking an impl item didn't return exactly one method") } /// Check that there are no macro invocations left in the AST: diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 737648cd90c..48c045ee4f9 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -176,7 +176,6 @@ pub mod rt { impl_to_source! { ast::Arg, arg_to_string } impl_to_source! { Generics, generics_to_string } impl_to_source! { P<ast::Item>, item_to_string } - impl_to_source! { P<ast::Method>, method_to_string } impl_to_source! { P<ast::Stmt>, stmt_to_string } impl_to_source! { P<ast::Expr>, expr_to_string } impl_to_source! { P<ast::Pat>, pat_to_string } @@ -311,7 +310,6 @@ pub mod rt { impl_to_tokens! { P<ast::Item> } impl_to_tokens! { P<ast::Pat> } impl_to_tokens! { ast::Arm } - impl_to_tokens! { P<ast::Method> } impl_to_tokens_lifetime! { &'a [P<ast::Item>] } impl_to_tokens! { ast::Ty } impl_to_tokens_lifetime! { &'a [ast::Ty] } @@ -446,15 +444,6 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt, base::MacEager::expr(expanded) } -pub fn expand_quote_method(cx: &mut ExtCtxt, - sp: Span, - tts: &[ast::TokenTree]) - -> Box<base::MacResult+'static> { - let expanded = expand_parse_call(cx, sp, "parse_method_with_outer_attributes", - vec!(), tts); - base::MacEager::expr(expanded) -} - pub fn expand_quote_stmt(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index dcdfad4632d..dad50af9a91 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -82,7 +82,8 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(ret) } - fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<ast::Method>> { + fn make_methods(self: Box<ParserAnyMacro<'a>>) + -> Option<SmallVector<P<ast::ImplItem>>> { let mut ret = SmallVector::zero(); loop { let mut parser = self.parser.borrow_mut(); |
