about summary refs log tree commit diff
path: root/src/libsyntax/ext/expand.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/ext/expand.rs')
-rw-r--r--src/libsyntax/ext/expand.rs130
1 files changed, 61 insertions, 69 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index fa0b747f45b..830248b5682 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -25,7 +25,6 @@ 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;
@@ -1175,42 +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.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
-                    }),
+            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!()
-                });
-                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()
-            }
-            _ => {
-                fold::noop_fold_trait_item(it, fld).into_iter()
-                    .map(|ti| Annotatable::TraitItem(ti)).collect()
-            }
-        },
+                },
+                span: fld.new_span(ti.span)
+            })),
+            _ => fold::noop_fold_trait_item(it, fld)
+        }.into_iter().map(Annotatable::TraitItem).collect(),
+
         Annotatable::ImplItem(ii) => {
-            expand_method(ii, fld).into_iter().map(Annotatable::ImplItem).collect()
+            expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect()
         }
     };
 
@@ -1291,35 +1274,47 @@ fn expand_item_multi_modifier(mut it: Annotatable,
     expand_item_multi_modifier(it, fld)
 }
 
-// expand an impl item if it's a method macro
-fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
+fn expand_impl_item(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(_)) => {
+        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::MethodImplItem(ast::MethMac(mac)) => (ii.span, mac),
+                ast::MacImplItem(mac) => (ii.span, mac),
                 _ => unreachable!()
             });
-            let maybe_new_methods =
+            let maybe_new_items =
                 expand_mac_invoc(mac, span,
-                                 |r| r.make_methods(),
-                                 |meths, mark| meths.move_map(|m| mark_method(m, mark)),
+                                 |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| expand_method(m, fld).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()
             }
         }
-        _ => SmallVector::one(ii)
+        _ => fold::noop_fold_impl_item(ii, fld)
     }
 }
 
@@ -1328,7 +1323,7 @@ fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
 /// 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 =
@@ -1342,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>,
@@ -1391,23 +1400,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         expand_arm(arm, self)
     }
 
-    fn fold_method(&mut self, m: ast::Method) -> ast::Method {
-        match m {
-            ast::MethDecl(sig, body) => {
-                let (rewritten_fn_decl, rewritten_body)
-                    = expand_and_rename_fn_decl_and_block(sig.decl, body, self);
-                ast::MethDecl(ast::MethodSig {
-                    generics: self.fold_generics(sig.generics),
-                    abi: sig.abi,
-                    explicit_self: self.fold_explicit_self(sig.explicit_self),
-                    unsafety: sig.unsafety,
-                    decl: rewritten_fn_decl
-                }, rewritten_body)
-            }
-            ast::MethMac(mac) => ast::MethMac(mac)
-        }
-    }
-
     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()
@@ -1561,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(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
+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 method")
+        .expect_one("marking an impl item didn't return exactly one impl item")
 }
 
 /// Check that there are no macro invocations left in the AST: