about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-03-11 23:38:58 +0200
committerEduard Burtescu <edy.burt@gmail.com>2015-03-11 23:39:16 +0200
commit9da918548d77182ca64f375fb6da24036d5ad60c (patch)
treef04e278a2ffe86f73f9499fa6d23e4dd14faa3c6
parentce10fa8d12cb20d9eee59fffeeaadfcca8badf4a (diff)
downloadrust-9da918548d77182ca64f375fb6da24036d5ad60c.tar.gz
rust-9da918548d77182ca64f375fb6da24036d5ad60c.zip
syntax: move MethMac to MacImplItem and combine {Provided,Required}Method into MethodTraitItem.
-rw-r--r--src/librustc/metadata/encoder.rs39
-rw-r--r--src/librustc/middle/dead.rs13
-rw-r--r--src/librustc/middle/effect.rs5
-rw-r--r--src/librustc/middle/infer/error_reporting.rs28
-rw-r--r--src/librustc/middle/reachable.rs27
-rw-r--r--src/librustc/middle/resolve_lifetime.rs9
-rw-r--r--src/librustc/middle/ty.rs15
-rw-r--r--src/librustc/util/ppaux.rs3
-rw-r--r--src/librustc_lint/builtin.rs20
-rw-r--r--src/librustc_privacy/lib.rs45
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs3
-rw-r--r--src/librustc_resolve/lib.rs29
-rw-r--r--src/librustc_trans/save/mod.rs107
-rw-r--r--src/librustc_trans/trans/base.rs26
-rw-r--r--src/librustc_trans/trans/debuginfo.rs26
-rw-r--r--src/librustc_trans/trans/inline.rs18
-rw-r--r--src/librustc_trans/trans/meth.rs22
-rw-r--r--src/librustc_trans/trans/monomorphize.rs15
-rw-r--r--src/librustc_typeck/check/mod.rs44
-rw-r--r--src/librustc_typeck/check/wf.rs2
-rw-r--r--src/librustc_typeck/coherence/mod.rs6
-rw-r--r--src/librustc_typeck/collect.rs39
-rw-r--r--src/librustdoc/clean/mod.rs34
-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
-rw-r--r--src/test/auxiliary/macro_crate_test.rs23
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs2
37 files changed, 464 insertions, 549 deletions
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index eb41a26fa77..611d8bc27d1 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -827,7 +827,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     let elem = ast_map::PathName(m.name);
     encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));
     if let Some(impl_item) = impl_item_opt {
-        if let ast::MethodImplItem(ref ast_method) = impl_item.node {
+        if let ast::MethodImplItem(ref sig, _) = impl_item.node {
             encode_attributes(rbml_w, &impl_item.attrs);
             let scheme = ty::lookup_item_type(ecx.tcx, m.def_id);
             let any_types = !scheme.generics.types.is_empty();
@@ -838,7 +838,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
             if !any_types {
                 encode_symbol(ecx, rbml_w, m.def_id.node);
             }
-            encode_method_argument_names(rbml_w, &ast_method.pe_sig().decl);
+            encode_method_argument_names(rbml_w, &sig.decl);
         }
     }
 
@@ -1362,28 +1362,25 @@ fn encode_info_for_item(ecx: &EncodeContext,
             encode_parent_sort(rbml_w, 't');
 
             let trait_item = &*ms[i];
-            let encode_trait_item = |rbml_w: &mut Encoder| {
-                // If this is a static method, we've already
-                // encoded this.
-                if is_nonstatic_method {
-                    // FIXME: I feel like there is something funny
-                    // going on.
-                    encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id());
-                }
-            };
             encode_attributes(rbml_w, &trait_item.attrs);
             match trait_item.node {
-                ast::RequiredMethod(ref m) => {
-                    encode_trait_item(rbml_w);
-                    encode_item_sort(rbml_w, 'r');
-                    encode_method_argument_names(rbml_w, &*m.decl);
-                }
+                ast::MethodTraitItem(ref sig, ref body) => {
+                    // If this is a static method, we've already
+                    // encoded this.
+                    if is_nonstatic_method {
+                        // FIXME: I feel like there is something funny
+                        // going on.
+                        encode_bounds_and_type_for_item(rbml_w, ecx,
+                            item_def_id.def_id().local_id());
+                    }
 
-                ast::ProvidedMethod(ref m) => {
-                    encode_trait_item(rbml_w);
-                    encode_item_sort(rbml_w, 'p');
-                    encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
-                    encode_method_argument_names(rbml_w, &*m.pe_sig().decl);
+                    if body.is_some() {
+                        encode_item_sort(rbml_w, 'p');
+                        encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
+                    } else {
+                        encode_item_sort(rbml_w, 'r');
+                    }
+                    encode_method_argument_names(rbml_w, &sig.decl);
                 }
 
                 ast::TypeTraitItem(..) => {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 6517378c75c..5efea66ab0c 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -18,7 +18,7 @@ use util::nodemap::NodeSet;
 
 use std::collections::HashSet;
 use syntax::{ast, ast_map, codemap};
-use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
+use syntax::ast_util::{local_def, is_local};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::visit::{self, Visitor};
 
@@ -353,7 +353,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
             ast::ItemTrait(_, _, _, ref trait_items) => {
                 for trait_item in trait_items {
                     match trait_item.node {
-                        ast::ProvidedMethod(_) => {
+                        ast::MethodTraitItem(_, Some(_)) => {
                             if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
                                 self.worklist.push(trait_item.id);
                             }
@@ -365,13 +365,14 @@ impl<'v> Visitor<'v> for LifeSeeder {
             ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
                 for impl_item in impl_items {
                     match impl_item.node {
-                        ast::MethodImplItem(_) => {
+                        ast::MethodImplItem(..) => {
                             if opt_trait.is_some() ||
                                     has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
                                 self.worklist.push(impl_item.id);
                             }
                         }
                         ast::TypeImplItem(_) => {}
+                        ast::MacImplItem(_) => panic!("unexpanded macro")
                     }
                 }
             }
@@ -578,10 +579,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
     // Overwrite so that we don't warn the trait method itself.
     fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
         match trait_method.node {
-            ast::ProvidedMethod(ref method) => {
-                visit::walk_block(self, method.pe_body())
+            ast::MethodTraitItem(_, Some(ref body)) => {
+                visit::walk_block(self, body)
             }
-            ast::RequiredMethod(_) |
+            ast::MethodTraitItem(_, None) |
             ast::TypeTraitItem(..) => {}
         }
     }
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index 02f2908a9e6..378f3db0823 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -18,7 +18,6 @@ use middle::ty::MethodCall;
 use util::ppaux;
 
 use syntax::ast;
-use syntax::ast_util::PostExpansionMethod;
 use syntax::codemap::Span;
 use syntax::visit;
 use syntax::visit::Visitor;
@@ -90,8 +89,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
         let (is_item_fn, is_unsafe_fn) = match fn_kind {
             visit::FkItemFn(_, _, fn_style, _) =>
                 (true, fn_style == ast::Unsafety::Unsafe),
-            visit::FkMethod(_, method) =>
-                (true, method.pe_sig().unsafety == ast::Unsafety::Unsafe),
+            visit::FkMethod(_, sig) =>
+                (true, sig.unsafety == ast::Unsafety::Unsafe),
             _ => (false, false),
         };
 
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 823acdc1691..1ca56596a01 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -83,7 +83,7 @@ use std::rc::Rc;
 use std::string::String;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{name_to_dummy_lifetime, PostExpansionMethod};
+use syntax::ast_util::name_to_dummy_lifetime;
 use syntax::owned_slice::OwnedSlice;
 use syntax::codemap;
 use syntax::parse::token;
@@ -848,25 +848,26 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 }
                 ast_map::NodeImplItem(item) => {
                     match item.node {
-                        ast::MethodImplItem(ref m) => {
-                            Some((&m.pe_sig().decl,
-                                  &m.pe_sig().generics,
-                                  m.pe_sig().unsafety,
+                        ast::MethodImplItem(ref sig, _) => {
+                            Some((&sig.decl,
+                                  &sig.generics,
+                                  sig.unsafety,
                                   item.ident,
-                                  Some(&m.pe_sig().explicit_self.node),
+                                  Some(&sig.explicit_self.node),
                                   item.span))
                         }
                         ast::TypeImplItem(_) => None,
+                        ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                     }
                 },
                 ast_map::NodeTraitItem(item) => {
                     match item.node {
-                        ast::ProvidedMethod(ref m) => {
-                            Some((&m.pe_sig().decl,
-                                  &m.pe_sig().generics,
-                                  m.pe_sig().unsafety,
+                        ast::MethodTraitItem(ref sig, Some(_)) => {
+                            Some((&sig.decl,
+                                  &sig.generics,
+                                  sig.unsafety,
                                   item.ident,
-                                  Some(&m.pe_sig().explicit_self.node),
+                                  Some(&sig.explicit_self.node),
                                   item.span))
                         }
                         _ => None
@@ -1731,11 +1732,12 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
             },
             ast_map::NodeImplItem(ii) => {
                 match ii.node {
-                    ast::MethodImplItem(ref m) => {
-                        taken.push_all(&m.pe_sig().generics.lifetimes);
+                    ast::MethodImplItem(ref sig, _) => {
+                        taken.push_all(&sig.generics.lifetimes);
                         Some(ii.id)
                     }
                     ast::TypeImplItem(_) => None,
+                    ast::MacImplItem(_) => tcx.sess.bug("unexpanded macro")
                 }
             }
             _ => None
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 75e9c60698b..7ded344414c 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -25,7 +25,7 @@ use std::collections::HashSet;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{is_local, PostExpansionMethod};
+use syntax::ast_util::is_local;
 use syntax::attr;
 use syntax::visit::Visitor;
 use syntax::visit;
@@ -53,11 +53,11 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
     }
 }
 
-fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
+fn method_might_be_inlined(tcx: &ty::ctxt, sig: &ast::MethodSig,
                            impl_item: &ast::ImplItem,
                            impl_src: ast::DefId) -> bool {
     if attr::requests_inline(&impl_item.attrs) ||
-        generics_require_inlining(&method.pe_sig().generics) {
+        generics_require_inlining(&sig.generics) {
         return true
     }
     if is_local(impl_src) {
@@ -183,15 +183,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
             }
             Some(ast_map::NodeTraitItem(trait_method)) => {
                 match trait_method.node {
-                    ast::RequiredMethod(_) => false,
-                    ast::ProvidedMethod(_) => true,
+                    ast::MethodTraitItem(_, ref body) => body.is_some(),
                     ast::TypeTraitItem(..) => false,
                 }
             }
             Some(ast_map::NodeImplItem(impl_item)) => {
                 match impl_item.node {
-                    ast::MethodImplItem(ref method) => {
-                        if generics_require_inlining(&method.pe_sig().generics) ||
+                    ast::MethodImplItem(ref sig, _) => {
+                        if generics_require_inlining(&sig.generics) ||
                                 attr::requests_inline(&impl_item.attrs) {
                             true
                         } else {
@@ -214,6 +213,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                         }
                     }
                     ast::TypeImplItem(_) => false,
+                    ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                 }
             }
             Some(_) => false,
@@ -303,24 +303,25 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
             }
             ast_map::NodeTraitItem(trait_method) => {
                 match trait_method.node {
-                    ast::RequiredMethod(..) => {
+                    ast::MethodTraitItem(_, None) => {
                         // Keep going, nothing to get exported
                     }
-                    ast::ProvidedMethod(ref method) => {
-                        visit::walk_block(self, &*method.pe_body());
+                    ast::MethodTraitItem(_, Some(ref body)) => {
+                        visit::walk_block(self, body);
                     }
                     ast::TypeTraitItem(..) => {}
                 }
             }
             ast_map::NodeImplItem(impl_item) => {
                 match impl_item.node {
-                    ast::MethodImplItem(ref method) => {
+                    ast::MethodImplItem(ref sig, ref body) => {
                         let did = self.tcx.map.get_parent_did(search_item);
-                        if method_might_be_inlined(self.tcx, method, impl_item, did) {
-                            visit::walk_block(self, method.pe_body())
+                        if method_might_be_inlined(self.tcx, sig, impl_item, did) {
+                            visit::walk_block(self, body)
                         }
                     }
                     ast::TypeImplItem(_) => {}
+                    ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                 }
             }
             // Nothing to recurse on for these
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 32d52bcbf74..e33a2553431 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -25,7 +25,6 @@ use middle::subst;
 use middle::ty;
 use std::fmt;
 use syntax::ast;
-use syntax::ast_util::PostExpansionMethod;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
@@ -148,8 +147,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                     visit::walk_fn(this, fk, fd, b, s)
                 })
             }
-            visit::FkMethod(_, m) => {
-                self.visit_early_late(subst::FnSpace, &m.pe_sig().generics, |this| {
+            visit::FkMethod(_, sig) => {
+                self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
                     visit::walk_fn(this, fk, fd, b, s)
                 })
             }
@@ -191,9 +190,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
     }
 
     fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
-        if let ast::RequiredMethod(ref m) = trait_item.node {
+        if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
             self.visit_early_late(
-                subst::FnSpace, &m.generics,
+                subst::FnSpace, &sig.generics,
                 |this| visit::walk_trait_item(this, trait_item))
         } else {
             visit::walk_trait_item(self, trait_item);
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 32b85d8c0a9..14d61a37008 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -82,7 +82,7 @@ use syntax::abi;
 use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE};
 use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
 use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
-use syntax::ast_util::{self, is_local, lit_is_str, local_def, PostExpansionMethod};
+use syntax::ast_util::{self, is_local, lit_is_str, local_def};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::codemap::Span;
 use syntax::parse::token::{self, InternedString, special_idents};
@@ -2287,7 +2287,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
         match cx.map.find(id) {
             Some(ast_map::NodeImplItem(ref impl_item)) => {
                 match impl_item.node {
-                    ast::MethodImplItem(ref method) => {
+                    ast::MethodImplItem(_, ref body) => {
                         let method_def_id = ast_util::local_def(id);
                         match ty::impl_or_trait_item(cx, method_def_id) {
                             MethodTraitItem(ref method_ty) => {
@@ -2298,7 +2298,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                     impl_item.span,
                                     method_generics,
                                     method_bounds,
-                                    method.pe_body().id)
+                                    body.id)
                             }
                             TypeTraitItem(_) => {
                                 cx.sess
@@ -2313,18 +2313,19 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                      can't create a parameter environment \
                                      for type impl items")
                     }
+                    ast::MacImplItem(_) => cx.sess.bug("unexpanded macro")
                 }
             }
             Some(ast_map::NodeTraitItem(trait_item)) => {
                 match trait_item.node {
-                    ast::RequiredMethod(_) => {
+                    ast::MethodTraitItem(_, None) => {
                         cx.sess.span_bug(trait_item.span,
                                          "ParameterEnvironment::for_item():
                                           can't create a parameter \
                                           environment for required trait \
                                           methods")
                     }
-                    ast::ProvidedMethod(ref method) => {
+                    ast::MethodTraitItem(_, Some(ref body)) => {
                         let method_def_id = ast_util::local_def(id);
                         match ty::impl_or_trait_item(cx, method_def_id) {
                             MethodTraitItem(ref method_ty) => {
@@ -2335,7 +2336,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                     trait_item.span,
                                     method_generics,
                                     method_bounds,
-                                    method.pe_body().id)
+                                    body.id)
                             }
                             TypeTraitItem(_) => {
                                 cx.sess
@@ -5082,7 +5083,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
     if is_local(id) {
         if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node {
             ms.iter().filter_map(|ti| {
-                if let ast::ProvidedMethod(_) = ti.node {
+                if let ast::MethodTraitItem(_, Some(_)) = ti.node {
                     match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
                         MethodTraitItem(m) => Some(m),
                         TypeTraitItem(_) => {
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index f1041809701..3a0b5832c9f 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -829,8 +829,7 @@ impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
 impl<'tcx> Repr<'tcx> for ast::TraitItem {
     fn repr(&self, _tcx: &ctxt) -> String {
         let kind = match self.node {
-            ast::RequiredMethod(_) => "RequiredMethod",
-            ast::ProvidedMethod(_) => "ProvidedMethod",
+            ast::MethodTraitItem(..) => "MethodTraitItem",
             ast::TypeTraitItem(..) => "TypeTraitItem",
         };
         format!("{}({}, id={})", kind, self.ident, self.id)
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 687b4cb8723..074591fb927 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -46,7 +46,7 @@ use std::{cmp, slice};
 use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
 
 use syntax::{abi, ast, ast_map};
-use syntax::ast_util::{self, is_shift_binop, local_def, PostExpansionMethod};
+use syntax::ast_util::{self, is_shift_binop, local_def};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::codemap::{self, Span};
 use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
@@ -1005,7 +1005,7 @@ impl LintPass for NonSnakeCase {
     }
 
     fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
-        if let ast::RequiredMethod(_) = trait_item.node {
+        if let ast::MethodTraitItem(_, None) = trait_item.node {
             self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span);
         }
     }
@@ -1318,8 +1318,8 @@ impl LintPass for UnsafeCode {
             visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) =>
                 cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
 
-            visit::FkMethod(_, m) => {
-                if m.pe_sig().unsafety == ast::Unsafety::Unsafe {
+            visit::FkMethod(_, sig) => {
+                if sig.unsafety == ast::Unsafety::Unsafe {
                     cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
                 }
             },
@@ -1329,8 +1329,8 @@ impl LintPass for UnsafeCode {
     }
 
     fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
-        if let ast::RequiredMethod(ref m) = trait_item.node {
-            if m.unsafety == ast::Unsafety::Unsafe {
+        if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
+            if sig.unsafety == ast::Unsafety::Unsafe {
                 cx.span_lint(UNSAFE_CODE, trait_item.span,
                              "declaration of an `unsafe` method")
             }
@@ -1564,8 +1564,7 @@ impl LintPass for MissingDoc {
 
     fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
         let desc = match trait_item.node {
-            ast::ProvidedMethod(_) => "a default method",
-            ast::RequiredMethod(_) => "a trait method",
+            ast::MethodTraitItem(..) => "a trait method",
             ast::TypeTraitItem(..) => "an associated type"
         };
         self.check_missing_docs_attrs(cx, Some(trait_item.id),
@@ -1580,8 +1579,9 @@ impl LintPass for MissingDoc {
         }
 
         let desc = match impl_item.node {
-            ast::MethodImplItem(_) => "a method",
-            ast::TypeImplItem(_) => "an associated type"
+            ast::MethodImplItem(..) => "a method",
+            ast::TypeImplItem(_) => "an associated type",
+            ast::MacImplItem(_) => "an impl item macro"
         };
         self.check_missing_docs_attrs(cx, Some(impl_item.id),
                                       &impl_item.attrs,
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 9b069962de4..27f807ebe42 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -48,7 +48,7 @@ use rustc::middle::ty::{self, Ty};
 use rustc::util::nodemap::{NodeMap, NodeSet};
 
 use syntax::{ast, ast_map};
-use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
+use syntax::ast_util::{is_local, local_def};
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::visit::{self, Visitor};
@@ -273,17 +273,17 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
                 if public_ty || public_trait {
                     for impl_item in impl_items {
                         match impl_item.node {
-                            ast::MethodImplItem(ref method) => {
-                                let meth_public =
-                                    match method.pe_sig().explicit_self.node {
-                                        ast::SelfStatic => public_ty,
-                                        _ => true,
-                                    } && impl_item.vis == ast::Public;
+                            ast::MethodImplItem(ref sig, _) => {
+                                let meth_public = match sig.explicit_self.node {
+                                    ast::SelfStatic => public_ty,
+                                    _ => true,
+                                } && impl_item.vis == ast::Public;
                                 if meth_public || tr.is_some() {
                                     self.exported_items.insert(impl_item.id);
                                 }
                             }
-                            ast::TypeImplItem(_) => {}
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => {}
                         }
                     }
                 }
@@ -491,7 +491,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                 //               where the method was defined?
                 Some(ast_map::NodeImplItem(ii)) => {
                     match ii.node {
-                        ast::MethodImplItem(_) => {
+                        ast::MethodImplItem(..) => {
                             let imp = self.tcx.map
                                           .get_parent_did(closest_private_id);
                             match ty::impl_trait_ref(self.tcx, imp) {
@@ -502,7 +502,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                                 _ => ii.vis
                             }
                         }
-                        ast::TypeImplItem(_) => return Allowable,
+                        ast::TypeImplItem(_) |
+                        ast::MacImplItem(_) => return Allowable,
                     }
                 }
                 Some(ast_map::NodeTraitItem(_)) => {
@@ -1125,10 +1126,11 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
             ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
                 for impl_item in impl_items {
                     match impl_item.node {
-                        ast::MethodImplItem(_) => {
+                        ast::MethodImplItem(..) => {
                             check_inherited(tcx, impl_item.span, impl_item.vis);
                         }
-                        ast::TypeImplItem(_) => {}
+                        ast::TypeImplItem(_) |
+                        ast::MacImplItem(_) => {}
                     }
                 }
             }
@@ -1302,10 +1304,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     impl_items.iter()
                               .any(|impl_item| {
                                   match impl_item.node {
-                                      ast::MethodImplItem(_) => {
+                                      ast::MethodImplItem(..) => {
                                           self.exported_items.contains(&impl_item.id)
                                       }
-                                      ast::TypeImplItem(_) => false,
+                                      ast::TypeImplItem(_) |
+                                      ast::MacImplItem(_) => false,
                                   }
                               });
 
@@ -1340,10 +1343,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                             // Those in 3. are warned with this call.
                             for impl_item in impl_items {
                                 match impl_item.node {
-                                    ast::MethodImplItem(..) => {},
                                     ast::TypeImplItem(ref ty) => {
                                         self.visit_ty(ty);
                                     }
+                                    ast::MethodImplItem(..) |
+                                    ast::MacImplItem(_) => {},
                                 }
                             }
                         }
@@ -1354,16 +1358,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     let mut found_pub_static = false;
                     for impl_item in impl_items {
                         match impl_item.node {
-                            ast::MethodImplItem(ref method) => {
-                                if method.pe_sig().explicit_self.node ==
-                                        ast::SelfStatic &&
-                                        self.exported_items
-                                            .contains(&impl_item.id) {
+                            ast::MethodImplItem(ref sig, _) => {
+                                if sig.explicit_self.node == ast::SelfStatic &&
+                                   self.exported_items.contains(&impl_item.id) {
                                     found_pub_static = true;
                                     visit::walk_impl_item(self, impl_item);
                                 }
                             }
-                            ast::TypeImplItem(_) => {}
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => {}
                         }
                     }
                     if found_pub_static {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index dd762f07b72..1cbbcad9550 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -531,8 +531,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                         trait_item.span);
 
                     match trait_item.node {
-                        ast::RequiredMethod(_) |
-                        ast::ProvidedMethod(_) => {
+                        ast::MethodTraitItem(..) => {
                             let def = DefMethod(local_def(trait_item.id),
                                                 FromTrait(local_def(item.id)));
                             // NB: not IMPORTABLE
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 296a9794f1c..e49fdc9c5d3 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -82,7 +82,7 @@ use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
 use syntax::ast::{TypeImplItem};
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
+use syntax::ast_util::{local_def, walk_pat};
 use syntax::attr::AttrMetaMethods;
 use syntax::ext::mtwt;
 use syntax::parse::token::{self, special_names, special_idents};
@@ -242,9 +242,9 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
                 self.visit_generics(generics);
                 ItemRibKind
             }
-            visit::FkMethod(_, method) => {
-                self.visit_generics(&method.pe_sig().generics);
-                self.visit_explicit_self(&method.pe_sig().explicit_self);
+            visit::FkMethod(_, sig) => {
+                self.visit_generics(&sig.generics);
+                self.visit_explicit_self(&sig.explicit_self);
                 MethodRibKind
             }
             visit::FkFnBlock(..) => ClosureRibKind(node_id)
@@ -2814,16 +2814,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         // FIXME #4951: Do we need a node ID here?
 
                         let type_parameters = match trait_item.node {
-                            ast::RequiredMethod(ref sig) => {
+                            ast::MethodTraitItem(ref sig, _) => {
                                 HasTypeParameters(&sig.generics,
                                                   FnSpace,
                                                   MethodRibKind)
                             }
-                            ast::ProvidedMethod(ref m) => {
-                                HasTypeParameters(&m.pe_sig().generics,
-                                                  FnSpace,
-                                                  MethodRibKind)
-                            }
                             ast::TypeTraitItem(..) => {
                                 this.check_if_primitive_type_name(trait_item.ident.name,
                                                                   trait_item.span);
@@ -3066,7 +3061,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 this.with_current_self_type(self_type, |this| {
                     for impl_item in impl_items {
                         match impl_item.node {
-                            MethodImplItem(ref method) => {
+                            MethodImplItem(ref sig, _) => {
                                 // If this is a trait impl, ensure the method
                                 // exists in trait
                                 this.check_trait_item(impl_item.ident.name,
@@ -3075,7 +3070,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 // We also need a new scope for the method-
                                 // specific type parameters.
                                 let type_parameters =
-                                    HasTypeParameters(&method.pe_sig().generics,
+                                    HasTypeParameters(&sig.generics,
                                                       FnSpace,
                                                       MethodRibKind);
                                 this.with_type_parameter_rib(type_parameters, |this| {
@@ -3090,6 +3085,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                                 this.visit_ty(ty);
                             }
+                            ast::MacImplItem(_) => {}
                         }
                     }
                 });
@@ -3953,19 +3949,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         fn is_static_method(this: &Resolver, did: DefId) -> bool {
             if did.krate == ast::LOCAL_CRATE {
-                let explicit_self = match this.ast_map.get(did.node) {
+                let sig = match this.ast_map.get(did.node) {
                     ast_map::NodeTraitItem(trait_item) => match trait_item.node {
-                        ast::RequiredMethod(ref m) => &m.explicit_self,
-                        ast::ProvidedMethod(ref m) => &m.pe_sig().explicit_self,
+                        ast::MethodTraitItem(ref sig, _) => sig,
                         _ => return false
                     },
                     ast_map::NodeImplItem(impl_item) => match impl_item.node {
-                        ast::MethodImplItem(ref m) => &m.pe_sig().explicit_self,
+                        ast::MethodImplItem(ref sig, _) => sig,
                         _ => return false
                     },
                     _ => return false
                 };
-                explicit_self.node == ast::SelfStatic
+                sig.explicit_self.node == ast::SelfStatic
             } else {
                 csearch::is_static_method(&this.session.cstore, did)
             }
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 2b1def22ed9..83bb5efb425 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -37,7 +37,7 @@ use std::env;
 use std::fs::{self, File};
 use std::path::{Path, PathBuf};
 
-use syntax::ast_util::{self, PostExpansionMethod};
+use syntax::ast_util;
 use syntax::ast::{self, NodeId, DefId};
 use syntax::ast_map::NodeItem;
 use syntax::attr;
@@ -284,7 +284,8 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_method(&mut self, method: &ast::Method,
+    fn process_method(&mut self, sig: &ast::MethodSig,
+                      body: Option<&ast::Block>,
                       id: ast::NodeId, ident: ast::Ident,
                       span: Span) {
         if generated_code(span) {
@@ -351,8 +352,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             },
         };
 
-        let qualname = format!("{}::{}", qualname, &get_ident(ident));
-        let qualname = &qualname[..];
+        let qualname = &format!("{}::{}", qualname, &get_ident(ident));
 
         // record the decl for this def (if it has one)
         let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
@@ -364,39 +364,44 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                     }
                     ty::TypeTraitItemId(_) => false,
                 } {
-                    Some(def_id)
+                    Some(def_id.def_id())
                 } else {
                     None
                 }
             });
-        let decl_id = match decl_id {
-            None => None,
-            Some(id) => Some(id.def_id()),
-        };
 
         let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn);
-        self.fmt.method_str(span,
-                            sub_span,
-                            id,
-                            qualname,
-                            decl_id,
-                            scope_id);
-
-        self.process_formals(&method.pe_sig().decl.inputs, qualname);
+        if body.is_some() {
+            self.fmt.method_str(span,
+                                sub_span,
+                                id,
+                                qualname,
+                                decl_id,
+                                scope_id);
+            self.process_formals(&sig.decl.inputs, qualname);
+        } else {
+            self.fmt.method_decl_str(span,
+                                     sub_span,
+                                     id,
+                                     qualname,
+                                     scope_id);
+        }
 
         // walk arg and return types
-        for arg in &method.pe_sig().decl.inputs {
-            self.visit_ty(&*arg.ty);
+        for arg in &sig.decl.inputs {
+            self.visit_ty(&arg.ty);
         }
 
-        if let ast::Return(ref ret_ty) = method.pe_sig().decl.output {
-            self.visit_ty(&**ret_ty);
+        if let ast::Return(ref ret_ty) = sig.decl.output {
+            self.visit_ty(ret_ty);
         }
 
         // walk the fn body
-        self.nest(id, |v| v.visit_block(&*method.pe_body()));
+        if let Some(body) = body {
+            self.nest(id, |v| v.visit_block(body));
+        }
 
-        self.process_generic_params(&method.pe_sig().generics,
+        self.process_generic_params(&sig.generics,
                                     span,
                                     qualname,
                                     id);
@@ -1226,51 +1231,9 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
 
     fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
         match trait_item.node {
-            ast::RequiredMethod(ref method_type) => {
-                if generated_code(trait_item.span) {
-                    return;
-                }
-
-                let mut scope_id;
-                let mut qualname = match ty::trait_of_item(&self.analysis.ty_cx,
-                                                           ast_util::local_def(trait_item.id)) {
-                    Some(def_id) => {
-                        scope_id = def_id.node;
-                        format!("::{}::", ty::item_path_str(&self.analysis.ty_cx, def_id))
-                    },
-                    None => {
-                        self.sess.span_bug(trait_item.span,
-                                           &format!("Could not find trait for method {}",
-                                                   trait_item.id));
-                    },
-                };
-
-                qualname.push_str(&get_ident(trait_item.ident));
-                let qualname = &qualname[..];
-
-                let sub_span = self.span.sub_span_after_keyword(trait_item.span, keywords::Fn);
-                self.fmt.method_decl_str(trait_item.span,
-                                         sub_span,
-                                         trait_item.id,
-                                         qualname,
-                                         scope_id);
-
-                // walk arg and return types
-                for arg in &method_type.decl.inputs {
-                    self.visit_ty(&*arg.ty);
-                }
-
-                if let ast::Return(ref ret_ty) = method_type.decl.output {
-                    self.visit_ty(&**ret_ty);
-                }
-
-                self.process_generic_params(&method_type.generics,
-                                            trait_item.span,
-                                            qualname,
-                                            trait_item.id);
-            }
-            ast::ProvidedMethod(ref method) => {
-                self.process_method(method, trait_item.id, trait_item.ident, trait_item.span);
+            ast::MethodTraitItem(ref sig, ref body) => {
+                self.process_method(sig, body.as_ref().map(|x| &**x),
+                                    trait_item.id, trait_item.ident, trait_item.span);
             }
             ast::TypeTraitItem(..) => {}
         }
@@ -1278,10 +1241,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
 
     fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
         match impl_item.node {
-            ast::MethodImplItem(ref method) => {
-                self.process_method(method, impl_item.id, impl_item.ident, impl_item.span);
+            ast::MethodImplItem(ref sig, ref body) => {
+                self.process_method(sig, Some(body), impl_item.id,
+                                    impl_item.ident, impl_item.span);
             }
-            ast::TypeImplItem(_) => {}
+            ast::TypeImplItem(_) |
+            ast::MacImplItem(_) => {}
         }
     }
 
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 9616bf8b648..74326d4ea91 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -94,7 +94,7 @@ use std::rc::Rc;
 use std::str;
 use std::{i8, i16, i32, i64};
 use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
-use syntax::ast_util::{local_def, PostExpansionMethod};
+use syntax::ast_util::local_def;
 use syntax::attr::AttrMetaMethods;
 use syntax::attr;
 use syntax::codemap::Span;
@@ -1263,15 +1263,15 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
         Some(ast_map::NodeItem(i)) => {
             match i.node {
                 ast::ItemFn(_, _, _, _, ref blk) => {
-                    &**blk
+                    blk
                 }
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
             }
         }
         Some(ast_map::NodeTraitItem(trait_item)) => {
             match trait_item.node {
-                ast::ProvidedMethod(ref m) => m.pe_body(),
-                ast::RequiredMethod(_) => {
+                ast::MethodTraitItem(_, Some(ref body)) => body,
+                ast::MethodTraitItem(_, None) => {
                     tcx.sess.bug("unexpected variant: required trait method \
                                   in has_nested_returns")
                 }
@@ -1283,16 +1283,20 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
         }
         Some(ast_map::NodeImplItem(impl_item)) => {
             match impl_item.node {
-                ast::MethodImplItem(ref m) => m.pe_body(),
+                ast::MethodImplItem(_, ref body) => body,
                 ast::TypeImplItem(_) => {
                     tcx.sess.bug("unexpected variant: associated type impl item in \
                                   has_nested_returns")
                 }
+                ast::MacImplItem(_) => {
+                    tcx.sess.bug("unexpected variant: unexpanded macro impl item in \
+                                  has_nested_returns")
+                }
             }
         }
         Some(ast_map::NodeExpr(e)) => {
             match e.node {
-                ast::ExprClosure(_, _, ref blk) => &**blk,
+                ast::ExprClosure(_, _, ref blk) => blk,
                 _ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
             }
         }
@@ -2805,11 +2809,11 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
         ast_map::NodeTraitItem(trait_item) => {
             debug!("get_item_val(): processing a NodeTraitItem");
             match trait_item.node {
-                ast::RequiredMethod(_) | ast::TypeTraitItem(..) => {
+                ast::MethodTraitItem(_, None) | ast::TypeTraitItem(..) => {
                     ccx.sess().span_bug(trait_item.span,
                         "unexpected variant: required trait method in get_item_val()");
                 }
-                ast::ProvidedMethod(_) => {
+                ast::MethodTraitItem(_, Some(_)) => {
                     register_method(ccx, id, &trait_item.attrs, trait_item.span)
                 }
             }
@@ -2817,13 +2821,17 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
         ast_map::NodeImplItem(impl_item) => {
             match impl_item.node {
-                ast::MethodImplItem(_) => {
+                ast::MethodImplItem(..) => {
                     register_method(ccx, id, &impl_item.attrs, impl_item.span)
                 }
                 ast::TypeImplItem(_) => {
                     ccx.sess().span_bug(impl_item.span,
                         "unexpected variant: associated type in get_item_val()")
                 }
+                ast::MacImplItem(_) => {
+                    ccx.sess().span_bug(impl_item.span,
+                        "unexpected variant: unexpanded macro in get_item_val()")
+                }
             }
         }
 
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 11495c7e6a3..b5ab2c28251 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -217,7 +217,6 @@ use std::rc::{Rc, Weak};
 use syntax::util::interner::Interner;
 use syntax::codemap::{Span, Pos};
 use syntax::{ast, codemap, ast_util, ast_map, attr};
-use syntax::ast_util::PostExpansionMethod;
 use syntax::parse::token::{self, special_idents};
 
 const DW_LANG_RUST: c_uint = 0x9000;
@@ -1292,7 +1291,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
             match item.node {
                 ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => {
-                    (item.ident, fn_decl, generics, &**top_level_block, item.span, true)
+                    (item.ident, fn_decl, generics, top_level_block, item.span, true)
                 }
                 _ => {
                     cx.sess().span_bug(item.span,
@@ -1302,15 +1301,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         }
         ast_map::NodeImplItem(impl_item) => {
             match impl_item.node {
-                ast::MethodImplItem(ref method) => {
+                ast::MethodImplItem(ref sig, ref body) => {
                     if contains_nodebug_attribute(&impl_item.attrs) {
                         return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
                     (impl_item.ident,
-                     &method.pe_sig().decl,
-                     &method.pe_sig().generics,
-                     method.pe_body(),
+                     &sig.decl,
+                     &sig.generics,
+                     body,
                      impl_item.span,
                      true)
                 }
@@ -1319,6 +1318,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                        "create_function_debug_context() \
                                         called on associated type?!")
                 }
+                ast::MacImplItem(_) => {
+                    cx.sess().span_bug(impl_item.span,
+                                       "create_function_debug_context() \
+                                        called on unexpanded macro?!")
+                }
             }
         }
         ast_map::NodeExpr(ref expr) => {
@@ -1330,7 +1334,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         // This is not quite right. It should actually inherit
                         // the generics of the enclosing function.
                         &empty_generics,
-                        &**top_level_block,
+                        top_level_block,
                         expr.span,
                         // Don't try to lookup the item path:
                         false)
@@ -1341,15 +1345,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         }
         ast_map::NodeTraitItem(trait_item) => {
             match trait_item.node {
-                ast::ProvidedMethod(ref method) => {
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
                     if contains_nodebug_attribute(&trait_item.attrs) {
                         return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
                     (trait_item.ident,
-                     &method.pe_sig().decl,
-                     &method.pe_sig().generics,
-                     method.pe_body(),
+                     &sig.decl,
+                     &sig.generics,
+                     body,
                      trait_item.span,
                      true)
                 }
diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs
index eacc40edcc6..2034c6223c1 100644
--- a/src/librustc_trans/trans/inline.rs
+++ b/src/librustc_trans/trans/inline.rs
@@ -17,7 +17,7 @@ use trans::common::*;
 use middle::ty;
 
 use syntax::ast;
-use syntax::ast_util::{local_def, PostExpansionMethod};
+use syntax::ast_util::local_def;
 
 fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
     -> Option<ast::DefId> {
@@ -146,19 +146,19 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
 
             // Translate monomorphic impl methods immediately.
-            if let ast::MethodImplItem(ref mth) = impl_item.node {
+            if let ast::MethodImplItem(ref sig, ref body) = impl_item.node {
                 let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
                 if impl_tpt.generics.types.is_empty() &&
-                        mth.pe_sig().generics.ty_params.is_empty() {
+                        sig.generics.ty_params.is_empty() {
                     let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
                     let llfn = get_item_val(ccx, impl_item.id);
                     trans_fn(ccx,
-                            &*mth.pe_sig().decl,
-                            &*mth.pe_body(),
-                            llfn,
-                            empty_substs,
-                            impl_item.id,
-                            &[]);
+                             &sig.decl,
+                             body,
+                             llfn,
+                             empty_substs,
+                             impl_item.id,
+                             &[]);
                     // Use InternalLinkage so LLVM can optimize more aggressively.
                     SetLinkage(llfn, InternalLinkage);
                 }
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 8df086fd232..ba3798d7d80 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -41,7 +41,6 @@ use std::rc::Rc;
 use syntax::abi::{Rust, RustCall};
 use syntax::parse::token;
 use syntax::{ast, ast_map, attr, visit};
-use syntax::ast_util::PostExpansionMethod;
 use syntax::codemap::DUMMY_SP;
 use syntax::ptr::P;
 
@@ -69,29 +68,25 @@ pub fn trans_impl(ccx: &CrateContext,
     if !generics.ty_params.is_empty() {
         for impl_item in impl_items {
             match impl_item.node {
-                ast::MethodImplItem(_) => {
+                ast::MethodImplItem(..) => {
                     visit::walk_impl_item(&mut v, impl_item);
                 }
-                ast::TypeImplItem(_) => {}
+                ast::TypeImplItem(_) |
+                ast::MacImplItem(_) => {}
             }
         }
         return;
     }
     for impl_item in impl_items {
         match impl_item.node {
-            ast::MethodImplItem(ref method) => {
-                if method.pe_sig().generics.ty_params.len() == 0 {
+            ast::MethodImplItem(ref sig, ref body) => {
+                if sig.generics.ty_params.len() == 0 {
                     let trans_everywhere = attr::requests_inline(&impl_item.attrs);
                     for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
                         let llfn = get_item_val(ccx, impl_item.id);
                         let empty_substs = tcx.mk_substs(Substs::trans_empty());
-                        trans_fn(ccx,
-                                 &method.pe_sig().decl,
-                                 method.pe_body(),
-                                 llfn,
-                                 empty_substs,
-                                 impl_item.id,
-                                 &[]);
+                        trans_fn(ccx, &sig.decl, body, llfn,
+                                 empty_substs, impl_item.id, &[]);
                         update_linkage(ccx,
                                        llfn,
                                        Some(impl_item.id),
@@ -100,7 +95,8 @@ pub fn trans_impl(ccx: &CrateContext,
                 }
                 visit::walk_impl_item(&mut v, impl_item);
             }
-            ast::TypeImplItem(_) => {}
+            ast::TypeImplItem(_) |
+            ast::MacImplItem(_) => {}
         }
     }
 }
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 80271a72c68..2083e737f89 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -29,7 +29,7 @@ use util::ppaux::Repr;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{local_def, PostExpansionMethod};
+use syntax::ast_util::local_def;
 use syntax::attr;
 use syntax::codemap::DUMMY_SP;
 use std::hash::{Hasher, Hash, SipHasher};
@@ -218,13 +218,13 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         }
         ast_map::NodeImplItem(impl_item) => {
             match impl_item.node {
-                ast::MethodImplItem(ref mth) => {
+                ast::MethodImplItem(ref sig, ref body) => {
                     let d = mk_lldecl(abi::Rust);
                     let needs_body = setup_lldecl(d, &impl_item.attrs);
                     if needs_body {
                         trans_fn(ccx,
-                                 &mth.pe_sig().decl,
-                                 mth.pe_body(),
+                                 &sig.decl,
+                                 body,
                                  d,
                                  psubsts,
                                  impl_item.id,
@@ -235,15 +235,18 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 ast::TypeImplItem(_) => {
                     ccx.sess().bug("can't monomorphize an associated type")
                 }
+                ast::MacImplItem(_) => {
+                    ccx.sess().bug("can't monomorphize an unexpanded macro")
+                }
             }
         }
         ast_map::NodeTraitItem(trait_item) => {
             match trait_item.node {
-                ast::ProvidedMethod(ref mth) => {
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
                     let d = mk_lldecl(abi::Rust);
                     let needs_body = setup_lldecl(d, &trait_item.attrs);
                     if needs_body {
-                        trans_fn(ccx, &mth.pe_sig().decl, mth.pe_body(), d,
+                        trans_fn(ccx, &sig.decl, body, d,
                                  psubsts, trait_item.id, &[]);
                     }
                     d
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 470e1d54c7f..41951ab2b62 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -119,8 +119,8 @@ use std::iter::repeat;
 use std::slice;
 use syntax::{self, abi, attr};
 use syntax::attr::AttrMetaMethods;
-use syntax::ast::{self, ProvidedMethod, RequiredMethod, TypeTraitItem, DefId, Visibility};
-use syntax::ast_util::{self, local_def, PostExpansionMethod};
+use syntax::ast::{self, DefId, Visibility};
+use syntax::ast_util::{self, local_def};
 use syntax::codemap::{self, Span};
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
@@ -740,11 +740,12 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
 
         for impl_item in impl_items {
             match impl_item.node {
-                ast::MethodImplItem(ref m) => {
-                    check_method_body(ccx, &impl_pty.generics, m,
+                ast::MethodImplItem(ref sig, ref body) => {
+                    check_method_body(ccx, &impl_pty.generics, sig, body,
                                       impl_item.id, impl_item.span);
                 }
-                ast::TypeImplItem(_) => {
+                ast::TypeImplItem(_) |
+                ast::MacImplItem(_) => {
                     // Nothing to do here.
                 }
             }
@@ -756,15 +757,15 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
         let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
         for trait_item in trait_items {
             match trait_item.node {
-                RequiredMethod(..) => {
+                ast::MethodTraitItem(_, None) => {
                     // Nothing to do, since required methods don't have
                     // bodies to check.
                 }
-                ProvidedMethod(ref m) => {
-                    check_method_body(ccx, &trait_def.generics, m,
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
+                    check_method_body(ccx, &trait_def.generics, sig, body,
                                       trait_item.id, trait_item.span);
                 }
-                TypeTraitItem(..) => {
+                ast::TypeTraitItem(..) => {
                     // Nothing to do.
                 }
             }
@@ -857,7 +858,8 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 /// * `method`: the method definition
 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                item_generics: &ty::Generics<'tcx>,
-                               method: &'tcx ast::Method,
+                               sig: &'tcx ast::MethodSig,
+                               body: &'tcx ast::Block,
                                id: ast::NodeId, span: Span) {
     debug!("check_method_body(item_generics={}, id={})",
             item_generics.repr(ccx.tcx), id);
@@ -866,13 +868,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let fty = ty::node_id_to_type(ccx.tcx, id);
     debug!("check_method_body: fty={}", fty.repr(ccx.tcx));
 
-    check_bare_fn(ccx,
-                  &*method.pe_sig().decl,
-                  &*method.pe_body(),
-                  id,
-                  span,
-                  fty,
-                  param_env);
+    check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
 }
 
 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@@ -887,7 +883,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     // and compatible with trait signature
     for impl_item in impl_items {
         match impl_item.node {
-            ast::MethodImplItem(ref impl_method) => {
+            ast::MethodImplItem(_, ref body) => {
                 let impl_method_def_id = local_def(impl_item.id);
                 let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
                                                           impl_method_def_id);
@@ -905,7 +901,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 compare_impl_method(ccx.tcx,
                                                     &**impl_method_ty,
                                                     impl_item.span,
-                                                    impl_method.pe_body().id,
+                                                    body.id,
                                                     &**trait_method_ty,
                                                     &*impl_trait_ref);
                             }
@@ -969,6 +965,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                     }
                 }
             }
+            ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,
+                                                     "unexpanded macro")
         }
     }
 
@@ -981,10 +979,11 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                 let is_implemented =
                     impl_items.iter().any(|ii| {
                         match ii.node {
-                            ast::MethodImplItem(_) => {
+                            ast::MethodImplItem(..) => {
                                 ii.ident.name == trait_method.name
                             }
-                            ast::TypeImplItem(_) => false,
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => false,
                         }
                     });
                 let is_provided =
@@ -999,7 +998,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         ast::TypeImplItem(_) => {
                             ii.ident.name == associated_type.name
                         }
-                        ast::MethodImplItem(_) => false,
+                        ast::MethodImplItem(..) |
+                        ast::MacImplItem(_) => false,
                     }
                 });
                 if !is_implemented {
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 0e50938abc4..adbf4c6b210 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -499,7 +499,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
     }
 
     fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) {
-        if let ast::RequiredMethod(_) = trait_item.node {
+        if let ast::MethodTraitItem(_, None) = trait_item.node {
             match ty::impl_or_trait_item(self.tcx(), local_def(trait_item.id)) {
                 ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
                     reject_non_type_param_bounds(
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index a4eab5b7a26..6b0fb8ac71a 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -279,12 +279,16 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
                 let mut items: Vec<ImplOrTraitItemId> =
                         impl_items.iter().map(|impl_item| {
                     match impl_item.node {
-                        ast::MethodImplItem(_) => {
+                        ast::MethodImplItem(..) => {
                             MethodTraitItemId(local_def(impl_item.id))
                         }
                         ast::TypeImplItem(_) => {
                             TypeTraitItemId(local_def(impl_item.id))
                         }
+                        ast::MacImplItem(_) => {
+                            self.crate_context.tcx.sess.span_bug(impl_item.span,
+                                                                 "unexpanded macro");
+                        }
                     }
                 }).collect();
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index a2ca228b11a..23726805767 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -89,7 +89,7 @@ use std::rc::Rc;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{local_def, PostExpansionMethod};
+use syntax::ast_util::local_def;
 use syntax::codemap::Span;
 use syntax::parse::token::{special_idents};
 use syntax::parse::token;
@@ -847,7 +847,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             // Convert all the associated types.
             for impl_item in impl_items {
                 match impl_item.node {
-                    ast::MethodImplItem(_) => {}
                     ast::TypeImplItem(ref ty) => {
                         if opt_trait_ref.is_none() {
                             span_err!(tcx.sess, impl_item.span, E0202,
@@ -867,20 +866,23 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                                                            ty::GenericPredicates::empty());
                         write_ty_to_tcx(tcx, impl_item.id, typ);
                     }
+                    ast::MethodImplItem(..) |
+                    ast::MacImplItem(_) => {}
                 }
             }
 
             let methods = impl_items.iter().filter_map(|ii| {
                 match ii.node {
-                    ast::MethodImplItem(ref m) => {
+                    ast::MethodImplItem(ref sig, _) => {
                         // if the method specifies a visibility, use that, otherwise
                         // inherit the visibility from the impl (so `foo` in `pub impl
                         // { fn foo(); }` is public, but private in `priv impl { fn
                         // foo(); }`).
                         let method_vis = ii.vis.inherit_from(parent_visibility);
-                        Some((m.pe_sig(), ii.id, ii.ident, method_vis, ii.span))
+                        Some((sig, ii.id, ii.ident, method_vis, ii.span))
                     }
-                    ast::TypeImplItem(_) => None
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => None
                 }
             });
             convert_methods(ccx,
@@ -892,16 +894,17 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
 
             for impl_item in impl_items {
                 match impl_item.node {
-                    ast::MethodImplItem(ref method) => {
-                        let body_id = method.pe_body().id;
+                    ast::MethodImplItem(ref sig, ref body) => {
+                        let body_id = body.id;
                         check_method_self_type(ccx,
                                                &BindingRscope::new(),
                                                ccx.method_ty(impl_item.id),
                                                selfty,
-                                               &method.pe_sig().explicit_self,
+                                               &sig.explicit_self,
                                                body_id);
                     }
-                    ast::TypeImplItem(_) => {}
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => {}
                 }
             }
 
@@ -930,8 +933,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             // Convert all the associated types.
             for trait_item in trait_items {
                 match trait_item.node {
-                    ast::RequiredMethod(_) |
-                    ast::ProvidedMethod(_) => {}
+                    ast::MethodTraitItem(..) => {}
                     ast::TypeTraitItem(..) => {
                         convert_associated_type(ccx, TraitContainer(local_def(it.id)),
                                                 trait_item.ident, trait_item.id, ast::Public);
@@ -941,8 +943,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
 
             let methods = trait_items.iter().filter_map(|ti| {
                 let sig = match ti.node {
-                    ast::RequiredMethod(ref sig) => sig,
-                    ast::ProvidedMethod(ref m) => m.pe_sig(),
+                    ast::MethodTraitItem(ref sig, _) => sig,
                     ast::TypeTraitItem(..) => return None,
                 };
                 Some((sig, ti.id, ti.ident, ast::Inherited, ti.span))
@@ -960,8 +961,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
                 let def_id = local_def(trait_item.id);
                 match trait_item.node {
-                    ast::RequiredMethod(_) |
-                    ast::ProvidedMethod(_) => {
+                    ast::MethodTraitItem(..) => {
                         ty::MethodTraitItemId(def_id)
                     }
                     ast::TypeTraitItem(..) => {
@@ -975,8 +975,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             // we have a method type stored for every method.
             for trait_item in trait_items {
                 let sig = match trait_item.node {
-                    ast::RequiredMethod(ref sig) => sig,
-                    ast::ProvidedMethod(ref method) => method.pe_sig(),
+                    ast::MethodTraitItem(ref sig, _) => sig,
                     ast::TypeTraitItem(..) => continue
                 };
                 check_method_self_type(ccx,
@@ -1196,7 +1195,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
     let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
         match trait_item.node {
-            ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None,
+            ast::MethodTraitItem(..) => None,
             ast::TypeTraitItem(..) => Some(trait_item.ident.name),
         }
     }).collect();
@@ -1269,7 +1268,7 @@ fn trait_defines_associated_type_named(ccx: &CrateCtxt,
     trait_items.iter().any(|trait_item| {
         match trait_item.node {
             ast::TypeTraitItem(..) => trait_item.ident.name == assoc_name,
-            ast::RequiredMethod(_) | ast::ProvidedMethod(_) => false,
+            ast::MethodTraitItem(..) => false,
         }
     })
 }
@@ -1329,7 +1328,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
         trait_items.iter().flat_map(|trait_item| {
             let bounds = match trait_item.node {
                 ast::TypeTraitItem(ref bounds, _) => bounds,
-                ast::RequiredMethod(..) | ast::ProvidedMethod(..) => {
+                ast::MethodTraitItem(..) => {
                     return vec!().into_iter();
                 }
             };
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 05139bf1eab..e91e95961c5 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -28,7 +28,6 @@ use syntax;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_util;
-use syntax::ast_util::PostExpansionMethod;
 use syntax::attr;
 use syntax::attr::{AttributeMethods, AttrMetaMethods};
 use syntax::codemap;
@@ -949,10 +948,10 @@ pub struct Method {
     pub abi: abi::Abi
 }
 
-impl Clean<Method> for ast::Method {
+impl Clean<Method> for ast::MethodSig {
     fn clean(&self, cx: &DocContext) -> Method {
-        let all_inputs = &self.pe_sig().decl.inputs;
-        let inputs = match self.pe_sig().explicit_self.node {
+        let all_inputs = &self.decl.inputs;
+        let inputs = match self.explicit_self.node {
             ast::SelfStatic => &**all_inputs,
             _ => &all_inputs[1..]
         };
@@ -960,15 +959,15 @@ impl Clean<Method> for ast::Method {
             inputs: Arguments {
                 values: inputs.clean(cx),
             },
-            output: self.pe_sig().decl.output.clean(cx),
+            output: self.decl.output.clean(cx),
             attrs: Vec::new()
         };
         Method {
-            generics: self.pe_sig().generics.clean(cx),
-            self_: self.pe_sig().explicit_self.node.clean(cx),
-            unsafety: self.pe_sig().unsafety.clone(),
+            generics: self.generics.clean(cx),
+            self_: self.explicit_self.node.clean(cx),
+            unsafety: self.unsafety.clone(),
             decl: decl,
-            abi: self.pe_sig().abi
+            abi: self.abi
         }
     }
 }
@@ -1190,8 +1189,12 @@ impl Clean<PolyTrait> for ast::PolyTraitRef {
 impl Clean<Item> for ast::TraitItem {
     fn clean(&self, cx: &DocContext) -> Item {
         let inner = match self.node {
-            ast::ProvidedMethod(ref m) => MethodItem(m.clean(cx)),
-            ast::RequiredMethod(ref m) => TyMethodItem(m.clean(cx)),
+            ast::MethodTraitItem(ref sig, Some(_)) => {
+                MethodItem(sig.clean(cx))
+            }
+            ast::MethodTraitItem(ref sig, None) => {
+                TyMethodItem(sig.clean(cx))
+            }
             ast::TypeTraitItem(ref bounds, ref default) => {
                 AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
             }
@@ -1211,7 +1214,9 @@ impl Clean<Item> for ast::TraitItem {
 impl Clean<Item> for ast::ImplItem {
     fn clean(&self, cx: &DocContext) -> Item {
         let inner = match self.node {
-            ast::MethodImplItem(ref m) => MethodItem(m.clean(cx)),
+            ast::MethodImplItem(ref sig, _) => {
+                MethodItem(sig.clean(cx))
+            }
             ast::TypeImplItem(ref ty) => TypedefItem(Typedef {
                 type_: ty.clean(cx),
                 generics: Generics {
@@ -1220,6 +1225,11 @@ impl Clean<Item> for ast::ImplItem {
                     where_predicates: Vec::new()
                 },
             }),
+            ast::MacImplItem(_) => {
+                MacroItem(Macro {
+                    source: self.span.to_src(cx),
+                })
+            }
         };
         Item {
             name: Some(self.ident.clean(cx)),
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);
+        }
     }
 }
 
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs
index 8218fa0c489..36a34bc6c8b 100644
--- a/src/test/auxiliary/macro_crate_test.rs
+++ b/src/test/auxiliary/macro_crate_test.rs
@@ -16,7 +16,7 @@
 extern crate syntax;
 extern crate rustc;
 
-use syntax::ast::{TokenTree, Item, MetaItem, ImplItem, TraitItem, Method};
+use syntax::ast::{self, TokenTree, Item, MetaItem};
 use syntax::codemap::Span;
 use syntax::ext::base::*;
 use syntax::parse::token;
@@ -81,7 +81,26 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
                 ..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone()
             }))
         }
-        it => it
+        Annotatable::ImplItem(it) => {
+            quote_item!(cx, impl X { fn foo(&self) -> i32 { 42 } }).unwrap().and_then(|i| {
+                match i.node {
+                    ast::ItemImpl(_, _, _, _, _, mut items) => {
+                        Annotatable::ImplItem(items.pop().expect("impl method not found"))
+                    }
+                    _ => unreachable!("impl parsed to something other than impl")
+                }
+            })
+        }
+        Annotatable::TraitItem(it) => {
+            quote_item!(cx, trait X { fn foo(&self) -> i32 { 0 } }).unwrap().and_then(|i| {
+                match i.node {
+                    ast::ItemTrait(_, _, _, mut items) => {
+                        Annotatable::TraitItem(items.pop().expect("trait method not found"))
+                    }
+                    _ => unreachable!("trait parsed to something other than trait")
+                }
+            })
+        }
     }
 }
 
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 788236a27a5..04db6c8c8f3 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -60,7 +60,7 @@ trait B {
 
 pub trait C { //~ ERROR: missing documentation for a trait
     fn foo(&self); //~ ERROR: missing documentation for a trait method
-    fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a default method
+    fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a trait method
 }
 
 #[allow(missing_docs)]