about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-03-10 12:28:44 +0200
committerEduard Burtescu <edy.burt@gmail.com>2015-03-11 23:39:16 +0200
commitf98b1763140e4c9b0f122bde2f5cbd24227554a2 (patch)
tree70e9da4c25e7f110b2ac58f3c6500dbb309bf772 /src/libsyntax/ext
parent98491827b920884e4ea1182dcacce2a650dde861 (diff)
downloadrust-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.rs50
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs46
-rw-r--r--src/libsyntax/ext/expand.rs145
-rw-r--r--src/libsyntax/ext/quote.rs11
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs3
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();