diff options
| author | bors <bors@rust-lang.org> | 2015-03-12 20:13:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-03-12 20:13:23 +0000 |
| commit | c9b03c24ec346e6405883032094f47805ef9c43e (patch) | |
| tree | cbb2bb6a0cd2a2e65b2cacd87d31bd8737f02e7d /src/libsyntax/ext | |
| parent | 538840bc2d1b634a2a34b2c8bd72d99894058b66 (diff) | |
| parent | 9da918548d77182ca64f375fb6da24036d5ad60c (diff) | |
| download | rust-c9b03c24ec346e6405883032094f47805ef9c43e.tar.gz rust-c9b03c24ec346e6405883032094f47805ef9c43e.zip | |
Auto merge of #23265 - eddyb:meth-ast-refactor, r=nikomatsakis
The end result is that common fields (id, name, attributes, etc.) are stored in now-structures `ImplItem` and `TraitItem`. The signature of a method is no longer duplicated between methods with a body (default/impl) and those without, they now share `MethodSig`. This is also a [breaking-change] because of minor bugfixes and changes to syntax extensions: * `pub fn` methods in a trait no longer parse - remove the `pub`, it has no meaning anymore * `MacResult::make_methods` is now `make_impl_items` and the return type has changed accordingly * `quote_method` is gone, because `P<ast::Method>` doesn't exist and it couldn't represent a full method anyways - could be replaced by `quote_impl_item`/`quote_trait_item` in the future, but I do hope we realize how silly that combinatorial macro expansion is and settle on a single `quote` macro + some type hints - or just no types at all (only token-trees) r? @nikomatsakis This is necessary (hopefully also sufficient) for associated constants.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 63 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 42 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 168 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 9 |
5 files changed, 120 insertions, 173 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8aeafe419da..35449bde0b2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -77,51 +77,31 @@ 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::TraitItem::RequiredMethod(ref tm) => &tm.attrs, - ast::TraitItem::ProvidedMethod(ref m) => &m.attrs, - ast::TraitItem::TypeTraitItem(ref at) => &at.attrs, - }, - Annotatable::ImplItem(ref i) => match *i { - ast::ImplItem::MethodImplItem(ref m) => &m.attrs, - ast::ImplItem::TypeImplItem(ref t) => &t.attrs, - } + Annotatable::TraitItem(ref ti) => &ti.attrs, + Annotatable::ImplItem(ref ii) => &ii.attrs, } } pub fn fold_attrs(self, attrs: Vec<ast::Attribute>) -> Annotatable { match self { - Annotatable::Item(i) => Annotatable::Item(P(ast::Item { + Annotatable::Item(i) => Annotatable::Item(i.map(|i| ast::Item { attrs: attrs, - ..(*i).clone() + ..i + })), + 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 } })), - Annotatable::TraitItem(i) => match i { - ast::TraitItem::RequiredMethod(tm) => Annotatable::TraitItem( - ast::TraitItem::RequiredMethod( - ast::TypeMethod { attrs: attrs, ..tm })), - ast::TraitItem::ProvidedMethod(m) => Annotatable::TraitItem( - ast::TraitItem::ProvidedMethod(P( - ast::Method { attrs: attrs, ..(*m).clone() }))), - ast::TraitItem::TypeTraitItem(at) => Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(P( - ast::AssociatedType { attrs: attrs, ..(*at).clone() }))), - }, - Annotatable::ImplItem(i) => match i { - ast::ImplItem::MethodImplItem(m) => Annotatable::ImplItem( - ast::ImplItem::MethodImplItem(P( - ast::Method { attrs: attrs, ..(*m).clone() }))), - ast::ImplItem::TypeImplItem(t) => Annotatable::ImplItem( - ast::ImplItem::TypeImplItem(P( - ast::Typedef { attrs: attrs, ..(*t).clone() }))), - } } } @@ -132,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") @@ -248,8 +228,8 @@ pub trait MacResult { None } - /// Create zero or more methods. - fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> { + /// Create zero or more impl items. + fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { None } @@ -295,7 +275,7 @@ make_MacEager! { expr: P<ast::Expr>, pat: P<ast::Pat>, items: SmallVector<P<ast::Item>>, - methods: SmallVector<P<ast::Method>>, + impl_items: SmallVector<P<ast::ImplItem>>, stmt: P<ast::Stmt>, } @@ -308,8 +288,8 @@ impl MacResult for MacEager { self.items } - fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> { - self.methods + fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { + self.impl_items } fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> { @@ -397,7 +377,7 @@ impl MacResult for DummyResult { Some(SmallVector::zero()) } } - fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::Method>>> { + fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> { if self.expr_only { None } else { @@ -505,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 9cd965a8138..58b6d96607d 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -386,22 +386,22 @@ impl<'a> TraitDef<'a> { cx: &mut ExtCtxt, type_ident: Ident, generics: &Generics, - methods: Vec<P<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)| { - P(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 - ), + )), }) }); @@ -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_) - }) - ).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>) -> P<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,18 +718,19 @@ impl<'a> MethodDef<'a> { let body_block = cx.block_expr(body); // Create the method. - P(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::MethodSig { + generics: fn_generics, + abi: abi, + explicit_self: explicit_self, + unsafety: ast::Unsafety::Normal, + decl: fn_decl + }, body_block) }) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6883395933e..ee2cf9017bb 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1174,29 +1174,26 @@ 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)))) - } - ast::TraitItem::TypeTraitItem(t) => { - SmallVector::one(Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(P(fld.fold_associated_type((*t).clone()))))) - } - }, - 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(P(fld.fold_typedef((*t).clone()))))) - } + + Annotatable::TraitItem(it) => match it.node { + ast::MethodTraitItem(_, Some(_)) => SmallVector::one(it.map(|ti| ast::TraitItem { + id: ti.id, + ident: ti.ident, + attrs: ti.attrs, + node: match ti.node { + ast::MethodTraitItem(sig, Some(body)) => { + let (sig, body) = expand_and_rename_method(sig, body, fld); + ast::MethodTraitItem(sig, Some(body)) + } + _ => unreachable!() + }, + span: fld.new_span(ti.span) + })), + _ => fold::noop_fold_trait_item(it, fld) + }.into_iter().map(Annotatable::TraitItem).collect(), + + Annotatable::ImplItem(ii) => { + expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect() } }; @@ -1204,21 +1201,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,54 +1274,48 @@ fn expand_item_multi_modifier(mut it: Annotatable, expand_item_multi_modifier(it, fld) } -// expand a method -fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<ast::Method>> { - m.and_then(|m| 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(P(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) => { - let maybe_new_methods = - expand_mac_invoc(mac, m.span, - |r| r.make_methods(), - |meths, mark| meths.move_map(|m| mark_method(m, mark)), +fn expand_impl_item(ii: P<ast::ImplItem>, fld: &mut MacroExpander) + -> SmallVector<P<ast::ImplItem>> { + match ii.node { + ast::MethodImplItem(..) => SmallVector::one(ii.map(|ii| ast::ImplItem { + id: ii.id, + ident: ii.ident, + attrs: ii.attrs, + vis: ii.vis, + node: match ii.node { + ast::MethodImplItem(sig, body) => { + let (sig, body) = expand_and_rename_method(sig, body, fld); + ast::MethodImplItem(sig, body) + } + _ => unreachable!() + }, + span: fld.new_span(ii.span) + })), + ast::MacImplItem(_) => { + let (span, mac) = ii.and_then(|ii| match ii.node { + ast::MacImplItem(mac) => (ii.span, mac), + _ => unreachable!() + }); + let maybe_new_items = + expand_mac_invoc(mac, span, + |r| r.make_impl_items(), + |meths, mark| meths.move_map(|m| mark_impl_item(m, mark)), fld); - match maybe_new_methods { - Some(methods) => { + match maybe_new_items { + Some(impl_items) => { // expand again if necessary - let new_methods = methods.into_iter() - .flat_map(|m| fld.fold_method(m).into_iter()) - .collect(); + let new_items = impl_items.into_iter().flat_map(|ii| { + expand_impl_item(ii, fld).into_iter() + }).collect(); fld.cx.bt_pop(); - new_methods + new_items } None => SmallVector::zero() } } - }) + _ => fold::noop_fold_impl_item(ii, fld) + } } /// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the @@ -1347,7 +1323,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as /// the block, returning both the new FnDecl and the new Block. fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Block>, fld: &mut MacroExpander) - -> (P<ast::FnDecl>, P<ast::Block>) { + -> (P<ast::FnDecl>, P<ast::Block>) { let expanded_decl = fld.fold_fn_decl(fn_decl); let idents = fn_decl_arg_bindings(&*expanded_decl); let renames = @@ -1361,6 +1337,20 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl (rewritten_fn_decl,rewritten_body) } +fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>, + fld: &mut MacroExpander) + -> (ast::MethodSig, P<ast::Block>) { + let (rewritten_fn_decl, rewritten_body) + = expand_and_rename_fn_decl_and_block(sig.decl, body, fld); + (ast::MethodSig { + generics: fld.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: fld.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: rewritten_fn_decl + }, rewritten_body) +} + /// A tree-folder that performs macro expansion pub struct MacroExpander<'a, 'b:'a> { pub cx: &'a mut ExtCtxt<'b>, @@ -1410,16 +1400,14 @@ 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_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: P<ast::Method>) -> SmallVector<P<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 +1553,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: P<ast::Method>, m: Mrk) -> P<ast::Method> { - Marker{mark:m}.fold_method(expr) - .expect_one("marking an item didn't return exactly one method") +fn mark_impl_item(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 impl item") } /// 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 644c6cd7e28..7575d4b5ecd 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -71,7 +71,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> { loop { let mut parser = self.parser.borrow_mut(); // so... do outer attributes attached to the macro invocation - // just disappear? This question applies to make_methods, as + // just disappear? This question applies to make_impl_items, as // well. match parser.parse_item_with_outer_attributes() { Some(item) => ret.push(item), @@ -82,15 +82,14 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(ret) } - fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Method>>> { + fn make_impl_items(self: Box<ParserAnyMacro<'a>>) + -> Option<SmallVector<P<ast::ImplItem>>> { let mut ret = SmallVector::zero(); loop { let mut parser = self.parser.borrow_mut(); match parser.token { token::Eof => break, - _ => { - ret.push(parser.parse_method_with_outer_attributes()); - } + _ => ret.push(parser.parse_impl_item_with_outer_attributes()) } } self.ensure_complete_parse(false); |
