about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs15
-rw-r--r--src/libsyntax/ast_map/blocks.rs28
-rw-r--r--src/libsyntax/ast_map/mod.rs22
-rw-r--r--src/libsyntax/ast_util.rs32
-rw-r--r--src/libsyntax/ext/base.rs12
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs4
-rw-r--r--src/libsyntax/ext/expand.rs130
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs10
-rw-r--r--src/libsyntax/fold.rs29
-rw-r--r--src/libsyntax/parse/parser.rs31
-rw-r--r--src/libsyntax/print/pprust.rs42
-rw-r--r--src/libsyntax/visit.rs58
12 files changed, 162 insertions, 251 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0a08b0b1207..657ffcaece9 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -33,7 +33,6 @@ pub use self::LocalSource::*;
 pub use self::Mac_::*;
 pub use self::MacStmtStyle::*;
 pub use self::MetaItem_::*;
-pub use self::Method::*;
 pub use self::Mutability::*;
 pub use self::Pat_::*;
 pub use self::PathListItem_::*;
@@ -1084,8 +1083,7 @@ pub struct TraitItem {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum TraitItem_ {
-    RequiredMethod(MethodSig),
-    ProvidedMethod(Method),
+    MethodTraitItem(MethodSig, Option<P<Block>>),
     TypeTraitItem(TyParamBounds, Option<P<Ty>>),
 }
 
@@ -1101,8 +1099,9 @@ pub struct ImplItem {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum ImplItem_ {
-    MethodImplItem(Method),
+    MethodImplItem(MethodSig, P<Block>),
     TypeImplItem(P<Ty>),
+    MacImplItem(Mac),
 }
 
 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
@@ -1417,14 +1416,6 @@ pub enum ExplicitSelf_ {
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Method {
-    /// Represents a method declaration
-    MethDecl(MethodSig, P<Block>),
-    /// Represents a macro in method position
-    MethMac(Mac),
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
index 345ccf902cd..16a339cdcb5 100644
--- a/src/libsyntax/ast_map/blocks.rs
+++ b/src/libsyntax/ast_map/blocks.rs
@@ -28,7 +28,6 @@ use ast::{Block, FnDecl, NodeId};
 use ast;
 use ast_map::{Node};
 use ast_map;
-use ast_util::PostExpansionMethod;
 use codemap::Span;
 use visit;
 
@@ -65,7 +64,7 @@ impl MaybeFnLike for ast::Item {
 
 impl MaybeFnLike for ast::TraitItem {
     fn is_fn_like(&self) -> bool {
-        match self.node { ast::ProvidedMethod(_) => true, _ => false, }
+        match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, }
     }
 }
 
@@ -156,25 +155,25 @@ impl<'a> FnLikeNode<'a> {
 
     pub fn body(self) -> &'a Block {
         self.handle(|i: ItemFnParts<'a>|  &*i.body,
-                    |_, _, m: &'a ast::Method, _|  m.pe_body(),
+                    |_, _, _: &'a ast::MethodSig, body: &'a ast::Block, _|  body,
                     |c: ClosureParts<'a>| c.body)
     }
 
     pub fn decl(self) -> &'a FnDecl {
         self.handle(|i: ItemFnParts<'a>|  &*i.decl,
-                    |_, _, m: &'a ast::Method, _|  &m.pe_sig().decl,
+                    |_, _, sig: &'a ast::MethodSig, _, _|  &sig.decl,
                     |c: ClosureParts<'a>| c.decl)
     }
 
     pub fn span(self) -> Span {
         self.handle(|i: ItemFnParts|     i.span,
-                    |_, _, _: &'a ast::Method, span| span,
+                    |_, _, _: &'a ast::MethodSig, _, span| span,
                     |c: ClosureParts|    c.span)
     }
 
     pub fn id(self) -> NodeId {
         self.handle(|i: ItemFnParts|     i.id,
-                    |id, _, _: &'a ast::Method, _| id,
+                    |id, _, _: &'a ast::MethodSig, _, _| id,
                     |c: ClosureParts|    c.id)
     }
 
@@ -185,15 +184,15 @@ impl<'a> FnLikeNode<'a> {
         let closure = |_: ClosureParts| {
             visit::FkFnBlock
         };
-        let method = |_, ident, m: &'a ast::Method, _| {
-            visit::FkMethod(ident, m)
+        let method = |_, ident, sig: &'a ast::MethodSig, _, _| {
+            visit::FkMethod(ident, sig)
         };
         self.handle(item, method, closure)
     }
 
     fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
         I: FnOnce(ItemFnParts<'a>) -> A,
-        M: FnOnce(NodeId, ast::Ident, &'a ast::Method, Span) -> A,
+        M: FnOnce(NodeId, ast::Ident, &'a ast::MethodSig, &'a ast::Block, Span) -> A,
         C: FnOnce(ClosureParts<'a>) -> A,
     {
         match self.node {
@@ -206,13 +205,18 @@ impl<'a> FnLikeNode<'a> {
                 _ => panic!("item FnLikeNode that is not fn-like"),
             },
             ast_map::NodeTraitItem(ti) => match ti.node {
-                ast::ProvidedMethod(ref m) => method(ti.id, ti.ident, m, ti.span),
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
+                    method(ti.id, ti.ident, sig, body, ti.span)
+                }
                 _ => panic!("trait method FnLikeNode that is not fn-like"),
             },
             ast_map::NodeImplItem(ii) => {
                 match ii.node {
-                    ast::MethodImplItem(ref m) => method(ii.id, ii.ident, m, ii.span),
-                    ast::TypeImplItem(_) => {
+                    ast::MethodImplItem(ref sig, ref body) => {
+                        method(ii.id, ii.ident, sig, body, ii.span)
+                    }
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => {
                         panic!("impl method FnLikeNode that is not fn-like")
                     }
                 }
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 606c6b640df..48bb044cb18 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -929,16 +929,10 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
         }
         Some(NodeImplItem(ii)) => {
             match ii.node {
-                MethodImplItem(ref m) => {
-                    match *m {
-                        MethDecl(..) =>
-                            format!("method {} in {}{}",
-                                    token::get_ident(ii.ident),
-                                    map.path_to_string(id), id_str),
-                        MethMac(ref mac) =>
-                            format!("method macro {}{}",
-                                    pprust::mac_to_string(mac), id_str)
-                    }
+                MethodImplItem(..) => {
+                    format!("method {} in {}{}",
+                            token::get_ident(ii.ident),
+                            map.path_to_string(id), id_str)
                 }
                 TypeImplItem(_) => {
                     format!("assoc type {} in {}{}",
@@ -946,13 +940,17 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                             map.path_to_string(id),
                             id_str)
                 }
+                MacImplItem(ref mac) => {
+                    format!("method macro {}{}",
+                            pprust::mac_to_string(mac), id_str)
+                }
             }
         }
         Some(NodeTraitItem(ti)) => {
             let kind = match ti.node {
-                RequiredMethod(_) => "required method",
-                ProvidedMethod(_) => "provided method",
+                MethodTraitItem(..) => "trait method",
                 TypeTraitItem(..) => "assoc type",
+//                 ConstTraitItem(..) => "assoc constant"
             };
 
             format!("{} {} in {}{}",
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 91ddc8beec8..cec824e79ff 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -459,8 +459,8 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
             visit::FkItemFn(_, generics, _, _) => {
                 self.visit_generics_helper(generics)
             }
-            visit::FkMethod(_, m) => {
-                self.visit_generics_helper(&m.pe_sig().generics)
+            visit::FkMethod(_, sig) => {
+                self.visit_generics_helper(&sig.generics)
             }
             visit::FkFnBlock => {}
         }
@@ -647,34 +647,6 @@ pub fn lit_is_str(lit: &Lit) -> bool {
     }
 }
 
-/// Macro invocations are guaranteed not to occur after expansion is complete.
-/// Extracting fields of a method requires a dynamic check to make sure that it's
-/// not a macro invocation. This check is guaranteed to succeed, assuming
-/// that the invocations are indeed gone.
-pub trait PostExpansionMethod {
-    fn pe_sig<'a>(&'a self) -> &'a ast::MethodSig;
-    fn pe_body<'a>(&'a self) -> &'a ast::Block;
-}
-
-macro_rules! mf_method{
-    ($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:expr) => {
-        fn $meth_name<'a>(&'a self) -> $field_ty {
-            match *self {
-                $field_pat => $result,
-                MethMac(_) => {
-                    panic!("expected an AST without macro invocations");
-                }
-            }
-        }
-    }
-}
-
-
-impl PostExpansionMethod for Method {
-    mf_method! { pe_sig, &'a ast::MethodSig,MethDecl(ref sig, _), sig }
-    mf_method! { pe_body, &'a ast::Block,MethDecl(_, ref body), body }
-}
-
 #[cfg(test)]
 mod test {
     use ast::*;
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index cad5f97a4a5..35449bde0b2 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -228,8 +228,8 @@ pub trait MacResult {
         None
     }
 
-    /// Create zero or more methods.
-    fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
+    /// Create zero or more impl items.
+    fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
         None
     }
 
@@ -275,7 +275,7 @@ make_MacEager! {
     expr: P<ast::Expr>,
     pat: P<ast::Pat>,
     items: SmallVector<P<ast::Item>>,
-    methods: SmallVector<P<ast::ImplItem>>,
+    impl_items: SmallVector<P<ast::ImplItem>>,
     stmt: P<ast::Stmt>,
 }
 
@@ -288,8 +288,8 @@ impl MacResult for MacEager {
         self.items
     }
 
-    fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
-        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>> {
@@ -377,7 +377,7 @@ impl MacResult for DummyResult {
             Some(SmallVector::zero())
         }
     }
-    fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> {
+    fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> {
         if self.expr_only {
             None
         } else {
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index d4b0f7d1dcb..58b6d96607d 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -724,13 +724,13 @@ impl<'a> MethodDef<'a> {
             span: trait_.span,
             vis: ast::Inherited,
             ident: method_ident,
-            node: ast::MethodImplItem(ast::MethDecl(ast::MethodSig {
+            node: ast::MethodImplItem(ast::MethodSig {
                 generics: fn_generics,
                 abi: abi,
                 explicit_self: explicit_self,
                 unsafety: ast::Unsafety::Normal,
                 decl: fn_decl
-            }, body_block))
+            }, body_block)
         })
     }
 
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:
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index dad50af9a91..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,16 +82,14 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
         Some(ret)
     }
 
-    fn make_methods(self: Box<ParserAnyMacro<'a>>)
-                    -> Option<SmallVector<P<ast::ImplItem>>> {
+    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);
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index d7982ef8399..105a61d0857 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -110,10 +110,6 @@ pub trait Folder : Sized {
         noop_fold_fn_decl(d, self)
     }
 
-    fn fold_method(&mut self, m: Method) -> Method {
-        noop_fold_method(m, self)
-    }
-
     fn fold_block(&mut self, b: P<Block>) -> P<Block> {
         noop_fold_block(b, self)
     }
@@ -977,8 +973,10 @@ pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T)
         ident: folder.fold_ident(ident),
         attrs: fold_attrs(attrs, folder),
         node: match node {
-            RequiredMethod(sig) => RequiredMethod(noop_fold_method_sig(sig, folder)),
-            ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)),
+            MethodTraitItem(sig, body) => {
+                MethodTraitItem(noop_fold_method_sig(sig, folder),
+                                body.map(|x| folder.fold_block(x)))
+            }
             TypeTraitItem(bounds, default) => {
                 TypeTraitItem(folder.fold_bounds(bounds),
                               default.map(|x| folder.fold_ty(x)))
@@ -996,8 +994,12 @@ pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T)
         attrs: fold_attrs(attrs, folder),
         vis: vis,
         node: match node  {
-            MethodImplItem(m) => MethodImplItem(folder.fold_method(m)),
-            TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty))
+            MethodImplItem(sig, body) => {
+                MethodImplItem(noop_fold_method_sig(sig, folder),
+                               folder.fold_block(body))
+            }
+            TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)),
+            MacImplItem(mac) => MacImplItem(folder.fold_mac(mac))
         },
         span: folder.new_span(span)
     }))
@@ -1099,17 +1101,6 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
     })
 }
 
-// Default fold over a method.
-pub fn noop_fold_method<T: Folder>(method: Method, folder: &mut T) -> Method {
-    match method {
-        MethDecl(sig, body) => {
-            MethDecl(noop_fold_method_sig(sig, folder),
-                     folder.fold_block(body))
-        },
-        MethMac(mac) => MethMac(folder.fold_mac(mac))
-    }
-}
-
 pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
     MethodSig {
         generics: folder.fold_generics(sig.generics),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2e77bd6df18..9f851e5de19 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -13,7 +13,7 @@ pub use self::PathParsingMode::*;
 use abi;
 use ast::{BareFnTy};
 use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
-use ast::{ProvidedMethod, Public, Unsafety};
+use ast::{Public, Unsafety};
 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block};
 use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
@@ -42,8 +42,7 @@ use ast::{MutTy, BiMul, Mutability};
 use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot};
 use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
-use ast::{PolyTraitRef};
-use ast::{QSelf, RequiredMethod};
+use ast::{PolyTraitRef, QSelf};
 use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub, StrStyle};
@@ -1349,18 +1348,18 @@ impl<'a> Parser<'a> {
                 };
 
                 let hi = p.last_span.hi;
-                let node = match p.token {
+                let body = match p.token {
                   token::Semi => {
                     p.bump();
                     debug!("parse_trait_methods(): parsing required method");
-                    RequiredMethod(sig)
+                    None
                   }
                   token::OpenDelim(token::Brace) => {
                     debug!("parse_trait_methods(): parsing provided method");
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
                     attrs.push_all(&inner_attrs[..]);
-                    ProvidedMethod(ast::MethDecl(sig, body))
+                    Some(body)
                   }
 
                   _ => {
@@ -1374,7 +1373,7 @@ impl<'a> Parser<'a> {
                     id: ast::DUMMY_NODE_ID,
                     ident: ident,
                     attrs: attrs,
-                    node: node,
+                    node: ast::MethodTraitItem(sig, body),
                     span: mk_sp(lo, hi),
                 })
             }
@@ -4682,11 +4681,15 @@ impl<'a> Parser<'a> {
         (ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs))
     }
 
-    /// Parse a method in a trait impl
-    pub fn parse_method_with_outer_attributes(&mut self) -> P<ImplItem> {
+    /// Parse an impl item.
+    pub fn parse_impl_item_with_outer_attributes(&mut self) -> P<ImplItem> {
         let attrs = self.parse_outer_attributes();
-        let visa = self.parse_visibility();
-        self.parse_method(attrs, visa)
+        let vis = self.parse_visibility();
+        if self.eat_keyword(keywords::Type) {
+            self.parse_assoc_ty_in_impl(attrs, vis)
+        } else {
+            self.parse_method(attrs, vis)
+        }
     }
 
     fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) {
@@ -4733,7 +4736,7 @@ impl<'a> Parser<'a> {
                 if delim != token::Brace {
                     self.expect(&token::Semi)
                 }
-                (ast::MethMac(m), self.span.hi, attrs,
+                (ast::MacImplItem(m), self.span.hi, attrs,
                  token::special_idents::invalid)
             } else {
                 let unsafety = self.parse_unsafety();
@@ -4753,7 +4756,7 @@ impl<'a> Parser<'a> {
                 let body_span = body.span;
                 let mut new_attrs = attrs;
                 new_attrs.push_all(&inner_attrs[..]);
-                (ast::MethDecl(ast::MethodSig {
+                (MethodImplItem(ast::MethodSig {
                     generics: generics,
                     abi: abi,
                     explicit_self: explicit_self,
@@ -4767,7 +4770,7 @@ impl<'a> Parser<'a> {
             attrs: new_attrs,
             vis: vis,
             ident: ident,
-            node: MethodImplItem(method_),
+            node: method_,
             span: mk_sp(lo, hi),
         })
     }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 20c8df42993..07303ba51ff 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1251,12 +1251,17 @@ impl<'a> State<'a> {
         try!(self.maybe_print_comment(ti.span.lo));
         try!(self.print_outer_attributes(&ti.attrs));
         match ti.node {
-            ast::RequiredMethod(ref sig) => {
+            ast::MethodTraitItem(ref sig, ref body) => {
+                if body.is_some() {
+                    try!(self.head(""));
+                }
                 try!(self.print_method_sig(ti.ident, sig, ast::Inherited));
-                word(&mut self.s, ";")
-            }
-            ast::ProvidedMethod(ref m) => {
-                self.print_method(ti.ident, &ti.attrs, ast::Inherited, m)
+                if let Some(ref body) = *body {
+                    try!(self.nbsp());
+                    self.print_block_with_attrs(body, &ti.attrs)
+                } else {
+                    word(&mut self.s, ";")
+                }
             }
             ast::TypeTraitItem(ref bounds, ref default) => {
                 self.print_associated_type(ti.ident, Some(bounds),
@@ -1270,30 +1275,17 @@ impl<'a> State<'a> {
         try!(self.maybe_print_comment(ii.span.lo));
         try!(self.print_outer_attributes(&ii.attrs));
         match ii.node {
-            ast::MethodImplItem(ref m) => {
-                self.print_method(ii.ident, &ii.attrs, ii.vis, m)
+            ast::MethodImplItem(ref sig, ref body) => {
+                try!(self.head(""));
+                try!(self.print_method_sig(ii.ident, sig, ii.vis));
+                try!(self.nbsp());
+                self.print_block_with_attrs(body, &ii.attrs)
             }
             ast::TypeImplItem(ref ty) => {
                 self.print_associated_type(ii.ident, None, Some(ty))
             }
-        }
-    }
-
-    pub fn print_method(&mut self,
-                        ident: ast::Ident,
-                        attrs: &[ast::Attribute],
-                        vis: ast::Visibility,
-                        meth: &ast::Method)
-                        -> io::Result<()> {
-        match *meth {
-            ast::MethDecl(ref sig, ref body) => {
-                try!(self.head(""));
-                try!(self.print_method_sig(ident, sig, vis));
-                try!(self.nbsp());
-                self.print_block_with_attrs(&**body, attrs)
-            },
-            ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
-                                            ..}) => {
+            ast::MacImplItem(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
+                                                ..}) => {
                 // code copied from ItemMac:
                 try!(self.print_path(pth, false, 0));
                 try!(word(&mut self.s, "! "));
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 4375e17ce0b..638ddd3ea2e 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -38,7 +38,7 @@ pub enum FnKind<'a> {
     FkItemFn(Ident, &'a Generics, Unsafety, Abi),
 
     /// fn foo(&self)
-    FkMethod(Ident, &'a Method),
+    FkMethod(Ident, &'a MethodSig),
 
     /// |x, y| ...
     /// proc(x, y) ...
@@ -592,28 +592,6 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &
     walk_fn_ret_ty(visitor, &function_declaration.output)
 }
 
-// Note: there is no visit_method() method in the visitor, instead override
-// visit_fn() and check for FkMethod().  I named this visit_method_helper()
-// because it is not a default impl of any method, though I doubt that really
-// clarifies anything. - Niko
-fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V,
-                                          id: NodeId,
-                                          ident: Ident,
-                                          span: Span,
-                                          method: &'v Method) {
-    match *method {
-        MethDecl(ref sig, ref body) => {
-            visitor.visit_ident(span, ident);
-            visitor.visit_fn(FkMethod(ident, method),
-                             &sig.decl,
-                             body,
-                             span,
-                             id);
-        },
-        MethMac(ref mac) => visitor.visit_mac(mac)
-    }
-}
-
 pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
                                    function_kind: FnKind<'v>,
                                    function_declaration: &'v FnDecl,
@@ -625,14 +603,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
         FkItemFn(_, generics, _, _) => {
             visitor.visit_generics(generics);
         }
-        FkMethod(_, method) => {
-            match *method {
-                MethDecl(ref sig, _) => {
-                    visitor.visit_generics(&sig.generics);
-                    visitor.visit_explicit_self(&sig.explicit_self);
-                }
-                MethMac(ref mac) => visitor.visit_mac(mac)
-            }
+        FkMethod(_, sig) => {
+            visitor.visit_generics(&sig.generics);
+            visitor.visit_explicit_self(&sig.explicit_self);
         }
         FkFnBlock(..) => {}
     }
@@ -646,17 +619,14 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
         visitor.visit_attribute(attr);
     }
     match trait_item.node {
-        RequiredMethod(ref sig) => {
+        MethodTraitItem(ref sig, None) => {
             visitor.visit_explicit_self(&sig.explicit_self);
             visitor.visit_generics(&sig.generics);
             walk_fn_decl(visitor, &sig.decl);
         }
-        ProvidedMethod(ref method) => {
-            walk_method_helper(visitor,
-                               trait_item.id,
-                               trait_item.ident,
-                               trait_item.span,
-                               method);
+        MethodTraitItem(ref sig, Some(ref body)) => {
+            visitor.visit_fn(FkMethod(trait_item.ident, sig), &sig.decl,
+                             body, trait_item.span, trait_item.id);
         }
         TypeTraitItem(ref bounds, ref default) => {
             walk_ty_param_bounds_helper(visitor, bounds);
@@ -671,16 +641,16 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
         visitor.visit_attribute(attr);
     }
     match impl_item.node {
-        MethodImplItem(ref method) => {
-            walk_method_helper(visitor,
-                               impl_item.id,
-                               impl_item.ident,
-                               impl_item.span,
-                               method);
+        MethodImplItem(ref sig, ref body) => {
+            visitor.visit_fn(FkMethod(impl_item.ident, sig), &sig.decl,
+                             body, impl_item.span, impl_item.id);
         }
         TypeImplItem(ref ty) => {
             visitor.visit_ty(ty);
         }
+        MacImplItem(ref mac) => {
+            visitor.visit_mac(mac);
+        }
     }
 }