about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-12 20:13:23 +0000
committerbors <bors@rust-lang.org>2015-03-12 20:13:23 +0000
commitc9b03c24ec346e6405883032094f47805ef9c43e (patch)
treecbb2bb6a0cd2a2e65b2cacd87d31bd8737f02e7d
parent538840bc2d1b634a2a34b2c8bd72d99894058b66 (diff)
parent9da918548d77182ca64f375fb6da24036d5ad60c (diff)
downloadrust-c9b03c24ec346e6405883032094f47805ef9c43e.tar.gz
rust-c9b03c24ec346e6405883032094f47805ef9c43e.zip
Auto merge of #23265 - eddyb:meth-ast-refactor, r=nikomatsakis
The end result is that common fields (id, name, attributes, etc.) are stored in now-structures `ImplItem` and `TraitItem`.
The signature of a method is no longer duplicated between methods with a body (default/impl) and those without, they now share `MethodSig`.

This is also a [breaking-change] because of minor bugfixes and changes to syntax extensions:
* `pub fn` methods in a trait no longer parse - remove the `pub`, it has no meaning anymore
* `MacResult::make_methods` is now `make_impl_items` and the return type has changed accordingly
* `quote_method` is gone, because `P<ast::Method>` doesn't exist and it couldn't represent a full method anyways - could be replaced by `quote_impl_item`/`quote_trait_item` in the future, but I do hope we realize how silly that combinatorial macro expansion is and settle on a single `quote` macro + some type hints - or just no types at all (only token-trees)

r? @nikomatsakis This is necessary (hopefully also sufficient) for associated constants.
-rw-r--r--src/librustc/lint/context.rs41
-rw-r--r--src/librustc/lint/mod.rs2
-rw-r--r--src/librustc/metadata/encoder.rs104
-rw-r--r--src/librustc/middle/astencode.rs63
-rw-r--r--src/librustc/middle/dead.rs64
-rw-r--r--src/librustc/middle/effect.rs5
-rw-r--r--src/librustc/middle/infer/error_reporting.rs50
-rw-r--r--src/librustc/middle/reachable.rs50
-rw-r--r--src/librustc/middle/resolve_lifetime.rs20
-rw-r--r--src/librustc/middle/stability.rs49
-rw-r--r--src/librustc/middle/ty.rs73
-rw-r--r--src/librustc/util/ppaux.rs13
-rw-r--r--src/librustc_back/svh.rs12
-rw-r--r--src/librustc_borrowck/borrowck/fragments.rs22
-rw-r--r--src/librustc_lint/builtin.rs127
-rw-r--r--src/librustc_privacy/lib.rs153
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs53
-rw-r--r--src/librustc_resolve/lib.rs65
-rw-r--r--src/librustc_trans/save/mod.rs185
-rw-r--r--src/librustc_trans/trans/base.rs89
-rw-r--r--src/librustc_trans/trans/debuginfo.rs52
-rw-r--r--src/librustc_trans/trans/inline.rs84
-rw-r--r--src/librustc_trans/trans/meth.rs57
-rw-r--r--src/librustc_trans/trans/monomorphize.rs31
-rw-r--r--src/librustc_typeck/astconv.rs26
-rw-r--r--src/librustc_typeck/check/mod.rs96
-rw-r--r--src/librustc_typeck/check/wf.rs32
-rw-r--r--src/librustc_typeck/coherence/mod.rs28
-rw-r--r--src/librustc_typeck/collect.rs529
-rw-r--r--src/librustdoc/clean/inline.rs18
-rw-r--r--src/librustdoc/clean/mod.rs226
-rw-r--r--src/librustdoc/doctree.rs4
-rw-r--r--src/librustdoc/fold.rs28
-rw-r--r--src/librustdoc/html/render.rs52
-rw-r--r--src/librustdoc/stability_summary.rs34
-rw-r--r--src/libsyntax/ast.rs82
-rw-r--r--src/libsyntax/ast_map/blocks.rs32
-rw-r--r--src/libsyntax/ast_map/mod.rs269
-rw-r--r--src/libsyntax/ast_util.rs124
-rw-r--r--src/libsyntax/config.rs23
-rw-r--r--src/libsyntax/ext/base.rs63
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs42
-rw-r--r--src/libsyntax/ext/expand.rs168
-rw-r--r--src/libsyntax/ext/quote.rs11
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs9
-rw-r--r--src/libsyntax/fold.rs178
-rw-r--r--src/libsyntax/parse/parser.rs155
-rw-r--r--src/libsyntax/print/pprust.rs209
-rw-r--r--src/libsyntax/visit.rs121
-rw-r--r--src/test/auxiliary/macro_crate_test.rs24
-rw-r--r--src/test/compile-fail/impl-duplicate-methods.rs2
-rw-r--r--src/test/compile-fail/issue-4265.rs2
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs4
-rw-r--r--src/test/compile-fail/unnecessary-private.rs2
-rw-r--r--src/test/compile-fail/useless-priv.rs5
-rw-r--r--src/test/parse-fail/issue-21153.rs2
-rw-r--r--src/test/parse-fail/trait-pub-assoc-ty.rs (renamed from src/test/compile-fail/useless-priv2.rs)9
-rw-r--r--src/test/parse-fail/trait-pub-method.rs15
-rw-r--r--src/test/run-pass-fulldeps/quote-tokens.rs3
59 files changed, 1516 insertions, 2575 deletions
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index a777e1f7f75..9aa6395b7b2 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -519,28 +519,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
 
     fn visit_fn(&mut self, fk: FnKind<'v>, decl: &'v ast::FnDecl,
                 body: &'v ast::Block, span: Span, id: ast::NodeId) {
-        match fk {
-            visit::FkMethod(_, _, m) => {
-                self.with_lint_attrs(&m.attrs, |cx| {
-                    run_lints!(cx, check_fn, fk, decl, body, span, id);
-                    cx.visit_ids(|v| {
-                        v.visit_fn(fk, decl, body, span, id);
-                    });
-                    visit::walk_fn(cx, fk, decl, body, span);
-                })
-            },
-            _ => {
-                run_lints!(self, check_fn, fk, decl, body, span, id);
-                visit::walk_fn(self, fk, decl, body, span);
-            }
-        }
-    }
-
-    fn visit_ty_method(&mut self, t: &ast::TypeMethod) {
-        self.with_lint_attrs(&t.attrs, |cx| {
-            run_lints!(cx, check_ty_method, t);
-            visit::walk_ty_method(cx, t);
-        })
+        run_lints!(self, check_fn, fk, decl, body, span, id);
+        visit::walk_fn(self, fk, decl, body, span);
     }
 
     fn visit_struct_def(&mut self,
@@ -611,9 +591,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
         visit::walk_generics(self, g);
     }
 
-    fn visit_trait_item(&mut self, m: &ast::TraitItem) {
-        run_lints!(self, check_trait_item, m);
-        visit::walk_trait_item(self, m);
+    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+        self.with_lint_attrs(&trait_item.attrs, |cx| {
+            run_lints!(cx, check_trait_item, trait_item);
+            cx.visit_ids(|v| v.visit_trait_item(trait_item));
+            visit::walk_trait_item(cx, trait_item);
+        });
+    }
+
+    fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
+        self.with_lint_attrs(&impl_item.attrs, |cx| {
+            run_lints!(cx, check_impl_item, impl_item);
+            cx.visit_ids(|v| v.visit_impl_item(impl_item));
+            visit::walk_impl_item(cx, impl_item);
+        });
     }
 
     fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>) {
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 506d20133bd..23f9cbc3a4b 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -143,8 +143,8 @@ pub trait LintPass {
     fn check_generics(&mut self, _: &Context, _: &ast::Generics) { }
     fn check_fn(&mut self, _: &Context,
         _: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
-    fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
     fn check_trait_item(&mut self, _: &Context, _: &ast::TraitItem) { }
+    fn check_impl_item(&mut self, _: &Context, _: &ast::ImplItem) { }
     fn check_struct_def(&mut self, _: &Context,
         _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
     fn check_struct_def_post(&mut self, _: &Context,
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 08263eb8e6a..611d8bc27d1 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -808,7 +808,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                     impl_path: PathElems,
                                     is_default_impl: bool,
                                     parent_id: NodeId,
-                                    ast_item_opt: Option<&ast::ImplItem>) {
+                                    impl_item_opt: Option<&ast::ImplItem>) {
 
     debug!("encode_info_for_method: {:?} {:?}", m.def_id,
            token::get_name(m.name));
@@ -826,21 +826,20 @@ 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()));
-    match ast_item_opt {
-        Some(&ast::MethodImplItem(ref ast_method)) => {
-            encode_attributes(rbml_w, &ast_method.attrs);
+    if let Some(impl_item) = impl_item_opt {
+        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();
-            if any_types || is_default_impl || attr::requests_inline(&ast_method.attrs) {
+            if any_types || is_default_impl || attr::requests_inline(&impl_item.attrs) {
                 encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id),
-                                                               ast_item_opt.unwrap()));
+                                                               impl_item));
             }
             if !any_types {
                 encode_symbol(ecx, rbml_w, m.def_id.node);
             }
-            encode_method_argument_names(rbml_w, ast_method.pe_fn_decl());
+            encode_method_argument_names(rbml_w, &sig.decl);
         }
-        Some(_) | None => {}
     }
 
     rbml_w.end_tag();
@@ -851,7 +850,7 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
                                    associated_type: &ty::AssociatedType,
                                    impl_path: PathElems,
                                    parent_id: NodeId,
-                                   typedef_opt: Option<P<ast::Typedef>>) {
+                                   impl_item_opt: Option<&ast::ImplItem>) {
     debug!("encode_info_for_associated_type({:?},{:?})",
            associated_type.def_id,
            token::get_name(associated_type.name));
@@ -873,13 +872,9 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
     let elem = ast_map::PathName(associated_type.name);
     encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));
 
-    match typedef_opt {
-        None => {}
-        Some(typedef) => {
-            encode_attributes(rbml_w, &typedef.attrs);
-            encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx,
-                                                         typedef.id));
-        }
+    if let Some(ii) = impl_item_opt {
+        encode_attributes(rbml_w, &ii.attrs);
+        encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx, ii.id));
     }
 
     rbml_w.end_tag();
@@ -1226,7 +1221,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         let num_implemented_methods = ast_items.len();
         for (i, &trait_item_def_id) in items.iter().enumerate() {
             let ast_item = if i < num_implemented_methods {
-                Some(&ast_items[i])
+                Some(&*ast_items[i])
             } else {
                 None
             };
@@ -1236,11 +1231,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
                 pos: rbml_w.mark_stable_position(),
             });
 
-            let trait_item_type =
-                ty::impl_or_trait_item(tcx, trait_item_def_id.def_id());
-            match (trait_item_type, ast_item) {
-                (ty::MethodTraitItem(ref method_type),
-                 Some(&ast::MethodImplItem(_))) => {
+            match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) {
+                ty::MethodTraitItem(ref method_type) => {
                     encode_info_for_method(ecx,
                                            rbml_w,
                                            &**method_type,
@@ -1249,31 +1241,13 @@ fn encode_info_for_item(ecx: &EncodeContext,
                                            item.id,
                                            ast_item)
                 }
-                (ty::MethodTraitItem(ref method_type), _) => {
-                    encode_info_for_method(ecx,
-                                           rbml_w,
-                                           &**method_type,
-                                           path.clone(),
-                                           false,
-                                           item.id,
-                                           None)
-                }
-                (ty::TypeTraitItem(ref associated_type),
-                 Some(&ast::TypeImplItem(ref typedef))) => {
-                    encode_info_for_associated_type(ecx,
-                                                    rbml_w,
-                                                    &**associated_type,
-                                                    path.clone(),
-                                                    item.id,
-                                                    Some((*typedef).clone()))
-                }
-                (ty::TypeTraitItem(ref associated_type), _) => {
+                ty::TypeTraitItem(ref associated_type) => {
                     encode_info_for_associated_type(ecx,
                                                     rbml_w,
                                                     &**associated_type,
                                                     path.clone(),
                                                     item.id,
-                                                    None)
+                                                    ast_item)
                 }
             }
         }
@@ -1387,35 +1361,29 @@ 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());
-                }
-            };
-            match trait_item {
-                &ast::RequiredMethod(ref m) => {
-                    encode_attributes(rbml_w, &m.attrs);
-                    encode_trait_item(rbml_w);
-                    encode_item_sort(rbml_w, 'r');
-                    encode_method_argument_names(rbml_w, &*m.decl);
-                }
+            let trait_item = &*ms[i];
+            encode_attributes(rbml_w, &trait_item.attrs);
+            match trait_item.node {
+                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_attributes(rbml_w, &m.attrs);
-                    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_fn_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(ref associated_type) => {
-                    encode_attributes(rbml_w,
-                                      &associated_type.attrs);
+                ast::TypeTraitItem(..) => {
                     encode_item_sort(rbml_w, 't');
                 }
             }
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 9d712c7c0fc..fb5b934c2cd 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -32,7 +32,6 @@ use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
 use util::ppaux::ty_to_string;
 
 use syntax::{ast, ast_map, ast_util, codemap, fold};
-use syntax::ast_util::PostExpansionMethod;
 use syntax::codemap::Span;
 use syntax::fold::Folder;
 use syntax::parse::token;
@@ -81,11 +80,8 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     let id = match ii {
         e::IIItemRef(i) => i.id,
         e::IIForeignRef(i) => i.id,
-        e::IITraitItemRef(_, &ast::ProvidedMethod(ref m)) => m.id,
-        e::IITraitItemRef(_, &ast::RequiredMethod(ref m)) => m.id,
-        e::IITraitItemRef(_, &ast::TypeTraitItem(ref ti)) => ti.ty_param.id,
-        e::IIImplItemRef(_, &ast::MethodImplItem(ref m)) => m.id,
-        e::IIImplItemRef(_, &ast::TypeImplItem(ref ti)) => ti.id,
+        e::IITraitItemRef(_, ti) => ti.id,
+        e::IIImplItemRef(_, ii) => ii.id,
     };
     debug!("> Encoding inlined item: {} ({:?})",
            ecx.tcx.map.path_to_string(id),
@@ -157,19 +153,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
         let ident = match *ii {
             ast::IIItem(ref i) => i.ident,
             ast::IIForeign(ref i) => i.ident,
-            ast::IITraitItem(_, ref ti) => {
-                match *ti {
-                    ast::ProvidedMethod(ref m) => m.pe_ident(),
-                    ast::RequiredMethod(ref ty_m) => ty_m.ident,
-                    ast::TypeTraitItem(ref ti) => ti.ty_param.ident,
-                }
-            },
-            ast::IIImplItem(_, ref m) => {
-                match *m {
-                    ast::MethodImplItem(ref m) => m.pe_ident(),
-                    ast::TypeImplItem(ref ti) => ti.ident,
-                }
-            }
+            ast::IITraitItem(_, ref ti) => ti.ident,
+            ast::IIImplItem(_, ref ii) => ii.ident
         };
         debug!("Fn named: {}", token::get_ident(ident));
         debug!("< Decoded inlined fn: {}::{}",
@@ -412,38 +397,16 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
                             .expect_one("expected one item"))
         }
         e::IITraitItemRef(d, ti) => {
-            ast::IITraitItem(d, match *ti {
-                ast::ProvidedMethod(ref m) => {
-                    ast::ProvidedMethod(
-                        fold::noop_fold_method(m.clone(), &mut fld)
-                            .expect_one("noop_fold_method must produce \
-                                         exactly one method"))
-                }
-                ast::RequiredMethod(ref ty_m) => {
-                    ast::RequiredMethod(
-                        fold::noop_fold_type_method(ty_m.clone(), &mut fld))
-                }
-                ast::TypeTraitItem(ref associated_type) => {
-                    ast::TypeTraitItem(
-                        P(fold::noop_fold_associated_type(
-                            (**associated_type).clone(),
-                            &mut fld)))
-                }
-            })
+            ast::IITraitItem(d,
+                fold::noop_fold_trait_item(P(ti.clone()), &mut fld)
+                    .expect_one("noop_fold_trait_item must produce \
+                                 exactly one trait item"))
         }
-        e::IIImplItemRef(d, m) => {
-            ast::IIImplItem(d, match *m {
-                ast::MethodImplItem(ref m) => {
-                    ast::MethodImplItem(
-                        fold::noop_fold_method(m.clone(), &mut fld)
-                            .expect_one("noop_fold_method must produce \
-                                         exactly one method"))
-                }
-                ast::TypeImplItem(ref td) => {
-                    ast::TypeImplItem(
-                        P(fold::noop_fold_typedef((**td).clone(), &mut fld)))
-                }
-            })
+        e::IIImplItemRef(d, ii) => {
+            ast::IIImplItem(d,
+                fold::noop_fold_impl_item(P(ii.clone()), &mut fld)
+                    .expect_one("noop_fold_impl_item must produce \
+                                 exactly one impl item"))
         }
         e::IIForeignRef(i) => {
             ast::IIForeign(fold::noop_fold_foreign_item(P(i.clone()), &mut fld))
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 2d837ce52b5..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};
 
@@ -228,16 +228,11 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                     _ => ()
                 }
             }
-            ast_map::NodeTraitItem(trait_method) => {
-                visit::walk_trait_item(self, trait_method);
+            ast_map::NodeTraitItem(trait_item) => {
+                visit::walk_trait_item(self, trait_item);
             }
             ast_map::NodeImplItem(impl_item) => {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        visit::walk_method_helper(self, method);
-                    }
-                    ast::TypeImplItem(_) => {}
-                }
+                visit::walk_impl_item(self, impl_item);
             }
             ast_map::NodeForeignItem(foreign_item) => {
                 visit::walk_foreign_item(self, &*foreign_item);
@@ -355,13 +350,29 @@ impl<'v> Visitor<'v> for LifeSeeder {
             ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
                 self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
             }
-            ast::ItemImpl(_, _, _, Some(ref _trait_ref), _, ref impl_items) => {
+            ast::ItemTrait(_, _, _, ref trait_items) => {
+                for trait_item in trait_items {
+                    match trait_item.node {
+                        ast::MethodTraitItem(_, Some(_)) => {
+                            if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
+                                self.worklist.push(trait_item.id);
+                            }
+                        }
+                        _ => {}
+                    }
+                }
+            }
+            ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref method) => {
-                            self.worklist.push(method.id);
+                    match impl_item.node {
+                        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")
                     }
                 }
             }
@@ -369,21 +380,6 @@ impl<'v> Visitor<'v> for LifeSeeder {
         }
         visit::walk_item(self, item);
     }
-
-    fn visit_fn(&mut self, fk: visit::FnKind<'v>,
-                _: &'v ast::FnDecl, block: &'v ast::Block,
-                _: codemap::Span, id: ast::NodeId) {
-        // Check for method here because methods are not ast::Item
-        match fk {
-            visit::FkMethod(_, _, method) => {
-                if has_allow_dead_code_or_lang_attr(&method.attrs) {
-                    self.worklist.push(id);
-                }
-            }
-            _ => ()
-        }
-        visit::walk_block(self, block);
-    }
 }
 
 fn create_and_seed_worklist(tcx: &ty::ctxt,
@@ -561,7 +557,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
                 span: codemap::Span, id: ast::NodeId) {
         // Have to warn method here because methods are not ast::Item
         match fk {
-            visit::FkMethod(name, _, _) => {
+            visit::FkMethod(name, _) => {
                 if !self.symbol_is_live(id, None) {
                     self.warn_dead_code(id, span, name, "method");
                 }
@@ -582,12 +578,12 @@ 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 {
-            ast::ProvidedMethod(ref method) => {
-                visit::walk_block(self, &*method.pe_body())
+        match trait_method.node {
+            ast::MethodTraitItem(_, Some(ref body)) => {
+                visit::walk_block(self, body)
             }
-            ast::RequiredMethod(_) => {}
-            ast::TypeTraitItem(_) => {}
+            ast::MethodTraitItem(_, None) |
+            ast::TypeTraitItem(..) => {}
         }
     }
 }
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index 9c85b7748ab..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_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 a7f5c2c8437..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;
@@ -841,33 +841,34 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 ast_map::NodeItem(ref item) => {
                     match item.node {
                         ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => {
-                            Some((&**fn_decl, gen, pur, item.ident, None, item.span))
+                            Some((fn_decl, gen, pur, item.ident, None, item.span))
                         },
                         _ => None
                     }
                 }
-                ast_map::NodeImplItem(ref item) => {
-                    match **item {
-                        ast::MethodImplItem(ref m) => {
-                            Some((m.pe_fn_decl(),
-                                  m.pe_generics(),
-                                  m.pe_unsafety(),
-                                  m.pe_ident(),
-                                  Some(&m.pe_explicit_self().node),
-                                  m.span))
+                ast_map::NodeImplItem(item) => {
+                    match item.node {
+                        ast::MethodImplItem(ref sig, _) => {
+                            Some((&sig.decl,
+                                  &sig.generics,
+                                  sig.unsafety,
+                                  item.ident,
+                                  Some(&sig.explicit_self.node),
+                                  item.span))
                         }
                         ast::TypeImplItem(_) => None,
+                        ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                     }
                 },
-                ast_map::NodeTraitItem(ref item) => {
-                    match **item {
-                        ast::ProvidedMethod(ref m) => {
-                            Some((m.pe_fn_decl(),
-                                  m.pe_generics(),
-                                  m.pe_unsafety(),
-                                  m.pe_ident(),
-                                  Some(&m.pe_explicit_self().node),
-                                  m.span))
+                ast_map::NodeTraitItem(item) => {
+                    match item.node {
+                        ast::MethodTraitItem(ref sig, Some(_)) => {
+                            Some((&sig.decl,
+                                  &sig.generics,
+                                  sig.unsafety,
+                                  item.ident,
+                                  Some(&sig.explicit_self.node),
+                                  item.span))
                         }
                         _ => None
                     }
@@ -1730,12 +1731,13 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
                 _ => None
             },
             ast_map::NodeImplItem(ii) => {
-                match *ii {
-                    ast::MethodImplItem(ref m) => {
-                        taken.push_all(&m.pe_generics().lifetimes);
-                        Some(m.id)
+                match ii.node {
+                    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 45d565ec693..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,10 +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(&method.attrs) ||
-        generics_require_inlining(method.pe_generics()) {
+    if attr::requests_inline(&impl_item.attrs) ||
+        generics_require_inlining(&sig.generics) {
         return true
     }
     if is_local(impl_src) {
@@ -66,13 +67,13 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
                     item_might_be_inlined(&*item)
                 }
                 Some(..) | None => {
-                    tcx.sess.span_bug(method.span, "impl did is not an item")
+                    tcx.sess.span_bug(impl_item.span, "impl did is not an item")
                 }
             }
         }
     } else {
-        tcx.sess.span_bug(method.span, "found a foreign impl as a parent of a \
-                                        local method")
+        tcx.sess.span_bug(impl_item.span, "found a foreign impl as a parent \
+                                           of a local method")
     }
 }
 
@@ -181,17 +182,16 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                 }
             }
             Some(ast_map::NodeTraitItem(trait_method)) => {
-                match *trait_method {
-                    ast::RequiredMethod(_) => false,
-                    ast::ProvidedMethod(_) => true,
-                    ast::TypeTraitItem(_) => false,
+                match trait_method.node {
+                    ast::MethodTraitItem(_, ref body) => body.is_some(),
+                    ast::TypeTraitItem(..) => false,
                 }
             }
             Some(ast_map::NodeImplItem(impl_item)) => {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        if generics_require_inlining(method.pe_generics()) ||
-                                attr::requests_inline(&method.attrs) {
+                match impl_item.node {
+                    ast::MethodImplItem(ref sig, _) => {
+                        if generics_require_inlining(&sig.generics) ||
+                                attr::requests_inline(&impl_item.attrs) {
                             true
                         } else {
                             let impl_did = self.tcx
@@ -213,6 +213,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                         }
                     }
                     ast::TypeImplItem(_) => false,
+                    ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                 }
             }
             Some(_) => false,
@@ -301,25 +302,26 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                 }
             }
             ast_map::NodeTraitItem(trait_method) => {
-                match *trait_method {
-                    ast::RequiredMethod(..) => {
+                match trait_method.node {
+                    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::TypeTraitItem(..) => {}
                 }
             }
             ast_map::NodeImplItem(impl_item) => {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
+                match impl_item.node {
+                    ast::MethodImplItem(ref sig, ref body) => {
                         let did = self.tcx.map.get_parent_did(search_item);
-                        if method_might_be_inlined(self.tcx, &**method, 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 a8a2887644a..e33a2553431 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -142,12 +142,16 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
     fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
                 b: &'v ast::Block, s: Span, _: ast::NodeId) {
         match fk {
-            visit::FkItemFn(_, generics, _, _) |
-            visit::FkMethod(_, generics, _) => {
+            visit::FkItemFn(_, generics, _, _) => {
                 self.visit_early_late(subst::FnSpace, generics, |this| {
                     visit::walk_fn(this, fk, fd, b, s)
                 })
             }
+            visit::FkMethod(_, sig) => {
+                self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
+                    visit::walk_fn(this, fk, fd, b, s)
+                })
+            }
             visit::FkFnBlock(..) => {
                 visit::walk_fn(self, fk, fd, b, s)
             }
@@ -185,10 +189,14 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         }
     }
 
-    fn visit_ty_method(&mut self, m: &ast::TypeMethod) {
-        self.visit_early_late(
-            subst::FnSpace, &m.generics,
-            |this| visit::walk_ty_method(this, m))
+    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+        if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
+            self.visit_early_late(
+                subst::FnSpace, &sig.generics,
+                |this| visit::walk_trait_item(this, trait_item))
+        } else {
+            visit::walk_trait_item(self, trait_item);
+        }
     }
 
     fn visit_block(&mut self, b: &ast::Block) {
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 3599ba5a0f7..01766b0de08 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -22,11 +22,10 @@ use syntax::codemap::{Span, DUMMY_SP};
 use syntax::{attr, visit};
 use syntax::ast;
 use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
-use syntax::ast::{Item, RequiredMethod, ProvidedMethod, TraitItem};
-use syntax::ast::{TypeMethod, Method, Generics, StructField, TypeTraitItem};
+use syntax::ast::{Item, Generics, StructField};
 use syntax::ast_util::is_local;
 use syntax::attr::{Stability, AttrMetaMethods};
-use syntax::visit::{FnKind, FkMethod, Visitor};
+use syntax::visit::{FnKind, Visitor};
 use syntax::feature_gate::emit_feature_warn;
 use util::nodemap::{NodeMap, DefIdMap, FnvHashSet, FnvHashMap};
 use util::ppaux::Repr;
@@ -124,31 +123,20 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
         }
     }
 
-    fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
-                _: &'v Block, sp: Span, _: NodeId) {
-        if let FkMethod(_, _, meth) = fk {
-            // Methods are not already annotated, so we annotate it
-            self.annotate(meth.id, true, &meth.attrs, sp, |_| {}, true);
-        }
+    fn visit_fn(&mut self, _: FnKind<'v>, _: &'v FnDecl,
+                _: &'v Block, _: Span, _: NodeId) {
         // Items defined in a function body have no reason to have
         // a stability attribute, so we don't recurse.
     }
 
-    fn visit_trait_item(&mut self, t: &TraitItem) {
-        let (id, attrs, sp) = match *t {
-            RequiredMethod(TypeMethod {id, ref attrs, span, ..}) => (id, attrs, span),
-
-            // work around lack of pattern matching for @ types
-            ProvidedMethod(ref method) => {
-                match **method {
-                    Method {ref attrs, id, span, ..} => (id, attrs, span),
-                }
-            }
+    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+        self.annotate(ti.id, true, &ti.attrs, ti.span,
+                      |v| visit::walk_trait_item(v, ti), true);
+    }
 
-            TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs,
-                                           typedef.ty_param.span),
-        };
-        self.annotate(id, true, attrs, sp, |v| visit::walk_trait_item(v, t), true);
+    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+        self.annotate(ii.id, true, &ii.attrs, ii.span,
+                      |v| visit::walk_impl_item(v, ii), true);
     }
 
     fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
@@ -335,22 +323,11 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
             let trait_items = ty::trait_items(tcx, trait_did);
 
             for impl_item in impl_items {
-                let (ident, span) = match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        (match method.node {
-                            ast::MethDecl(ident, _, _, _, _, _, _, _) => ident,
-                            ast::MethMac(..) => unreachable!(),
-                        }, method.span)
-                    }
-                    ast::TypeImplItem(ref typedef) => {
-                        (typedef.ident, typedef.span)
-                    }
-                };
                 let item = trait_items.iter().find(|item| {
-                    item.name() == ident.name
+                    item.name() == impl_item.ident.name
                 }).unwrap();
                 if warn_about_defns {
-                    maybe_do_stability_check(tcx, item.def_id(), span, cb);
+                    maybe_do_stability_check(tcx, item.def_id(), impl_item.span, cb);
                 }
             }
         }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index a871602b865..8705e56b094 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};
@@ -2286,8 +2286,8 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
     pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
         match cx.map.find(id) {
             Some(ast_map::NodeImplItem(ref impl_item)) => {
-                match **impl_item {
-                    ast::MethodImplItem(ref method) => {
+                match impl_item.node {
+                    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) => {
@@ -2295,10 +2295,10 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                 let method_bounds = &method_ty.predicates;
                                 construct_parameter_environment(
                                     cx,
-                                    method.span,
+                                    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_method)) => {
-                match *trait_method {
-                    ast::RequiredMethod(ref required) => {
-                        cx.sess.span_bug(required.span,
+            Some(ast_map::NodeTraitItem(trait_item)) => {
+                match trait_item.node {
+                    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) => {
@@ -2332,10 +2333,10 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                 let method_bounds = &method_ty.predicates;
                                 construct_parameter_environment(
                                     cx,
-                                    method.span,
+                                    trait_item.span,
                                     method_generics,
                                     method_bounds,
-                                    method.pe_body().id)
+                                    body.id)
                             }
                             TypeTraitItem(_) => {
                                 cx.sess
@@ -2345,7 +2346,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                             }
                         }
                     }
-                    ast::TypeTraitItem(_) => {
+                    ast::TypeTraitItem(..) => {
                         cx.sess.bug("ParameterEnvironment::from_item(): \
                                      can't create a parameter environment \
                                      for type trait items")
@@ -5080,39 +5081,23 @@ pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
 pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
                                     -> Vec<Rc<Method<'tcx>>> {
     if is_local(id) {
-        match cx.map.find(id.node) {
-            Some(ast_map::NodeItem(item)) => {
-                match item.node {
-                    ItemTrait(_, _, _, ref ms) => {
-                        let (_, p) =
-                            ast_util::split_trait_methods(&ms[..]);
-                        p.iter()
-                         .map(|m| {
-                            match impl_or_trait_item(
-                                    cx,
-                                    ast_util::local_def(m.id)) {
-                                MethodTraitItem(m) => m,
-                                TypeTraitItem(_) => {
-                                    cx.sess.bug("provided_trait_methods(): \
-                                                 split_trait_methods() put \
-                                                 associated types in the \
-                                                 provided method bucket?!")
-                                }
-                            }
-                         }).collect()
-                    }
-                    _ => {
-                        cx.sess.bug(&format!("provided_trait_methods: `{:?}` is \
-                                             not a trait",
-                                            id))
+        if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node {
+            ms.iter().filter_map(|ti| {
+                if let ast::MethodTraitItem(_, Some(_)) = ti.node {
+                    match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
+                        MethodTraitItem(m) => Some(m),
+                        TypeTraitItem(_) => {
+                            cx.sess.bug("provided_trait_methods(): \
+                                         associated type found from \
+                                         looking up ProvidedMethod?!")
+                        }
                     }
+                } else {
+                    None
                 }
-            }
-            _ => {
-                cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a \
-                                     trait",
-                                    id))
-            }
+            }).collect()
+        } else {
+            cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
         }
     } else {
         csearch::get_provided_trait_methods(cx, id)
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index f41d969c1a2..3a0b5832c9f 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -828,14 +828,11 @@ impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
 
 impl<'tcx> Repr<'tcx> for ast::TraitItem {
     fn repr(&self, _tcx: &ctxt) -> String {
-        match *self {
-            ast::RequiredMethod(ref data) => format!("RequiredMethod({}, id={})",
-                                                     data.ident, data.id),
-            ast::ProvidedMethod(ref data) => format!("ProvidedMethod(id={})",
-                                                     data.id),
-            ast::TypeTraitItem(ref data) => format!("TypeTraitItem({}, id={})",
-                                                     data.ty_param.ident, data.ty_param.id),
-        }
+        let kind = match self.node {
+            ast::MethodTraitItem(..) => "MethodTraitItem",
+            ast::TypeTraitItem(..) => "TypeTraitItem",
+        };
+        format!("{}({}, id={})", kind, self.ident, self.id)
     }
 }
 
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index e16df61c25c..467b7c1ca38 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -188,8 +188,8 @@ mod svh_visitor {
         SawTy,
         SawGenerics,
         SawFn,
-        SawTyMethod,
-        SawTraitMethod,
+        SawTraitItem,
+        SawImplItem,
         SawStructField,
         SawVariant,
         SawExplicitSelf,
@@ -463,12 +463,12 @@ mod svh_visitor {
             SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s)
         }
 
-        fn visit_ty_method(&mut self, t: &TypeMethod) {
-            SawTyMethod.hash(self.st); visit::walk_ty_method(self, t)
+        fn visit_trait_item(&mut self, ti: &TraitItem) {
+            SawTraitItem.hash(self.st); visit::walk_trait_item(self, ti)
         }
 
-        fn visit_trait_item(&mut self, t: &TraitItem) {
-            SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t)
+        fn visit_impl_item(&mut self, ii: &ImplItem) {
+            SawImplItem.hash(self.st); visit::walk_impl_item(self, ii)
         }
 
         fn visit_struct_field(&mut self, s: &StructField) {
diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs
index 8cb4090bf39..f3abcb4376c 100644
--- a/src/librustc_borrowck/borrowck/fragments.rs
+++ b/src/librustc_borrowck/borrowck/fragments.rs
@@ -26,7 +26,6 @@ use rustc::util::ppaux::{Repr, UserString};
 use std::mem;
 use std::rc::Rc;
 use syntax::ast;
-use syntax::ast_map;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::Span;
 
@@ -119,24 +118,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
                                        tcx: &ty::ctxt<'tcx>,
                                        sp: Span,
                                        id: ast::NodeId) {
-    let (span_err, print) = {
-        let attrs : &[ast::Attribute];
-        attrs = match tcx.map.find(id) {
-            Some(ast_map::NodeItem(ref item)) =>
-                &item.attrs,
-            Some(ast_map::NodeImplItem(&ast::MethodImplItem(ref m))) =>
-                &m.attrs,
-            Some(ast_map::NodeTraitItem(&ast::ProvidedMethod(ref m))) =>
-                &m.attrs,
-            _ => &[],
-        };
-
-        let span_err =
-            attrs.iter().any(|a| a.check_name("rustc_move_fragments"));
-        let print = tcx.sess.opts.debugging_opts.print_move_fragments;
-
-        (span_err, print)
-    };
+    let span_err = tcx.map.attrs(id).iter()
+                          .any(|a| a.check_name("rustc_move_fragments"));
+    let print = tcx.sess.opts.debugging_opts.print_move_fragments;
 
     if !span_err && !print { return; }
 
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 99febcfe346..074591fb927 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -46,13 +46,12 @@ 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::is_shift_binop;
+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};
 use syntax::parse::token;
 use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
-use syntax::ast_util;
 use syntax::ptr::P;
 use syntax::visit::{self, Visitor};
 
@@ -879,36 +878,18 @@ enum MethodContext {
     PlainImpl
 }
 
-fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
-    let did = ast::DefId {
-        krate: ast::LOCAL_CRATE,
-        node: m.id
-    };
-
-    match cx.tcx.impl_or_trait_items.borrow().get(&did).cloned() {
-        None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
-        Some(ty::MethodTraitItem(md)) => {
-            match md.container {
-                ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
-                ty::ImplContainer(cid) => {
-                    match ty::impl_trait_ref(cx.tcx, cid) {
-                        Some(..) => MethodContext::TraitImpl,
-                        None => MethodContext::PlainImpl
-                    }
+fn method_context(cx: &Context, id: ast::NodeId, span: Span) -> MethodContext {
+    match cx.tcx.impl_or_trait_items.borrow().get(&local_def(id)) {
+        None => cx.sess().span_bug(span, "missing method descriptor?!"),
+        Some(item) => match item.container() {
+            ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
+            ty::ImplContainer(cid) => {
+                match ty::impl_trait_ref(cx.tcx, cid) {
+                    Some(_) => MethodContext::TraitImpl,
+                    None => MethodContext::PlainImpl
                 }
             }
-        },
-        Some(ty::TypeTraitItem(typedef)) => {
-            match typedef.container {
-                ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
-                ty::ImplContainer(cid) => {
-                    match ty::impl_trait_ref(cx.tcx, cid) {
-                        Some(..) => MethodContext::TraitImpl,
-                        None => MethodContext::PlainImpl
-                    }
-                }
-            }
-        },
+        }
     }
 }
 
@@ -999,9 +980,9 @@ impl LintPass for NonSnakeCase {
 
     fn check_fn(&mut self, cx: &Context,
                 fk: visit::FnKind, _: &ast::FnDecl,
-                _: &ast::Block, span: Span, _: ast::NodeId) {
+                _: &ast::Block, span: Span, id: ast::NodeId) {
         match fk {
-            visit::FkMethod(ident, _, m) => match method_context(cx, m) {
+            visit::FkMethod(ident, _) => match method_context(cx, id, span) {
                 MethodContext::PlainImpl => {
                     self.check_snake_case(cx, "method", ident, span)
                 },
@@ -1023,8 +1004,10 @@ impl LintPass for NonSnakeCase {
         }
     }
 
-    fn check_ty_method(&mut self, cx: &Context, t: &ast::TypeMethod) {
-        self.check_snake_case(cx, "trait method", t.ident, t.span);
+    fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
+        if let ast::MethodTraitItem(_, None) = trait_item.node {
+            self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span);
+        }
     }
 
     fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
@@ -1335,9 +1318,9 @@ impl LintPass for UnsafeCode {
             visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) =>
                 cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
 
-            visit::FkMethod(_, _, m) => {
-                if let ast::Method_::MethDecl(_, _, _, _, ast::Unsafety::Unsafe, _, _, _) = m.node {
-                    cx.span_lint(UNSAFE_CODE, m.span, "implementation of an `unsafe` method")
+            visit::FkMethod(_, sig) => {
+                if sig.unsafety == ast::Unsafety::Unsafe {
+                    cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
                 }
             },
 
@@ -1345,9 +1328,12 @@ impl LintPass for UnsafeCode {
         }
     }
 
-    fn check_ty_method(&mut self, cx: &Context, ty_method: &ast::TypeMethod) {
-        if let ast::TypeMethod { unsafety: ast::Unsafety::Unsafe, span, ..} = *ty_method {
-            cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method")
+    fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
+        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")
+            }
         }
     }
 }
@@ -1576,30 +1562,30 @@ impl LintPass for MissingDoc {
         self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
     }
 
-    fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
-                _: &ast::Block, _: Span, _: ast::NodeId) {
-        if let visit::FkMethod(_, _, m) = fk {
-            // If the method is an impl for a trait, don't doc.
-            if method_context(cx, m) == MethodContext::TraitImpl {
-                return;
-            }
-
-            // Otherwise, doc according to privacy. This will also check
-            // doc for default methods defined on traits.
-            self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs, m.span, "a method");
-        }
-    }
-
-    fn check_ty_method(&mut self, cx: &Context, tm: &ast::TypeMethod) {
-        self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs, tm.span, "a type method");
+    fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
+        let desc = match trait_item.node {
+            ast::MethodTraitItem(..) => "a trait method",
+            ast::TypeTraitItem(..) => "an associated type"
+        };
+        self.check_missing_docs_attrs(cx, Some(trait_item.id),
+                                      &trait_item.attrs,
+                                      trait_item.span, desc);
     }
 
-    fn check_trait_item(&mut self, cx: &Context, it: &ast::TraitItem) {
-        if let ast::TraitItem::TypeTraitItem(ref ty) = *it {
-            let assoc_ty = &ty.ty_param;
-            self.check_missing_docs_attrs(cx, Some(assoc_ty.id), &ty.attrs,
-                                          assoc_ty.span, "an associated type");
+    fn check_impl_item(&mut self, cx: &Context, impl_item: &ast::ImplItem) {
+        // If the method is an impl for a trait, don't doc.
+        if method_context(cx, impl_item.id, impl_item.span) == MethodContext::TraitImpl {
+            return;
         }
+
+        let desc = match impl_item.node {
+            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,
+                                      impl_item.span, desc);
     }
 
     fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) {
@@ -1644,10 +1630,7 @@ impl LintPass for MissingCopyImplementations {
         if !cx.exported_items.contains(&item.id) {
             return;
         }
-        if cx.tcx
-             .destructor_for_type
-             .borrow()
-             .contains_key(&ast_util::local_def(item.id)) {
+        if cx.tcx.destructor_for_type.borrow().contains_key(&local_def(item.id)) {
             return;
         }
         let ty = match item.node {
@@ -1655,16 +1638,14 @@ impl LintPass for MissingCopyImplementations {
                 if ast_generics.is_parameterized() {
                     return;
                 }
-                ty::mk_struct(cx.tcx,
-                              ast_util::local_def(item.id),
+                ty::mk_struct(cx.tcx, local_def(item.id),
                               cx.tcx.mk_substs(Substs::empty()))
             }
             ast::ItemEnum(_, ref ast_generics) => {
                 if ast_generics.is_parameterized() {
                     return;
                 }
-                ty::mk_enum(cx.tcx,
-                            ast_util::local_def(item.id),
+                ty::mk_enum(cx.tcx, local_def(item.id),
                             cx.tcx.mk_substs(Substs::empty()))
             }
             _ => return,
@@ -1828,13 +1809,13 @@ impl LintPass for UnconditionalRecursion {
 
         let (name, checker) = match fn_kind {
             visit::FkItemFn(name, _, _, _) => (name, id_refers_to_this_fn as F),
-            visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F),
+            visit::FkMethod(name, _) => (name, id_refers_to_this_method as F),
             // closures can't recur, so they don't matter.
             visit::FkFnBlock => return
         };
 
-        let impl_def_id = ty::impl_of_method(cx.tcx, ast_util::local_def(id))
-            .unwrap_or(ast_util::local_def(ast::DUMMY_NODE_ID));
+        let impl_def_id = ty::impl_of_method(cx.tcx, local_def(id))
+            .unwrap_or(local_def(ast::DUMMY_NODE_ID));
         assert!(ast_util::is_local(impl_def_id));
         let impl_node_id = impl_def_id.node;
 
@@ -1938,7 +1919,7 @@ impl LintPass for UnconditionalRecursion {
                                       _: ast::Ident,
                                       id: ast::NodeId) -> bool {
             tcx.def_map.borrow().get(&id)
-               .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
+               .map_or(false, |def| def.def_id() == local_def(fn_id))
         }
 
         // check if the method call `id` refers to method `method_id`
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index c766b20389e..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};
@@ -92,17 +92,9 @@ impl<'v> Visitor<'v> for ParentVisitor {
             // method to the root. In this case, if the trait is private, then
             // parent all the methods to the trait to indicate that they're
             // private.
-            ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
-                for m in methods {
-                    match *m {
-                        ast::ProvidedMethod(ref m) => {
-                            self.parents.insert(m.id, item.id);
-                        }
-                        ast::RequiredMethod(ref m) => {
-                            self.parents.insert(m.id, item.id);
-                        }
-                        ast::TypeTraitItem(_) => {}
-                    };
+            ast::ItemTrait(_, _, _, ref trait_items) if item.vis != ast::Public => {
+                for trait_item in trait_items {
+                    self.parents.insert(trait_item.id, item.id);
                 }
             }
 
@@ -280,18 +272,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
 
                 if public_ty || public_trait {
                     for impl_item in impl_items {
-                        match *impl_item {
-                            ast::MethodImplItem(ref method) => {
-                                let meth_public =
-                                    match method.pe_explicit_self().node {
-                                        ast::SelfStatic => public_ty,
-                                        _ => true,
-                                    } && method.pe_vis() == ast::Public;
+                        match impl_item.node {
+                            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(method.id);
+                                    self.exported_items.insert(impl_item.id);
                                 }
                             }
-                            ast::TypeImplItem(_) => {}
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => {}
                         }
                     }
                 }
@@ -299,22 +291,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
 
             // Default methods on traits are all public so long as the trait
             // is public
-            ast::ItemTrait(_, _, _, ref methods) if public_first => {
-                for method in methods {
-                    match *method {
-                        ast::ProvidedMethod(ref m) => {
-                            debug!("provided {}", m.id);
-                            self.exported_items.insert(m.id);
-                        }
-                        ast::RequiredMethod(ref m) => {
-                            debug!("required {}", m.id);
-                            self.exported_items.insert(m.id);
-                        }
-                        ast::TypeTraitItem(ref t) => {
-                            debug!("typedef {}", t.ty_param.id);
-                            self.exported_items.insert(t.ty_param.id);
-                        }
-                    }
+            ast::ItemTrait(_, _, _, ref trait_items) if public_first => {
+                for trait_item in trait_items {
+                    debug!("trait item {}", trait_item.id);
+                    self.exported_items.insert(trait_item.id);
                 }
             }
 
@@ -510,19 +490,20 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                 // FIXME(#10573) is this the right behavior? Why not consider
                 //               where the method was defined?
                 Some(ast_map::NodeImplItem(ii)) => {
-                    match *ii {
-                        ast::MethodImplItem(ref m) => {
+                    match ii.node {
+                        ast::MethodImplItem(..) => {
                             let imp = self.tcx.map
                                           .get_parent_did(closest_private_id);
                             match ty::impl_trait_ref(self.tcx, imp) {
                                 Some(..) => return Allowable,
-                                _ if m.pe_vis() == ast::Public => {
+                                _ if ii.vis == ast::Public => {
                                     return Allowable
                                 }
-                                _ => m.pe_vis()
+                                _ => ii.vis
                             }
                         }
-                        ast::TypeImplItem(_) => return Allowable,
+                        ast::TypeImplItem(_) |
+                        ast::MacImplItem(_) => return Allowable,
                     }
                 }
                 Some(ast_map::NodeTraitItem(_)) => {
@@ -1088,12 +1069,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
                                 "visibility qualifiers have no effect on trait \
                                  impls");
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref m) => {
-                            check_inherited(m.span, m.pe_vis(), "");
-                        }
-                        ast::TypeImplItem(_) => {}
-                    }
+                    check_inherited(impl_item.span, impl_item.vis, "");
                 }
             }
 
@@ -1121,23 +1097,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
                 }
             }
 
-            ast::ItemTrait(_, _, _, ref methods) => {
-                for m in methods {
-                    match *m {
-                        ast::ProvidedMethod(ref m) => {
-                            check_inherited(m.span, m.pe_vis(),
-                                            "unnecessary visibility");
-                        }
-                        ast::RequiredMethod(ref m) => {
-                            check_inherited(m.span, m.vis,
-                                            "unnecessary visibility");
-                        }
-                        ast::TypeTraitItem(_) => {}
-                    }
-                }
-            }
-
-            ast::ItemDefaultImpl(..) |
+            ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
             ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
             ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
             ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {}
@@ -1165,11 +1125,12 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
         match item.node {
             ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref m) => {
-                            check_inherited(tcx, m.span, m.pe_vis());
+                    match impl_item.node {
+                        ast::MethodImplItem(..) => {
+                            check_inherited(tcx, impl_item.span, impl_item.vis);
                         }
-                        ast::TypeImplItem(_) => {}
+                        ast::TypeImplItem(_) |
+                        ast::MacImplItem(_) => {}
                     }
                 }
             }
@@ -1186,18 +1147,8 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
 
             ast::ItemStruct(ref def, _) => check_struct(&**def),
 
-            ast::ItemTrait(_, _, _, ref methods) => {
-                for m in methods {
-                    match *m {
-                        ast::RequiredMethod(..) => {}
-                        ast::ProvidedMethod(ref m) => check_inherited(tcx, m.span,
-                                                                m.pe_vis()),
-                        ast::TypeTraitItem(_) => {}
-                    }
-                }
-            }
-
-            ast::ItemDefaultImpl(..) | ast::ItemExternCrate(_) | ast::ItemUse(_) |
+            ast::ItemExternCrate(_) | ast::ItemUse(_) |
+            ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
             ast::ItemStatic(..) | ast::ItemConst(..) |
             ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
             ast::ItemMac(..) => {}
@@ -1352,11 +1303,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     trait_ref.is_some() ||
                     impl_items.iter()
                               .any(|impl_item| {
-                                  match *impl_item {
-                                      ast::MethodImplItem(ref m) => {
-                                          self.exported_items.contains(&m.id)
+                                  match impl_item.node {
+                                      ast::MethodImplItem(..) => {
+                                          self.exported_items.contains(&impl_item.id)
                                       }
-                                      ast::TypeImplItem(_) => false,
+                                      ast::TypeImplItem(_) |
+                                      ast::MacImplItem(_) => false,
                                   }
                               });
 
@@ -1369,12 +1321,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     match *trait_ref {
                         None => {
                             for impl_item in impl_items {
-                                match *impl_item {
-                                    ast::MethodImplItem(ref method) => {
-                                        visit::walk_method_helper(self, &**method)
-                                    }
-                                    ast::TypeImplItem(_) => {}
-                                }
+                                visit::walk_impl_item(self, impl_item);
                             }
                         }
                         Some(ref tr) => {
@@ -1395,11 +1342,12 @@ 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 {
-                                    ast::MethodImplItem(..) => {},
-                                    ast::TypeImplItem(ref typedef) => {
-                                        self.visit_ty(&typedef.typ);
+                                match impl_item.node {
+                                    ast::TypeImplItem(ref ty) => {
+                                        self.visit_ty(ty);
                                     }
+                                    ast::MethodImplItem(..) |
+                                    ast::MacImplItem(_) => {},
                                 }
                             }
                         }
@@ -1409,17 +1357,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
                     for impl_item in impl_items {
-                        match *impl_item {
-                            ast::MethodImplItem(ref method) => {
-                                if method.pe_explicit_self().node ==
-                                        ast::SelfStatic &&
-                                        self.exported_items
-                                            .contains(&method.id) {
+                        match impl_item.node {
+                            ast::MethodImplItem(ref sig, _) => {
+                                if sig.explicit_self.node == ast::SelfStatic &&
+                                   self.exported_items.contains(&impl_item.id) {
                                     found_pub_static = true;
-                                    visit::walk_method_helper(self, &**method);
+                                    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 67e2b409c8e..1cbbcad9550 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -48,7 +48,7 @@ use syntax::ast::UnnamedField;
 use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
 use syntax::ast::{Visibility};
 use syntax::ast;
-use syntax::ast_util::{self, local_def};
+use syntax::ast_util::local_def;
 use syntax::attr::AttrMetaMethods;
 use syntax::parse::token::{self, special_idents};
 use syntax::codemap::{Span, DUMMY_SP};
@@ -525,49 +525,28 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
                 // Add the names of all the items to the trait info.
                 for trait_item in items {
-                    let (name, trait_item_id) = match *trait_item {
-                        ast::RequiredMethod(_) |
-                        ast::ProvidedMethod(_) => {
-                            let ty_m = ast_util::trait_item_to_ty_method(trait_item);
-
-                            let name = ty_m.ident.name;
-
-                            // Add it as a name in the trait module.
-                            let def = DefMethod(local_def(ty_m.id),
+                    let name_bindings = self.add_child(trait_item.ident.name,
+                                        &module_parent,
+                                        ForbidDuplicateTypesAndValues,
+                                        trait_item.span);
+
+                    match trait_item.node {
+                        ast::MethodTraitItem(..) => {
+                            let def = DefMethod(local_def(trait_item.id),
                                                 FromTrait(local_def(item.id)));
-
-                            let method_name_bindings =
-                                self.add_child(name,
-                                               &module_parent,
-                                               ForbidDuplicateTypesAndValues,
-                                               ty_m.span);
                             // NB: not IMPORTABLE
-                            method_name_bindings.define_value(def,
-                                                              ty_m.span,
-                                                              PUBLIC);
-
-                            (name, local_def(ty_m.id))
+                            name_bindings.define_value(def, trait_item.span, PUBLIC);
                         }
-                        ast::TypeTraitItem(ref associated_type) => {
+                        ast::TypeTraitItem(..) => {
                             let def = DefAssociatedTy(local_def(item.id),
-                                                      local_def(associated_type.ty_param.id));
-
-                            let name_bindings =
-                                self.add_child(associated_type.ty_param.ident.name,
-                                               &module_parent,
-                                               ForbidDuplicateTypesAndValues,
-                                               associated_type.ty_param.span);
+                                                      local_def(trait_item.id));
                             // NB: not IMPORTABLE
-                            name_bindings.define_type(def,
-                                                      associated_type.ty_param.span,
-                                                      PUBLIC);
-
-                            (associated_type.ty_param.ident.name,
-                             local_def(associated_type.ty_param.id))
+                            name_bindings.define_type(def, trait_item.span, PUBLIC);
                         }
-                    };
+                    }
 
-                    self.trait_item_map.insert((name, def_id), trait_item_id);
+                    self.trait_item_map.insert((trait_item.ident.name, def_id),
+                                               local_def(trait_item.id));
                 }
 
                 name_bindings.define_type(DefTrait(def_id), sp, modifiers);
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ccca99f8b4e..e49fdc9c5d3 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -82,10 +82,11 @@ 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};
+use syntax::ptr::P;
 use syntax::codemap::{self, Span, Pos};
 use syntax::visit::{self, Visitor};
 
@@ -241,9 +242,9 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
                 self.visit_generics(generics);
                 ItemRibKind
             }
-            visit::FkMethod(_, generics, method) => {
-                self.visit_generics(generics);
-                self.visit_explicit_self(method.pe_explicit_self());
+            visit::FkMethod(_, sig) => {
+                self.visit_generics(&sig.generics);
+                self.visit_explicit_self(&sig.explicit_self);
                 MethodRibKind
             }
             visit::FkFnBlock(..) => ClosureRibKind(node_id)
@@ -2806,27 +2807,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     this.visit_generics(generics);
                     visit::walk_ty_param_bounds_helper(this, bounds);
 
-                    for trait_item in &(*trait_items) {
+                    for trait_item in trait_items {
                         // Create a new rib for the trait_item-specific type
                         // parameters.
                         //
                         // FIXME #4951: Do we need a node ID here?
 
-                        let type_parameters = match *trait_item {
-                            ast::RequiredMethod(ref ty_m) => {
-                                HasTypeParameters(&ty_m.generics,
-                                                  FnSpace,
-                                                  MethodRibKind)
-                            }
-                            ast::ProvidedMethod(ref m) => {
-                                HasTypeParameters(m.pe_generics(),
+                        let type_parameters = match trait_item.node {
+                            ast::MethodTraitItem(ref sig, _) => {
+                                HasTypeParameters(&sig.generics,
                                                   FnSpace,
                                                   MethodRibKind)
                             }
-                            ast::TypeTraitItem(ref assoc_ty) => {
-                                let ty_param = &assoc_ty.ty_param;
-                                this.check_if_primitive_type_name(ty_param.ident.name,
-                                                                  ty_param.span);
+                            ast::TypeTraitItem(..) => {
+                                this.check_if_primitive_type_name(trait_item.ident.name,
+                                                                  trait_item.span);
                                 NoTypeParameters
                             }
                         };
@@ -3049,7 +3044,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                               generics: &Generics,
                               opt_trait_reference: &Option<TraitRef>,
                               self_type: &Ty,
-                              impl_items: &[ImplItem]) {
+                              impl_items: &[P<ImplItem>]) {
         // If applicable, create a rib for the type parameters.
         self.with_type_parameter_rib(HasTypeParameters(generics,
                                                        TypeSpace,
@@ -3065,31 +3060,32 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                 this.with_current_self_type(self_type, |this| {
                     for impl_item in impl_items {
-                        match *impl_item {
-                            MethodImplItem(ref method) => {
+                        match impl_item.node {
+                            MethodImplItem(ref sig, _) => {
                                 // If this is a trait impl, ensure the method
                                 // exists in trait
-                                this.check_trait_item(method.pe_ident().name,
-                                                      method.span);
+                                this.check_trait_item(impl_item.ident.name,
+                                                      impl_item.span);
 
                                 // We also need a new scope for the method-
                                 // specific type parameters.
                                 let type_parameters =
-                                    HasTypeParameters(method.pe_generics(),
+                                    HasTypeParameters(&sig.generics,
                                                       FnSpace,
                                                       MethodRibKind);
                                 this.with_type_parameter_rib(type_parameters, |this| {
-                                    visit::walk_method_helper(this, &**method);
+                                    visit::walk_impl_item(this, impl_item);
                                 });
                             }
-                            TypeImplItem(ref typedef) => {
+                            TypeImplItem(ref ty) => {
                                 // If this is a trait impl, ensure the method
                                 // exists in trait
-                                this.check_trait_item(typedef.ident.name,
-                                                      typedef.span);
+                                this.check_trait_item(impl_item.ident.name,
+                                                      impl_item.span);
 
-                                this.visit_ty(&*typedef.typ);
+                                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) {
-                    ast_map::NodeTraitItem(m) => match *m {
-                        ast::RequiredMethod(ref m) => &m.explicit_self,
-                        ast::ProvidedMethod(ref m) => m.pe_explicit_self(),
+                let sig = match this.ast_map.get(did.node) {
+                    ast_map::NodeTraitItem(trait_item) => match trait_item.node {
+                        ast::MethodTraitItem(ref sig, _) => sig,
                         _ => return false
                     },
-                    ast_map::NodeImplItem(m) => match *m {
-                        ast::MethodImplItem(ref m) => m.pe_explicit_self(),
+                    ast_map::NodeImplItem(impl_item) => match impl_item.node {
+                        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 3c6cb5f9de9..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,8 +284,11 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_method(&mut self, method: &ast::Method) {
-        if generated_code(method.span) {
+    fn process_method(&mut self, sig: &ast::MethodSig,
+                      body: Option<&ast::Block>,
+                      id: ast::NodeId, ident: ast::Ident,
+                      span: Span) {
+        if generated_code(span) {
             return;
         }
 
@@ -293,7 +296,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
         let qualname = match ty::impl_of_method(&self.analysis.ty_cx,
-                                                ast_util::local_def(method.id)) {
+                                                ast_util::local_def(id)) {
             Some(impl_id) => match self.analysis.ty_cx.map.get(impl_id.node) {
                 NodeItem(item) => {
                     scope_id = item.id;
@@ -303,7 +306,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             result.push_str(&ty_to_string(&**ty));
 
                             match ty::trait_of_item(&self.analysis.ty_cx,
-                                                    ast_util::local_def(method.id)) {
+                                                    ast_util::local_def(id)) {
                                 Some(def_id) => {
                                     result.push_str(" as ");
                                     result.push_str(
@@ -315,23 +318,20 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             result
                         }
                         _ => {
-                            self.sess.span_bug(method.span,
-                                               &format!("Container {} for method {} not an impl?",
-                                                       impl_id.node, method.id));
+                            self.sess.span_bug(span,
+                                &format!("Container {} for method {} not an impl?",
+                                         impl_id.node, id));
                         },
                     }
                 },
                 _ => {
-                    self.sess.span_bug(method.span,
-                                       &format!(
-                                           "Container {} for method {} is not a node item {:?}",
-                                           impl_id.node,
-                                           method.id,
-                                           self.analysis.ty_cx.map.get(impl_id.node)));
+                    self.sess.span_bug(span,
+                        &format!("Container {} for method {} is not a node item {:?}",
+                                 impl_id.node, id, self.analysis.ty_cx.map.get(impl_id.node)));
                 },
             },
             None => match ty::trait_of_item(&self.analysis.ty_cx,
-                                            ast_util::local_def(method.id)) {
+                                            ast_util::local_def(id)) {
                 Some(def_id) => {
                     scope_id = def_id.node;
                     match self.analysis.ty_cx.map.get(def_id.node) {
@@ -339,69 +339,72 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             format!("::{}", ty::item_path_str(&self.analysis.ty_cx, def_id))
                         }
                         _ => {
-                            self.sess.span_bug(method.span,
-                                               &format!("Could not find container {} for method {}",
-                                                       def_id.node, method.id));
+                            self.sess.span_bug(span,
+                                &format!("Could not find container {} for method {}",
+                                         def_id.node, id));
                         }
                     }
                 },
                 None => {
-                    self.sess.span_bug(method.span,
-                                       &format!("Could not find container for method {}",
-                                               method.id));
+                    self.sess.span_bug(span,
+                        &format!("Could not find container for method {}", id));
                 },
             },
         };
 
-        let qualname = format!("{}::{}", qualname, &get_ident(method.pe_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,
-                                             ast_util::local_def(method.id))
+                                             ast_util::local_def(id))
             .and_then(|def_id| {
                 if match def_id {
                     ty::MethodTraitItemId(def_id) => {
-                        def_id.node != 0 && def_id != ast_util::local_def(method.id)
+                        def_id.node != 0 && def_id != ast_util::local_def(id)
                     }
                     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(method.span, keywords::Fn);
-        self.fmt.method_str(method.span,
-                            sub_span,
-                            method.id,
-                            qualname,
-                            decl_id,
-                            scope_id);
-
-        self.process_formals(&method.pe_fn_decl().inputs, qualname);
+        let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn);
+        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_fn_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_fn_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(method.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_generics(),
-                                    method.span,
+        self.process_generic_params(&sig.generics,
+                                    span,
                                     qualname,
-                                    method.id);
+                                    id);
     }
 
     fn process_trait_ref(&mut self,
@@ -656,7 +659,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                     type_parameters: &ast::Generics,
                     trait_ref: &Option<ast::TraitRef>,
                     typ: &ast::Ty,
-                    impl_items: &Vec<ast::ImplItem>) {
+                    impl_items: &[P<ast::ImplItem>]) {
         let trait_id = trait_ref.as_ref().and_then(|tr| self.lookup_type_ref(tr.ref_id));
         match typ.node {
             // Common case impl for a struct or something basic.
@@ -698,14 +701,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
 
         self.process_generic_params(type_parameters, item.span, "", item.id);
         for impl_item in impl_items {
-            match *impl_item {
-                ast::MethodImplItem(ref method) => {
-                    visit::walk_method_helper(self, &**method)
-                }
-                ast::TypeImplItem(ref typedef) => {
-                    visit::walk_ty(self, &*typedef.typ)
-                }
-            }
+            visit::walk_impl_item(self, impl_item);
         }
     }
 
@@ -713,7 +709,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                      item: &ast::Item,
                      generics: &ast::Generics,
                      trait_refs: &OwnedSlice<ast::TyParamBound>,
-                     methods: &Vec<ast::TraitItem>) {
+                     methods: &[P<ast::TraitItem>]) {
         let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
         let val = self.span.snippet(item.span);
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
@@ -1233,71 +1229,24 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
         }
     }
 
-    // We don't actually index functions here, that is done in visit_item/ItemFn.
-    // Here we just visit methods.
-    fn visit_fn(&mut self,
-                fk: visit::FnKind<'v>,
-                fd: &'v ast::FnDecl,
-                b: &'v ast::Block,
-                s: Span,
-                _: ast::NodeId) {
-        if generated_code(s) {
-            return;
-        }
-
-        match fk {
-            visit::FkMethod(_, _, method) => self.process_method(method),
-            _ => visit::walk_fn(self, fk, fd, b, s),
+    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+        match trait_item.node {
+            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(..) => {}
         }
     }
 
-    fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
-        match *tm {
-            ast::RequiredMethod(ref method_type) => {
-                if generated_code(method_type.span) {
-                    return;
-                }
-
-                let mut scope_id;
-                let mut qualname = match ty::trait_of_item(&self.analysis.ty_cx,
-                                                           ast_util::local_def(method_type.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(method_type.span,
-                                           &format!("Could not find trait for method {}",
-                                                   method_type.id));
-                    },
-                };
-
-                qualname.push_str(&get_ident(method_type.ident));
-                let qualname = &qualname[..];
-
-                let sub_span = self.span.sub_span_after_keyword(method_type.span, keywords::Fn);
-                self.fmt.method_decl_str(method_type.span,
-                                         sub_span,
-                                         method_type.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,
-                                            method_type.span,
-                                            qualname,
-                                            method_type.id);
+    fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
+        match impl_item.node {
+            ast::MethodImplItem(ref sig, ref body) => {
+                self.process_method(sig, Some(body), impl_item.id,
+                                    impl_item.ident, impl_item.span);
             }
-            ast::ProvidedMethod(ref method) => self.process_method(&**method),
-            ast::TypeTraitItem(_) => {}
+            ast::TypeImplItem(_) |
+            ast::MacImplItem(_) => {}
         }
     }
 
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index f49905613d2..74326d4ea91 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -1268,47 +1268,35 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
             }
         }
-        Some(ast_map::NodeTraitItem(trait_method)) => {
-            match *trait_method {
-                ast::ProvidedMethod(ref m) => {
-                    match m.node {
-                        ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
-                            blk
-                        }
-                        ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
-                    }
-                }
-                ast::RequiredMethod(_) => {
+        Some(ast_map::NodeTraitItem(trait_item)) => {
+            match trait_item.node {
+                ast::MethodTraitItem(_, Some(ref body)) => body,
+                ast::MethodTraitItem(_, None) => {
                     tcx.sess.bug("unexpected variant: required trait method \
                                   in has_nested_returns")
                 }
-                ast::TypeTraitItem(_) => {
-                    tcx.sess.bug("unexpected variant: type trait item in \
+                ast::TypeTraitItem(..) => {
+                    tcx.sess.bug("unexpected variant: associated type trait item in \
                                   has_nested_returns")
                 }
             }
         }
-        Some(ast_map::NodeImplItem(ii)) => {
-            match *ii {
-                ast::MethodImplItem(ref m) => {
-                    match m.node {
-                        ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
-                            blk
-                        }
-                        ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
-                    }
-                }
+        Some(ast_map::NodeImplItem(impl_item)) => {
+            match impl_item.node {
+                ast::MethodImplItem(_, ref body) => body,
                 ast::TypeImplItem(_) => {
-                    tcx.sess.bug("unexpected variant: type impl item in \
+                    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")
             }
         }
@@ -1322,7 +1310,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
                                    tcx.map.path_to_string(id)))
     };
 
-    (blk.id, Some(cfg::CFG::new(tcx, &**blk)))
+    (blk.id, Some(cfg::CFG::new(tcx, blk)))
 }
 
 // Checks for the presence of "nested returns" in a function.
@@ -2818,26 +2806,31 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             v
         }
 
-        ast_map::NodeTraitItem(trait_method) => {
+        ast_map::NodeTraitItem(trait_item) => {
             debug!("get_item_val(): processing a NodeTraitItem");
-            match *trait_method {
-                ast::RequiredMethod(_) | ast::TypeTraitItem(_) => {
-                    ccx.sess().bug("unexpected variant: required trait \
-                                    method in get_item_val()");
+            match trait_item.node {
+                ast::MethodTraitItem(_, None) | ast::TypeTraitItem(..) => {
+                    ccx.sess().span_bug(trait_item.span,
+                        "unexpected variant: required trait method in get_item_val()");
                 }
-                ast::ProvidedMethod(ref m) => {
-                    register_method(ccx, id, &**m)
+                ast::MethodTraitItem(_, Some(_)) => {
+                    register_method(ccx, id, &trait_item.attrs, trait_item.span)
                 }
             }
         }
 
-        ast_map::NodeImplItem(ii) => {
-            match *ii {
-                ast::MethodImplItem(ref m) => register_method(ccx, id, &**m),
-                ast::TypeImplItem(ref typedef) => {
-                    ccx.sess().span_bug(typedef.span,
-                                        "unexpected variant: required impl \
-                                         method in get_item_val()")
+        ast_map::NodeImplItem(impl_item) => {
+            match impl_item.node {
+                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()")
                 }
             }
         }
@@ -2925,21 +2918,21 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 }
 
 fn register_method(ccx: &CrateContext, id: ast::NodeId,
-                   m: &ast::Method) -> ValueRef {
+                   attrs: &[ast::Attribute], span: Span) -> ValueRef {
     let mty = ty::node_id_to_type(ccx.tcx(), id);
 
-    let sym = exported_name(ccx, id, mty, &m.attrs);
+    let sym = exported_name(ccx, id, mty, &attrs);
 
     if let ty::ty_bare_fn(_, ref f) = mty.sty {
         let llfn = if f.abi == Rust || f.abi == RustCall {
-            register_fn(ccx, m.span, sym, id, mty)
+            register_fn(ccx, span, sym, id, mty)
         } else {
-            foreign::register_rust_fn_with_foreign_abi(ccx, m.span, sym, id)
+            foreign::register_rust_fn_with_foreign_abi(ccx, span, sym, id)
         };
-        set_llvm_fn_attrs(ccx, &m.attrs, llfn);
+        set_llvm_fn_attrs(ccx, &attrs, llfn);
         return llfn;
     } else {
-        ccx.sess().span_bug(m.span, "expected bare rust function");
+        ccx.sess().span_bug(span, "expected bare rust function");
     }
 }
 
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 95c39270cc6..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,
@@ -1300,25 +1299,30 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 }
             }
         }
-        ast_map::NodeImplItem(ref item) => {
-            match **item {
-                ast::MethodImplItem(ref method) => {
-                    if contains_nodebug_attribute(&method.attrs) {
+        ast_map::NodeImplItem(impl_item) => {
+            match impl_item.node {
+                ast::MethodImplItem(ref sig, ref body) => {
+                    if contains_nodebug_attribute(&impl_item.attrs) {
                         return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
-                    (method.pe_ident(),
-                     method.pe_fn_decl(),
-                     method.pe_generics(),
-                     method.pe_body(),
-                     method.span,
+                    (impl_item.ident,
+                     &sig.decl,
+                     &sig.generics,
+                     body,
+                     impl_item.span,
                      true)
                 }
-                ast::TypeImplItem(ref typedef) => {
-                    cx.sess().span_bug(typedef.span,
+                ast::TypeImplItem(_) => {
+                    cx.sess().span_bug(impl_item.span,
                                        "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) => {
@@ -1326,11 +1330,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 ast::ExprClosure(_, ref fn_decl, ref top_level_block) => {
                     let name = format!("fn{}", token::gensym("fn"));
                     let name = token::str_to_ident(&name[..]);
-                    (name, &**fn_decl,
+                    (name, fn_decl,
                         // 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)
@@ -1339,18 +1343,18 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         "create_function_debug_context: expected an expr_fn_block here")
             }
         }
-        ast_map::NodeTraitItem(ref trait_method) => {
-            match **trait_method {
-                ast::ProvidedMethod(ref method) => {
-                    if contains_nodebug_attribute(&method.attrs) {
+        ast_map::NodeTraitItem(trait_item) => {
+            match trait_item.node {
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
+                    if contains_nodebug_attribute(&trait_item.attrs) {
                         return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
-                    (method.pe_ident(),
-                     method.pe_fn_decl(),
-                     method.pe_generics(),
-                     method.pe_body(),
-                     method.span,
+                    (trait_item.ident,
+                     &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 14f92334073..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> {
@@ -42,7 +42,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             ccx.tcx(), fn_id,
             Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d)));
 
-    let inline_def = match csearch_result {
+    let inline_id = match csearch_result {
         csearch::FoundAst::NotFound => {
             ccx.external().borrow_mut().insert(fn_id, None);
             return None;
@@ -88,12 +88,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
                 None => {}
             }
 
-            local_def(item.id)
+            item.id
         }
         csearch::FoundAst::Found(&ast::IIForeign(ref item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(item.id));
             ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
-            local_def(item.id)
+            item.id
         }
         csearch::FoundAst::FoundParent(parent_id, &ast::IIItem(ref item)) => {
             ccx.external().borrow_mut().insert(parent_id, Some(item.id));
@@ -122,67 +122,53 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
                                  non-enum, non-struct parent")
           }
           trans_item(ccx, &**item);
-          local_def(my_id)
+          my_id
         }
         csearch::FoundAst::FoundParent(_, _) => {
             ccx.sess().bug("maybe_get_item_ast returned a FoundParent \
              with a non-item parent");
         }
         csearch::FoundAst::Found(&ast::IITraitItem(_, ref trait_item)) => {
-            match *trait_item {
-                ast::RequiredMethod(_) => ccx.sess().bug("found RequiredMethod IITraitItem"),
-                ast::ProvidedMethod(ref mth) => {
-                    ccx.external().borrow_mut().insert(fn_id, Some(mth.id));
-                    ccx.external_srcs().borrow_mut().insert(mth.id, fn_id);
-
-                    ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
-
-                    // If this is a default method, we can't look up the
-                    // impl type. But we aren't going to translate anyways, so
-                    // don't.
-                    local_def(mth.id)
-                }
-                ast::TypeTraitItem(_) => {
-                    ccx.sess().bug("found TypeTraitItem IITraitItem")
-                }
-            }
+            ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id));
+            ccx.external_srcs().borrow_mut().insert(trait_item.id, fn_id);
+
+            ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
+
+            // If this is a default method, we can't look up the
+            // impl type. But we aren't going to translate anyways, so
+            // don't.
+            trait_item.id
         }
         csearch::FoundAst::Found(&ast::IIImplItem(impl_did, ref impl_item)) => {
-            match *impl_item {
-                ast::MethodImplItem(ref mth) => {
-                    ccx.external().borrow_mut().insert(fn_id, Some(mth.id));
-                    ccx.external_srcs().borrow_mut().insert(mth.id, fn_id);
+            ccx.external().borrow_mut().insert(fn_id, Some(impl_item.id));
+            ccx.external_srcs().borrow_mut().insert(impl_item.id, fn_id);
 
-                    ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
-
-                    let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
-                    let unparameterized = impl_tpt.generics.types.is_empty() &&
-                            mth.pe_generics().ty_params.is_empty();
+            ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
 
+            // Translate monomorphic impl methods immediately.
+            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() &&
+                        sig.generics.ty_params.is_empty() {
                     let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
-                    if unparameterized {
-                        let llfn = get_item_val(ccx, mth.id);
-                        trans_fn(ccx,
-                                 &*mth.pe_fn_decl(),
-                                 &*mth.pe_body(),
-                                 llfn,
-                                 empty_substs,
-                                 mth.id,
-                                 &[]);
-                        // Use InternalLinkage so LLVM can optimize more
-                        // aggressively.
-                        SetLinkage(llfn, InternalLinkage);
-                    }
-                    local_def(mth.id)
-                }
-                ast::TypeImplItem(_) => {
-                    ccx.sess().bug("found TypeImplItem IIImplItem")
+                    let llfn = get_item_val(ccx, impl_item.id);
+                    trans_fn(ccx,
+                             &sig.decl,
+                             body,
+                             llfn,
+                             empty_substs,
+                             impl_item.id,
+                             &[]);
+                    // Use InternalLinkage so LLVM can optimize more aggressively.
+                    SetLinkage(llfn, InternalLinkage);
                 }
             }
+
+            impl_item.id
         }
     };
 
-    return Some(inline_def);
+    Some(local_def(inline_id))
 }
 
 pub fn get_local_instance(ccx: &CrateContext, fn_id: ast::DefId)
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 0c82d681eed..ba3798d7d80 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -41,8 +41,8 @@ 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;
 
 // drop_glue pointer, size, align.
 const VTABLE_OFFSET: uint = 3;
@@ -53,7 +53,7 @@ const VTABLE_OFFSET: uint = 3;
 /// see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
 pub fn trans_impl(ccx: &CrateContext,
                   name: ast::Ident,
-                  impl_items: &[ast::ImplItem],
+                  impl_items: &[P<ast::ImplItem>],
                   generics: &ast::Generics,
                   id: ast::NodeId) {
     let _icx = push_ctxt("meth::trans_impl");
@@ -61,47 +61,42 @@ pub fn trans_impl(ccx: &CrateContext,
 
     debug!("trans_impl(name={}, id={})", name.repr(tcx), id);
 
+    let mut v = TransItemVisitor { ccx: ccx };
+
     // Both here and below with generic methods, be sure to recurse and look for
     // items that we need to translate.
     if !generics.ty_params.is_empty() {
-        let mut v = TransItemVisitor{ ccx: ccx };
         for impl_item in impl_items {
-            match *impl_item {
-                ast::MethodImplItem(ref method) => {
-                    visit::walk_method_helper(&mut v, &**method);
+            match impl_item.node {
+                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 {
-            ast::MethodImplItem(ref method) => {
-                if method.pe_generics().ty_params.len() == 0 {
-                    let trans_everywhere = attr::requests_inline(&method.attrs);
+        match impl_item.node {
+            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, method.id);
+                        let llfn = get_item_val(ccx, impl_item.id);
                         let empty_substs = tcx.mk_substs(Substs::trans_empty());
-                        trans_fn(ccx,
-                                 method.pe_fn_decl(),
-                                 method.pe_body(),
-                                 llfn,
-                                 empty_substs,
-                                 method.id,
-                                 &[]);
+                        trans_fn(ccx, &sig.decl, body, llfn,
+                                 empty_substs, impl_item.id, &[]);
                         update_linkage(ccx,
                                        llfn,
-                                       Some(method.id),
+                                       Some(impl_item.id),
                                        if is_origin { OriginalTranslation } else { InlinedCopy });
                     }
                 }
-                let mut v = TransItemVisitor {
-                    ccx: ccx,
-                };
-                visit::walk_method_helper(&mut v, &**method);
+                visit::walk_impl_item(&mut v, impl_item);
             }
-            ast::TypeImplItem(_) => {}
+            ast::TypeImplItem(_) |
+            ast::MacImplItem(_) => {}
         }
     }
 }
@@ -189,17 +184,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let mname = if method_id.krate == ast::LOCAL_CRATE {
         match tcx.map.get(method_id.node) {
-            ast_map::NodeTraitItem(method) => {
-                let ident = match *method {
-                    ast::RequiredMethod(ref m) => m.ident,
-                    ast::ProvidedMethod(ref m) => m.pe_ident(),
-                    ast::TypeTraitItem(_) => {
-                        tcx.sess.bug("trans_static_method_callee() on \
-                                      an associated type?!")
-                    }
-                };
-                ident.name
-            }
+            ast_map::NodeTraitItem(trait_item) => trait_item.ident.name,
             _ => panic!("callee is not a trait method")
         }
     } else {
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 5ab1ec2a69e..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};
@@ -216,18 +216,18 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             }
             d
         }
-        ast_map::NodeImplItem(ii) => {
-            match *ii {
-                ast::MethodImplItem(ref mth) => {
+        ast_map::NodeImplItem(impl_item) => {
+            match impl_item.node {
+                ast::MethodImplItem(ref sig, ref body) => {
                     let d = mk_lldecl(abi::Rust);
-                    let needs_body = setup_lldecl(d, &mth.attrs);
+                    let needs_body = setup_lldecl(d, &impl_item.attrs);
                     if needs_body {
                         trans_fn(ccx,
-                                 mth.pe_fn_decl(),
-                                 mth.pe_body(),
+                                 &sig.decl,
+                                 body,
                                  d,
                                  psubsts,
-                                 mth.id,
+                                 impl_item.id,
                                  &[]);
                     }
                     d
@@ -235,16 +235,19 @@ 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(method) => {
-            match *method {
-                ast::ProvidedMethod(ref mth) => {
+        ast_map::NodeTraitItem(trait_item) => {
+            match trait_item.node {
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
                     let d = mk_lldecl(abi::Rust);
-                    let needs_body = setup_lldecl(d, &mth.attrs);
+                    let needs_body = setup_lldecl(d, &trait_item.attrs);
                     if needs_body {
-                        trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d,
-                                 psubsts, mth.id, &[]);
+                        trans_fn(ccx, &sig.decl, body, d,
+                                 psubsts, trait_item.id, &[]);
                     }
                     d
                 }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 2c7a9bf8020..28e7027b212 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1095,14 +1095,9 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
         // by type collection, which may be in progress at this point.
         match this.tcx().map.expect_item(trait_did.node).node {
             ast::ItemTrait(_, _, _, ref trait_items) => {
-                trait_items.iter().filter_map(|i| {
-                    if let ast::TypeTraitItem(ref assoc) = *i {
-                        if assoc.ty_param.ident.name == assoc_name {
-                            return Some(ast_util::local_def(assoc.ty_param.id));
-                        }
-                    }
-                    None
-                }).next().expect("missing associated type")
+                let item = trait_items.iter().find(|i| i.ident.name == assoc_name)
+                                      .expect("missing associated type");
+                ast_util::local_def(item.id)
             }
             _ => unreachable!()
         }
@@ -1447,22 +1442,19 @@ struct SelfInfo<'a, 'tcx> {
 }
 
 pub fn ty_of_method<'tcx>(this: &AstConv<'tcx>,
-                          unsafety: ast::Unsafety,
-                          untransformed_self_ty: Ty<'tcx>,
-                          explicit_self: &ast::ExplicitSelf,
-                          decl: &ast::FnDecl,
-                          abi: abi::Abi)
+                          sig: &ast::MethodSig,
+                          untransformed_self_ty: Ty<'tcx>)
                           -> (ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) {
     let self_info = Some(SelfInfo {
         untransformed_self_ty: untransformed_self_ty,
-        explicit_self: explicit_self,
+        explicit_self: &sig.explicit_self,
     });
     let (bare_fn_ty, optional_explicit_self_category) =
         ty_of_method_or_bare_fn(this,
-                                unsafety,
-                                abi,
+                                sig.unsafety,
+                                sig.abi,
                                 self_info,
-                                decl);
+                                &sig.decl);
     (bare_fn_ty, optional_explicit_self_category.unwrap())
 }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 44500ce0bbb..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;
@@ -739,30 +739,33 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
           }
 
         for impl_item in impl_items {
-            match *impl_item {
-                ast::MethodImplItem(ref m) => {
-                    check_method_body(ccx, &impl_pty.generics, &**m);
+            match impl_item.node {
+                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.
                 }
             }
         }
 
       }
-      ast::ItemTrait(_, ref generics, _, ref trait_methods) => {
+      ast::ItemTrait(_, ref generics, _, ref trait_items) => {
         check_trait_on_unimplemented(ccx, generics, it);
         let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
-        for trait_method in trait_methods {
-            match *trait_method {
-                RequiredMethod(..) => {
+        for trait_item in trait_items {
+            match trait_item.node {
+                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.
                 }
             }
@@ -855,28 +858,23 @@ 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) {
-    debug!("check_method_body(item_generics={}, method.id={})",
-            item_generics.repr(ccx.tcx),
-            method.id);
-    let param_env = ParameterEnvironment::for_item(ccx.tcx, method.id);
-
-    let fty = ty::node_id_to_type(ccx.tcx, method.id);
+                               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);
+    let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
+
+    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_fn_decl(),
-                  &*method.pe_body(),
-                  method.id,
-                  method.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>,
                                             impl_span: Span,
                                             impl_trait_ref: &ty::TraitRef<'tcx>,
-                                            impl_items: &[ast::ImplItem]) {
+                                            impl_items: &[P<ast::ImplItem>]) {
     // Locate trait methods
     let tcx = ccx.tcx;
     let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id);
@@ -884,9 +882,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     // Check existing impl methods to see if they are both present in trait
     // and compatible with trait signature
     for impl_item in impl_items {
-        match *impl_item {
-            ast::MethodImplItem(ref impl_method) => {
-                let impl_method_def_id = local_def(impl_method.id);
+        match impl_item.node {
+            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);
 
@@ -902,8 +900,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                              &ty::MethodTraitItem(ref impl_method_ty)) => {
                                 compare_impl_method(ccx.tcx,
                                                     &**impl_method_ty,
-                                                    impl_method.span,
-                                                    impl_method.pe_body().id,
+                                                    impl_item.span,
+                                                    body.id,
                                                     &**trait_method_ty,
                                                     &*impl_trait_ref);
                             }
@@ -911,7 +909,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 // This is span_bug as it should have already been
                                 // caught in resolve.
                                 tcx.sess.span_bug(
-                                    impl_method.span,
+                                    impl_item.span,
                                     &format!("item `{}` is of a different kind from its trait `{}`",
                                              token::get_name(impl_item_ty.name()),
                                              impl_trait_ref.repr(tcx)));
@@ -922,15 +920,15 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         // This is span_bug as it should have already been
                         // caught in resolve.
                         tcx.sess.span_bug(
-                            impl_method.span,
+                            impl_item.span,
                             &format!("method `{}` is not a member of trait `{}`",
                                      token::get_name(impl_item_ty.name()),
                                      impl_trait_ref.repr(tcx)));
                     }
                 }
             }
-            ast::TypeImplItem(ref typedef) => {
-                let typedef_def_id = local_def(typedef.id);
+            ast::TypeImplItem(_) => {
+                let typedef_def_id = local_def(impl_item.id);
                 let typedef_ty = ty::impl_or_trait_item(ccx.tcx,
                                                         typedef_def_id);
 
@@ -947,7 +945,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 // This is `span_bug` as it should have
                                 // already been caught in resolve.
                                 tcx.sess.span_bug(
-                                    typedef.span,
+                                    impl_item.span,
                                     &format!("item `{}` is of a different kind from its trait `{}`",
                                              token::get_name(typedef_ty.name()),
                                              impl_trait_ref.repr(tcx)));
@@ -958,7 +956,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         // This is `span_bug` as it should have already been
                         // caught in resolve.
                         tcx.sess.span_bug(
-                            typedef.span,
+                            impl_item.span,
                             &format!(
                                 "associated type `{}` is not a member of \
                                  trait `{}`",
@@ -967,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")
         }
     }
 
@@ -978,11 +978,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             ty::MethodTraitItem(ref trait_method) => {
                 let is_implemented =
                     impl_items.iter().any(|ii| {
-                        match *ii {
-                            ast::MethodImplItem(ref m) => {
-                                m.pe_ident().name == trait_method.name
+                        match ii.node {
+                            ast::MethodImplItem(..) => {
+                                ii.ident.name == trait_method.name
                             }
-                            ast::TypeImplItem(_) => false,
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => false,
                         }
                     });
                 let is_provided =
@@ -993,11 +994,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             }
             ty::TypeTraitItem(ref associated_type) => {
                 let is_implemented = impl_items.iter().any(|ii| {
-                    match *ii {
-                        ast::TypeImplItem(ref typedef) => {
-                            typedef.ident.name == associated_type.name
+                    match ii.node {
+                        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 32bd40ebda2..adbf4c6b210 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -498,28 +498,24 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         visit::walk_fn(self, fk, fd, b, span)
     }
 
-    fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
-        match t {
-            &ast::TraitItem::ProvidedMethod(_) |
-            &ast::TraitItem::TypeTraitItem(_) => {},
-            &ast::TraitItem::RequiredMethod(ref method) => {
-                match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) {
-                    ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
-                        reject_non_type_param_bounds(
-                            self.tcx(),
-                            method.span,
-                            &ty_method.predicates);
-                        reject_shadowing_type_parameters(
-                            self.tcx(),
-                            method.span,
-                            &ty_method.generics);
-                    }
-                    _ => {}
+    fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) {
+        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(
+                        self.tcx(),
+                        trait_item.span,
+                        &ty_method.predicates);
+                    reject_shadowing_type_parameters(
+                        self.tcx(),
+                        trait_item.span,
+                        &ty_method.generics);
                 }
+                _ => {}
             }
         }
 
-        visit::walk_trait_item(self, t)
+        visit::walk_trait_item(self, trait_item)
     }
 }
 
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index a06dcbaf556..6b0fb8ac71a 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -275,20 +275,22 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
     // Converts an implementation in the AST to a vector of items.
     fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
         match item.node {
-            ItemImpl(_, _, _, ref opt_trait, _, ref ast_items) => {
+            ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
                 let mut items: Vec<ImplOrTraitItemId> =
-                        ast_items.iter()
-                                 .map(|ast_item| {
-                            match *ast_item {
-                                ast::MethodImplItem(ref ast_method) => {
-                                    MethodTraitItemId(
-                                        local_def(ast_method.id))
-                                }
-                                ast::TypeImplItem(ref typedef) => {
-                                    TypeTraitItemId(local_def(typedef.id))
-                                }
-                            }
-                        }).collect();
+                        impl_items.iter().map(|impl_item| {
+                    match impl_item.node {
+                        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();
 
                 if opt_trait.is_some() {
                     let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index bd68802f262..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;
@@ -621,160 +621,52 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }
 }
 
-fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                                   trait_id: ast::NodeId,
-                                   trait_def: &ty::TraitDef<'tcx>,
-                                   trait_predicates: &ty::GenericPredicates<'tcx>) {
-    let tcx = ccx.tcx;
-    if let ast_map::NodeItem(item) = tcx.map.get(trait_id) {
-        if let ast::ItemTrait(_, _, _, ref trait_items) = item.node {
-            // For each method, construct a suitable ty::Method and
-            // store it into the `tcx.impl_or_trait_items` table:
-            for trait_item in trait_items {
-                match *trait_item {
-                    ast::RequiredMethod(_) |
-                    ast::ProvidedMethod(_) => {
-                        let ty_method = Rc::new(match *trait_item {
-                            ast::RequiredMethod(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &trait_predicates,
-                                    &trait_items[..],
-                                    &m.id,
-                                    &m.ident.name,
-                                    &m.explicit_self,
-                                    m.abi,
-                                    &m.generics,
-                                    &m.unsafety,
-                                    &*m.decl)
-                            }
-                            ast::ProvidedMethod(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &trait_predicates,
-                                    &trait_items[..],
-                                    &m.id,
-                                    &m.pe_ident().name,
-                                    m.pe_explicit_self(),
-                                    m.pe_abi(),
-                                    m.pe_generics(),
-                                    &m.pe_unsafety(),
-                                    &*m.pe_fn_decl())
-                            }
-                            ast::TypeTraitItem(ref at) => {
-                                tcx.sess.span_bug(at.ty_param.span,
-                                                  "there shouldn't be a type trait item here")
-                            }
-                        });
-
-                        debug!("ty_method_of_trait_method yielded {} for method {} of trait {}",
-                               ty_method.repr(ccx.tcx),
-                               trait_item.repr(ccx.tcx),
-                               local_def(trait_id).repr(ccx.tcx));
-
-                        make_method_ty(ccx, &*ty_method);
-
-                        tcx.impl_or_trait_items
-                            .borrow_mut()
-                            .insert(ty_method.def_id, ty::MethodTraitItem(ty_method));
-                    }
-                    ast::TypeTraitItem(ref ast_associated_type) => {
-                        let trait_did = local_def(trait_id);
-                        let associated_type = ty::AssociatedType {
-                            name: ast_associated_type.ty_param.ident.name,
-                            vis: ast::Public,
-                            def_id: local_def(ast_associated_type.ty_param.id),
-                            container: TraitContainer(trait_did),
-                        };
-
-                        let trait_item = ty::TypeTraitItem(Rc::new(associated_type));
-                        tcx.impl_or_trait_items
-                            .borrow_mut()
-                            .insert(associated_type.def_id, trait_item);
-                    }
-                }
-            }
-
-            // Add an entry mapping
-            let trait_item_def_ids =
-                Rc::new(trait_items.iter().map(|ti| {
-                    match *ti {
-                        ast::RequiredMethod(ref ty_method) => {
-                            ty::MethodTraitItemId(local_def(ty_method.id))
-                        }
-                        ast::ProvidedMethod(ref method) => {
-                            ty::MethodTraitItemId(local_def(method.id))
-                        }
-                        ast::TypeTraitItem(ref typedef) => {
-                            ty::TypeTraitItemId(local_def(typedef.ty_param.id))
-                        }
-                    }
-                }).collect());
+fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
+                            container: ImplOrTraitItemContainer,
+                            sig: &ast::MethodSig,
+                            id: ast::NodeId,
+                            ident: ast::Ident,
+                            vis: ast::Visibility,
+                            untransformed_rcvr_ty: Ty<'tcx>,
+                            rcvr_ty_generics: &ty::Generics<'tcx>,
+                            rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
+    let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
+
+    let ty_generic_predicates =
+        ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
+
+    let (fty, explicit_self_category) =
+        astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
+                              sig, untransformed_rcvr_ty);
+
+    let def_id = local_def(id);
+    let ty_method = ty::Method::new(ident.name,
+                                    ty_generics,
+                                    ty_generic_predicates,
+                                    fty,
+                                    explicit_self_category,
+                                    vis,
+                                    def_id,
+                                    container,
+                                    None);
+
+    let fty = ty::mk_bare_fn(ccx.tcx, Some(def_id),
+                             ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
+    debug!("method {} (id {}) has type {}",
+            ident.repr(ccx.tcx), id, fty.repr(ccx.tcx));
+    ccx.tcx.tcache.borrow_mut().insert(def_id,TypeScheme {
+        generics: ty_method.generics.clone(),
+        ty: fty
+    });
+    ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
 
-            let trait_def_id = local_def(trait_id);
-            tcx.trait_item_def_ids.borrow_mut().insert(trait_def_id, trait_item_def_ids);
-        }
-    }
+    write_ty_to_tcx(ccx.tcx, id, fty);
 
-    fn make_method_ty<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, m: &ty::Method<'tcx>) {
-        ccx.tcx.tcache.borrow_mut().insert(
-            m.def_id,
-            TypeScheme {
-                generics: m.generics.clone(),
-                ty: ty::mk_bare_fn(ccx.tcx, Some(m.def_id), ccx.tcx.mk_bare_fn(m.fty.clone()))
-            });
-        ccx.tcx.predicates.borrow_mut().insert(
-            m.def_id,
-            m.predicates.clone());
-    }
-
-    fn ty_method_of_trait_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                                           trait_id: ast::NodeId,
-                                           trait_generics: &ty::Generics<'tcx>,
-                                           trait_bounds: &ty::GenericPredicates<'tcx>,
-                                           _trait_items: &[ast::TraitItem],
-                                           m_id: &ast::NodeId,
-                                           m_name: &ast::Name,
-                                           m_explicit_self: &ast::ExplicitSelf,
-                                           m_abi: abi::Abi,
-                                           m_generics: &ast::Generics,
-                                           m_unsafety: &ast::Unsafety,
-                                           m_decl: &ast::FnDecl)
-                                           -> ty::Method<'tcx>
-    {
-        let ty_generics =
-            ty_generics_for_fn(ccx, m_generics, trait_generics);
-
-        let ty_generic_predicates =
-            ty_generic_predicates_for_fn(ccx, m_generics, trait_bounds);
-
-        let (fty, explicit_self_category) = {
-            let trait_self_ty = ty::mk_self_type(ccx.tcx);
-            astconv::ty_of_method(&ccx.icx(&(trait_bounds, m_generics)),
-                                  *m_unsafety,
-                                  trait_self_ty,
-                                  m_explicit_self,
-                                  m_decl,
-                                  m_abi)
-        };
+    debug!("writing method type: def_id={:?} mty={}",
+            def_id, ty_method.repr(ccx.tcx));
 
-        ty::Method::new(
-            *m_name,
-            ty_generics,
-            ty_generic_predicates,
-            fty,
-            explicit_self_category,
-            // assume public, because this is only invoked on trait methods
-            ast::Public,
-            local_def(*m_id),
-            TraitContainer(local_def(trait_id)),
-            None
-        )
-    }
+    ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
+        ty::MethodTraitItem(Rc::new(ty_method)));
 }
 
 fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@@ -817,29 +709,28 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 }
 
 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                                     trait_def: &ty::TraitDef<'tcx>,
-                                     associated_type: &ast::AssociatedType)
+                                     container: ImplOrTraitItemContainer,
+                                     ident: ast::Ident,
+                                     id: ast::NodeId,
+                                     vis: ast::Visibility)
 {
     let associated_type = Rc::new(ty::AssociatedType {
-        name: associated_type.ty_param.ident.name,
-        vis: ast::Public,
-        def_id: local_def(associated_type.ty_param.id),
-        container: TraitContainer(trait_def.trait_ref.def_id),
+        name: ident.name,
+        vis: vis,
+        def_id: local_def(id),
+        container: container
     });
-    ccx.tcx
-       .impl_or_trait_items
-       .borrow_mut()
-       .insert(associated_type.def_id, ty::TypeTraitItem(associated_type));
+    ccx.tcx.impl_or_trait_items.borrow_mut()
+       .insert(local_def(id), ty::TypeTraitItem(associated_type));
 }
 
 fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
                                  container: ImplOrTraitItemContainer,
-                                 ms: I,
+                                 methods: I,
                                  untransformed_rcvr_ty: Ty<'tcx>,
                                  rcvr_ty_generics: &ty::Generics<'tcx>,
-                                 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,
-                                 rcvr_visibility: ast::Visibility)
-                                 where I: Iterator<Item=&'i ast::Method>
+                                 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>)
+    where I: Iterator<Item=(&'i ast::MethodSig, ast::NodeId, ast::Ident, ast::Visibility, Span)>
 {
     debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})",
            untransformed_rcvr_ty.repr(ccx.tcx),
@@ -848,81 +739,20 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
 
     let tcx = ccx.tcx;
     let mut seen_methods = FnvHashSet();
-    for m in ms {
-        if !seen_methods.insert(m.pe_ident().repr(tcx)) {
-            span_err!(tcx.sess, m.span, E0201, "duplicate method in trait impl");
+    for (sig, id, ident, vis, span) in methods {
+        if !seen_methods.insert(ident.name) {
+            span_err!(tcx.sess, span, E0201, "duplicate method");
         }
 
-        let m_def_id = local_def(m.id);
-
-        let mty = Rc::new(ty_of_method(ccx,
-                                       container,
-                                       m,
-                                       untransformed_rcvr_ty,
-                                       rcvr_ty_generics,
-                                       rcvr_ty_predicates,
-                                       rcvr_visibility));
-        let fty = ty::mk_bare_fn(tcx, Some(m_def_id), tcx.mk_bare_fn(mty.fty.clone()));
-        debug!("method {} (id {}) has type {}",
-                m.pe_ident().repr(tcx),
-                m.id,
-                fty.repr(tcx));
-        tcx.tcache.borrow_mut().insert(
-            m_def_id,
-            TypeScheme {
-                generics: mty.generics.clone(),
-                ty: fty
-            });
-        tcx.predicates.borrow_mut().insert(m_def_id, mty.predicates.clone());
-
-        write_ty_to_tcx(tcx, m.id, fty);
-
-        debug!("writing method type: def_id={:?} mty={}",
-               mty.def_id, mty.repr(ccx.tcx));
-
-        tcx.impl_or_trait_items
-           .borrow_mut()
-           .insert(mty.def_id, ty::MethodTraitItem(mty));
-    }
-
-    fn ty_of_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                              container: ImplOrTraitItemContainer,
-                              m: &ast::Method,
-                              untransformed_rcvr_ty: Ty<'tcx>,
-                              rcvr_ty_generics: &ty::Generics<'tcx>,
-                              rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,
-                              rcvr_visibility: ast::Visibility)
-                              -> ty::Method<'tcx>
-    {
-        let m_ty_generics =
-            ty_generics_for_fn(ccx, m.pe_generics(), rcvr_ty_generics);
-
-        let m_ty_generic_predicates =
-            ty_generic_predicates_for_fn(ccx, m.pe_generics(), rcvr_ty_predicates);
-
-        let (fty, explicit_self_category) =
-            astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, m.pe_generics())),
-                                  m.pe_unsafety(),
-                                  untransformed_rcvr_ty,
-                                  m.pe_explicit_self(),
-                                  &*m.pe_fn_decl(),
-                                  m.pe_abi());
-
-        // 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 = m.pe_vis().inherit_from(rcvr_visibility);
-
-        ty::Method::new(m.pe_ident().name,
-                        m_ty_generics,
-                        m_ty_generic_predicates,
-                        fty,
-                        explicit_self_category,
-                        method_vis,
-                        local_def(m.id),
-                        container,
-                        None)
+        convert_method(ccx,
+                       container,
+                       sig,
+                       id,
+                       ident,
+                       vis,
+                       untransformed_rcvr_ty,
+                       rcvr_ty_generics,
+                       rcvr_ty_predicates);
     }
 }
 
@@ -1014,62 +844,67 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                 it.vis
             };
 
-            let mut methods = Vec::new();
+            // Convert all the associated types.
             for impl_item in impl_items {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        methods.push(&**method);
-                    }
-                    ast::TypeImplItem(ref typedef) => {
+                match impl_item.node {
+                    ast::TypeImplItem(ref ty) => {
                         if opt_trait_ref.is_none() {
-                            span_err!(tcx.sess, typedef.span, E0202,
+                            span_err!(tcx.sess, impl_item.span, E0202,
                                               "associated items are not allowed in inherent impls");
                         }
 
-                        let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &*typedef.typ);
-                        tcx.tcache.borrow_mut().insert(local_def(typedef.id),
+                        convert_associated_type(ccx, ImplContainer(local_def(it.id)),
+                                                impl_item.ident, impl_item.id, impl_item.vis);
+
+                        let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
+                        tcx.tcache.borrow_mut().insert(local_def(impl_item.id),
                                                        TypeScheme {
                                                            generics: ty::Generics::empty(),
                                                            ty: typ,
                                                        });
-                        tcx.predicates.borrow_mut().insert(local_def(typedef.id),
+                        tcx.predicates.borrow_mut().insert(local_def(impl_item.id),
                                                            ty::GenericPredicates::empty());
-                        write_ty_to_tcx(tcx, typedef.id, typ);
-
-                        let associated_type = Rc::new(ty::AssociatedType {
-                            name: typedef.ident.name,
-                            vis: typedef.vis,
-                            def_id: local_def(typedef.id),
-                            container: ty::ImplContainer(local_def(it.id)),
-                        });
-                        tcx.impl_or_trait_items
-                           .borrow_mut()
-                           .insert(local_def(typedef.id),
-                                   ty::TypeTraitItem(associated_type));
+                        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 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((sig, ii.id, ii.ident, method_vis, ii.span))
+                    }
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => None
+                }
+            });
             convert_methods(ccx,
                             ImplContainer(local_def(it.id)),
-                            methods.into_iter(),
+                            methods,
                             selfty,
                             &ty_generics,
-                            &ty_predicates,
-                            parent_visibility);
+                            &ty_predicates);
 
             for impl_item in impl_items {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        let body_id = method.pe_body().id;
+                match impl_item.node {
+                    ast::MethodImplItem(ref sig, ref body) => {
+                        let body_id = body.id;
                         check_method_self_type(ccx,
                                                &BindingRscope::new(),
-                                               ccx.method_ty(method.id),
+                                               ccx.method_ty(impl_item.id),
                                                selfty,
-                                               method.pe_explicit_self(),
+                                               &sig.explicit_self,
                                                body_id);
                     }
-                    ast::TypeImplItem(..) => { }
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => {}
                 }
             }
 
@@ -1091,57 +926,64 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             let _: Result<(), ErrorReported> = // any error is already reported, can ignore
                 ccx.ensure_super_predicates(it.span, local_def(it.id));
             convert_trait_predicates(ccx, it);
-            let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(it.id));
+            let trait_predicates = ty::lookup_predicates(tcx, local_def(it.id));
 
             debug!("convert: trait_bounds={:?}", trait_predicates);
 
-            // Run convert_methods on the provided methods.
-            let untransformed_rcvr_ty = ty::mk_self_type(tcx);
+            // Convert all the associated types.
+            for trait_item in trait_items {
+                match trait_item.node {
+                    ast::MethodTraitItem(..) => {}
+                    ast::TypeTraitItem(..) => {
+                        convert_associated_type(ccx, TraitContainer(local_def(it.id)),
+                                                trait_item.ident, trait_item.id, ast::Public);
+                    }
+                }
+            };
+
+            let methods = trait_items.iter().filter_map(|ti| {
+                let sig = match ti.node {
+                    ast::MethodTraitItem(ref sig, _) => sig,
+                    ast::TypeTraitItem(..) => return None,
+                };
+                Some((sig, ti.id, ti.ident, ast::Inherited, ti.span))
+            });
+
+            // Run convert_methods on the trait methods.
             convert_methods(ccx,
                             TraitContainer(local_def(it.id)),
-                            trait_items.iter().filter_map(|m| match *m {
-                                ast::RequiredMethod(_) => None,
-                                ast::ProvidedMethod(ref m) => Some(&**m),
-                                ast::TypeTraitItem(_) => None,
-                            }),
-                            untransformed_rcvr_ty,
+                            methods,
+                            ty::mk_self_type(tcx),
                             &trait_def.generics,
-                            &trait_predicates,
-                            it.vis);
+                            &trait_predicates);
 
-            // We need to do this *after* converting methods, since
-            // convert_methods produces a tcache entry that is wrong for
-            // static trait methods. This is somewhat unfortunate.
-            collect_trait_methods(ccx, it.id, &*trait_def, &trait_predicates);
+            // Add an entry mapping
+            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::MethodTraitItem(..) => {
+                        ty::MethodTraitItemId(def_id)
+                    }
+                    ast::TypeTraitItem(..) => {
+                        ty::TypeTraitItemId(def_id)
+                    }
+                }
+            }).collect());
+            tcx.trait_item_def_ids.borrow_mut().insert(local_def(it.id), trait_item_def_ids);
 
             // This must be done after `collect_trait_methods` so that
             // we have a method type stored for every method.
             for trait_item in trait_items {
-                let self_type = ty::mk_self_type(tcx);
-                match *trait_item {
-                    ast::RequiredMethod(ref type_method) => {
-                        let rscope = BindingRscope::new();
-                        check_method_self_type(ccx,
-                                               &rscope,
-                                               ccx.method_ty(type_method.id),
-                                               self_type,
-                                               &type_method.explicit_self,
-                                               it.id)
-                    }
-                    ast::ProvidedMethod(ref method) => {
-                        check_method_self_type(ccx,
-                                               &BindingRscope::new(),
-                                               ccx.method_ty(method.id),
-                                               self_type,
-                                               method.pe_explicit_self(),
-                                               it.id)
-                    }
-                    ast::TypeTraitItem(ref associated_type) => {
-                        convert_associated_type(ccx,
-                                                &*trait_def,
-                                                &**associated_type);
-                    }
-                }
+                let sig = match trait_item.node {
+                    ast::MethodTraitItem(ref sig, _) => sig,
+                    ast::TypeTraitItem(..) => continue
+                };
+                check_method_self_type(ccx,
+                                       &BindingRscope::new(),
+                                       ccx.method_ty(trait_item.id),
+                                       ty::mk_self_type(tcx),
+                                       &sig.explicit_self,
+                                       it.id)
             }
         },
         ast::ItemStruct(ref struct_def, _) => {
@@ -1351,15 +1193,12 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
     let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
 
-    let associated_type_names: Vec<_> =
-        items.iter()
-             .filter_map(|item| {
-                 match *item {
-                     ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None,
-                     ast::TypeTraitItem(ref data) => Some(data.ty_param.ident.name),
-                 }
-             })
-             .collect();
+    let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
+        match trait_item.node {
+            ast::MethodTraitItem(..) => None,
+            ast::TypeTraitItem(..) => Some(trait_item.ident.name),
+        }
+    }).collect();
 
     let trait_ref = Rc::new(ty::TraitRef {
         def_id: def_id,
@@ -1426,13 +1265,12 @@ fn trait_defines_associated_type_named(ccx: &CrateCtxt,
         _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
     };
 
-    trait_items.iter()
-               .any(|trait_item| {
-                   match *trait_item {
-                       ast::TypeTraitItem(ref t) => t.ty_param.ident.name == assoc_name,
-                       ast::RequiredMethod(..) | ast::ProvidedMethod(..) => false,
-                   }
-               })
+    trait_items.iter().any(|trait_item| {
+        match trait_item.node {
+            ast::TypeTraitItem(..) => trait_item.ident.name == assoc_name,
+            ast::MethodTraitItem(..) => false,
+        }
+    })
 }
 
 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) {
@@ -1484,32 +1322,29 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item)
                                                  ast_generics: &ast::Generics,
                                                  trait_predicates: &ty::GenericPredicates<'tcx>,
                                                  self_trait_ref: &Rc<ty::TraitRef<'tcx>>,
-                                                 trait_items: &[ast::TraitItem])
+                                                 trait_items: &[P<ast::TraitItem>])
                                                  -> Vec<ty::Predicate<'tcx>>
     {
-        trait_items
-            .iter()
-            .flat_map(|trait_item| {
-                let assoc_type_def = match *trait_item {
-                    ast::TypeTraitItem(ref assoc_type) => &assoc_type.ty_param,
-                    ast::RequiredMethod(..) | ast::ProvidedMethod(..) => {
-                        return vec!().into_iter();
-                    }
-                };
+        trait_items.iter().flat_map(|trait_item| {
+            let bounds = match trait_item.node {
+                ast::TypeTraitItem(ref bounds, _) => bounds,
+                ast::MethodTraitItem(..) => {
+                    return vec!().into_iter();
+                }
+            };
 
-                let assoc_ty = ty::mk_projection(ccx.tcx,
-                                                 self_trait_ref.clone(),
-                                                 assoc_type_def.ident.name);
+            let assoc_ty = ty::mk_projection(ccx.tcx,
+                                             self_trait_ref.clone(),
+                                             trait_item.ident.name);
 
-                let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
-                                            assoc_ty,
-                                            &*assoc_type_def.bounds,
-                                            SizedByDefault::Yes,
-                                            assoc_type_def.span);
+            let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
+                                        assoc_ty,
+                                        bounds,
+                                        SizedByDefault::Yes,
+                                        trait_item.span);
 
-                ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter()
-            })
-            .collect()
+            ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter()
+        }).collect()
     }
 }
 
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index db41bf9fee3..9f7b68f38fa 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -147,29 +147,13 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind
 
 pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
                             did: ast::DefId) -> clean::Trait {
-    use clean::TraitMethod;
-
     let def = ty::lookup_trait_def(tcx, did);
     let trait_items = ty::trait_items(tcx, did).clean(cx);
-    let provided = ty::provided_trait_methods(tcx, did);
-    let items = trait_items.into_iter().map(|trait_item| {
-        match trait_item.inner {
-            clean::TyMethodItem(_) => {
-                if provided.iter().any(|a| a.def_id == trait_item.def_id) {
-                    TraitMethod::ProvidedMethod(trait_item)
-                } else {
-                    TraitMethod::RequiredMethod(trait_item)
-                }
-            },
-            clean::AssociatedTypeItem(_) => TraitMethod::TypeTraitItem(trait_item),
-            _ => unreachable!()
-        }
-    });
     let predicates = ty::lookup_predicates(tcx, did);
     clean::Trait {
         unsafety: def.unsafety,
         generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx),
-        items: items.collect(),
+        items: trait_items,
         bounds: vec![], // supertraits can be found in the list of predicates
     }
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index c39451b15ad..e91e95961c5 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -11,7 +11,6 @@
 //! This module contains the "cleaned" pieces of the AST, and the functions
 //! that clean them.
 
-pub use self::ImplMethod::*;
 pub use self::Type::*;
 pub use self::PrimitiveType::*;
 pub use self::TypeKind::*;
@@ -24,13 +23,11 @@ pub use self::Attribute::*;
 pub use self::TyParamBound::*;
 pub use self::SelfTy::*;
 pub use self::FunctionRetTy::*;
-pub use self::TraitMethod::*;
 
 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;
@@ -70,7 +67,7 @@ pub trait Clean<T> {
     fn clean(&self, cx: &DocContext) -> T;
 }
 
-impl<T: Clean<U>, U> Clean<Vec<U>> for Vec<T> {
+impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
     fn clean(&self, cx: &DocContext) -> Vec<U> {
         self.iter().map(|x| x.clean(cx)).collect()
     }
@@ -339,7 +336,7 @@ pub enum ItemEnum {
     ForeignStaticItem(Static),
     MacroItem(Macro),
     PrimitiveItem(PrimitiveType),
-    AssociatedTypeItem(TyParam),
+    AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -951,34 +948,26 @@ pub struct Method {
     pub abi: abi::Abi
 }
 
-impl Clean<Item> for ast::Method {
-    fn clean(&self, cx: &DocContext) -> Item {
-        let all_inputs = &self.pe_fn_decl().inputs;
-        let inputs = match self.pe_explicit_self().node {
+impl Clean<Method> for ast::MethodSig {
+    fn clean(&self, cx: &DocContext) -> Method {
+        let all_inputs = &self.decl.inputs;
+        let inputs = match self.explicit_self.node {
             ast::SelfStatic => &**all_inputs,
             _ => &all_inputs[1..]
         };
         let decl = FnDecl {
             inputs: Arguments {
-                values: inputs.iter().map(|x| x.clean(cx)).collect(),
+                values: inputs.clean(cx),
             },
-            output: self.pe_fn_decl().output.clean(cx),
+            output: self.decl.output.clean(cx),
             attrs: Vec::new()
         };
-        Item {
-            name: Some(self.pe_ident().clean(cx)),
-            attrs: self.attrs.clean(cx),
-            source: self.span.clean(cx),
-            def_id: ast_util::local_def(self.id),
-            visibility: self.pe_vis().clean(cx),
-            stability: get_stability(cx, ast_util::local_def(self.id)),
-            inner: MethodItem(Method {
-                generics: self.pe_generics().clean(cx),
-                self_: self.pe_explicit_self().node.clean(cx),
-                unsafety: self.pe_unsafety().clone(),
-                decl: decl,
-                abi: self.pe_abi()
-            }),
+        Method {
+            generics: self.generics.clean(cx),
+            self_: self.explicit_self.node.clean(cx),
+            unsafety: self.unsafety.clone(),
+            decl: decl,
+            abi: self.abi
         }
     }
 }
@@ -992,33 +981,25 @@ pub struct TyMethod {
     pub abi: abi::Abi
 }
 
-impl Clean<Item> for ast::TypeMethod {
-    fn clean(&self, cx: &DocContext) -> Item {
+impl Clean<TyMethod> for ast::MethodSig {
+    fn clean(&self, cx: &DocContext) -> TyMethod {
         let inputs = match self.explicit_self.node {
             ast::SelfStatic => &*self.decl.inputs,
             _ => &self.decl.inputs[1..]
         };
         let decl = FnDecl {
             inputs: Arguments {
-                values: inputs.iter().map(|x| x.clean(cx)).collect(),
+                values: inputs.clean(cx),
             },
             output: self.decl.output.clean(cx),
             attrs: Vec::new()
         };
-        Item {
-            name: Some(self.ident.clean(cx)),
-            attrs: self.attrs.clean(cx),
-            source: self.span.clean(cx),
-            def_id: ast_util::local_def(self.id),
-            visibility: None,
-            stability: get_stability(cx, ast_util::local_def(self.id)),
-            inner: TyMethodItem(TyMethod {
-                unsafety: self.unsafety.clone(),
-                decl: decl,
-                self_: self.explicit_self.node.clean(cx),
-                generics: self.generics.clean(cx),
-                abi: self.abi
-            }),
+        TyMethod {
+            unsafety: self.unsafety.clone(),
+            decl: decl,
+            self_: self.explicit_self.node.clean(cx),
+            generics: self.generics.clean(cx),
+            abi: self.abi
         }
     }
 }
@@ -1166,7 +1147,7 @@ impl Clean<FunctionRetTy> for ast::FunctionRetTy {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Trait {
     pub unsafety: ast::Unsafety,
-    pub items: Vec<TraitMethod>,
+    pub items: Vec<Item>,
     pub generics: Generics,
     pub bounds: Vec<TyParamBound>,
 }
@@ -1205,64 +1186,59 @@ impl Clean<PolyTrait> for ast::PolyTraitRef {
     }
 }
 
-/// An item belonging to a trait, whether a method or associated. Could be named
-/// TraitItem except that's already taken by an exported enum variant.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub enum TraitMethod {
-    RequiredMethod(Item),
-    ProvidedMethod(Item),
-    TypeTraitItem(Item), // an associated type
-}
-
-impl TraitMethod {
-    pub fn is_req(&self) -> bool {
-        match self {
-            &RequiredMethod(..) => true,
-            _ => false,
-        }
-    }
-    pub fn is_def(&self) -> bool {
-        match self {
-            &ProvidedMethod(..) => true,
-            _ => false,
-        }
-    }
-    pub fn is_type(&self) -> bool {
-        match self {
-            &TypeTraitItem(..) => true,
-            _ => false,
-        }
-    }
-    pub fn item<'a>(&'a self) -> &'a Item {
-        match *self {
-            RequiredMethod(ref item) => item,
-            ProvidedMethod(ref item) => item,
-            TypeTraitItem(ref item) => item,
-        }
-    }
-}
-
-impl Clean<TraitMethod> for ast::TraitItem {
-    fn clean(&self, cx: &DocContext) -> TraitMethod {
-        match self {
-            &ast::RequiredMethod(ref t) => RequiredMethod(t.clean(cx)),
-            &ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean(cx)),
-            &ast::TypeTraitItem(ref t) => TypeTraitItem(t.clean(cx)),
+impl Clean<Item> for ast::TraitItem {
+    fn clean(&self, cx: &DocContext) -> Item {
+        let inner = match self.node {
+            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))
+            }
+        };
+        Item {
+            name: Some(self.ident.clean(cx)),
+            attrs: self.attrs.clean(cx),
+            source: self.span.clean(cx),
+            def_id: ast_util::local_def(self.id),
+            visibility: None,
+            stability: get_stability(cx, ast_util::local_def(self.id)),
+            inner: inner
         }
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub enum ImplMethod {
-    MethodImplItem(Item),
-    TypeImplItem(Item),
-}
-
-impl Clean<ImplMethod> for ast::ImplItem {
-    fn clean(&self, cx: &DocContext) -> ImplMethod {
-        match self {
-            &ast::MethodImplItem(ref t) => MethodImplItem(t.clean(cx)),
-            &ast::TypeImplItem(ref t) => TypeImplItem(t.clean(cx)),
+impl Clean<Item> for ast::ImplItem {
+    fn clean(&self, cx: &DocContext) -> Item {
+        let inner = match self.node {
+            ast::MethodImplItem(ref sig, _) => {
+                MethodItem(sig.clean(cx))
+            }
+            ast::TypeImplItem(ref ty) => TypedefItem(Typedef {
+                type_: ty.clean(cx),
+                generics: Generics {
+                    lifetimes: Vec::new(),
+                    type_params: Vec::new(),
+                    where_predicates: Vec::new()
+                },
+            }),
+            ast::MacImplItem(_) => {
+                MacroItem(Macro {
+                    source: self.span.to_src(cx),
+                })
+            }
+        };
+        Item {
+            name: Some(self.ident.clean(cx)),
+            source: self.span.clean(cx),
+            attrs: self.attrs.clean(cx),
+            def_id: ast_util::local_def(self.id),
+            visibility: self.vis.clean(cx),
+            stability: get_stability(cx, ast_util::local_def(self.id)),
+            inner: inner
         }
     }
 }
@@ -2128,12 +2104,7 @@ impl Clean<Item> for doctree::Impl {
                 generics: self.generics.clean(cx),
                 trait_: self.trait_.clean(cx),
                 for_: self.for_.clean(cx),
-                items: self.items.clean(cx).into_iter().map(|ti| {
-                        match ti {
-                            MethodImplItem(i) => i,
-                            TypeImplItem(i) => i,
-                        }
-                    }).collect(),
+                items: self.items.clean(cx),
                 derived: detect_derived(&self.attrs),
                 polarity: Some(self.polarity.clean(cx)),
             }),
@@ -2500,37 +2471,15 @@ impl Clean<Stability> for attr::Stability {
     }
 }
 
-impl Clean<Item> for ast::AssociatedType {
-    fn clean(&self, cx: &DocContext) -> Item {
-        Item {
-            source: self.ty_param.span.clean(cx),
-            name: Some(self.ty_param.ident.clean(cx)),
-            attrs: self.attrs.clean(cx),
-            inner: AssociatedTypeItem(self.ty_param.clean(cx)),
-            visibility: None,
-            def_id: ast_util::local_def(self.ty_param.id),
-            stability: None,
-        }
-    }
-}
-
 impl Clean<Item> for ty::AssociatedType {
     fn clean(&self, cx: &DocContext) -> Item {
         Item {
             source: DUMMY_SP.clean(cx),
             name: Some(self.name.clean(cx)),
             attrs: Vec::new(),
-            inner: AssociatedTypeItem(TyParam {
-                name: self.name.clean(cx),
-                did: ast::DefId {
-                    krate: 0,
-                    node: ast::DUMMY_NODE_ID
-                },
-                // FIXME(#20727): bounds are missing and need to be filled in from the
-                // predicates on the trait itself
-                bounds: vec![],
-                default: None,
-            }),
+            // FIXME(#20727): bounds are missing and need to be filled in from the
+            // predicates on the trait itself
+            inner: AssociatedTypeItem(vec![], None),
             visibility: None,
             def_id: self.def_id,
             stability: None,
@@ -2538,27 +2487,6 @@ impl Clean<Item> for ty::AssociatedType {
     }
 }
 
-impl Clean<Item> for ast::Typedef {
-    fn clean(&self, cx: &DocContext) -> Item {
-        Item {
-            source: self.span.clean(cx),
-            name: Some(self.ident.clean(cx)),
-            attrs: self.attrs.clean(cx),
-            inner: TypedefItem(Typedef {
-                type_: self.typ.clean(cx),
-                generics: Generics {
-                    lifetimes: Vec::new(),
-                    type_params: Vec::new(),
-                    where_predicates: Vec::new()
-                },
-            }),
-            visibility: None,
-            def_id: ast_util::local_def(self.id),
-            stability: None,
-        }
-    }
-}
-
 impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>, ParamSpace) {
     fn clean(&self, cx: &DocContext) -> Typedef {
         let (ref ty_scheme, ref predicates, ps) = *self;
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 8143926982f..5a4deaa2e72 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -174,7 +174,7 @@ pub struct Constant {
 pub struct Trait {
     pub unsafety: ast::Unsafety,
     pub name: Ident,
-    pub items: Vec<ast::TraitItem>, //should be TraitItem
+    pub items: Vec<P<ast::TraitItem>>, //should be TraitItem
     pub generics: ast::Generics,
     pub bounds: Vec<ast::TyParamBound>,
     pub attrs: Vec<ast::Attribute>,
@@ -190,7 +190,7 @@ pub struct Impl {
     pub generics: ast::Generics,
     pub trait_: Option<ast::TraitRef>,
     pub for_: P<ast::Ty>,
-    pub items: Vec<ast::ImplItem>,
+    pub items: Vec<P<ast::ImplItem>>,
     pub attrs: Vec<ast::Attribute>,
     pub whence: Span,
     pub vis: ast::Visibility,
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 4f277cc868a..cdeeacfb783 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -40,37 +40,13 @@ pub trait DocFolder : Sized {
                 EnumItem(i)
             },
             TraitItem(mut i) => {
-                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod)
-                        -> Option<TraitMethod> {
-                    match trm {
-                        RequiredMethod(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(RequiredMethod(x)),
-                                None => return None,
-                            }
-                        },
-                        ProvidedMethod(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(ProvidedMethod(x)),
-                                None => return None,
-                            }
-                        },
-                        TypeTraitItem(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(TypeTraitItem(x)),
-                                None => return None,
-                            }
-                        }
-                    }
-                }
                 let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
-                i.items.extend(foo.into_iter().filter_map(|x| vtrm(self, x)));
+                i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x)));
                 TraitItem(i)
             },
             ImplItem(mut i) => {
                 let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
-                i.items.extend(foo.into_iter()
-                                  .filter_map(|x| self.fold_item(x)));
+                i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x)));
                 ImplItem(i)
             },
             VariantItem(i) => {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 46c7a701954..dba7b16ecee 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1685,9 +1685,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                   bounds,
                   WhereClause(&t.generics)));
 
-    let types = t.items.iter().filter(|m| m.is_type()).collect::<Vec<_>>();
-    let required = t.items.iter().filter(|m| m.is_req()).collect::<Vec<_>>();
-    let provided = t.items.iter().filter(|m| m.is_def()).collect::<Vec<_>>();
+    let types = t.items.iter().filter(|m| {
+        match m.inner { clean::AssociatedTypeItem(..) => true, _ => false }
+    }).collect::<Vec<_>>();
+    let required = t.items.iter().filter(|m| {
+        match m.inner { clean::TyMethodItem(_) => true, _ => false }
+    }).collect::<Vec<_>>();
+    let provided = t.items.iter().filter(|m| {
+        match m.inner { clean::MethodItem(_) => true, _ => false }
+    }).collect::<Vec<_>>();
 
     if t.items.len() == 0 {
         try!(write!(w, "{{ }}"));
@@ -1695,7 +1701,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         try!(write!(w, "{{\n"));
         for t in &types {
             try!(write!(w, "    "));
-            try!(render_method(w, t.item()));
+            try!(render_method(w, t));
             try!(write!(w, ";\n"));
         }
         if types.len() > 0 && required.len() > 0 {
@@ -1703,7 +1709,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         }
         for m in &required {
             try!(write!(w, "    "));
-            try!(render_method(w, m.item()));
+            try!(render_method(w, m));
             try!(write!(w, ";\n"));
         }
         if required.len() > 0 && provided.len() > 0 {
@@ -1711,7 +1717,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         }
         for m in &provided {
             try!(write!(w, "    "));
-            try!(render_method(w, m.item()));
+            try!(render_method(w, m));
             try!(write!(w, " {{ ... }}\n"));
         }
         try!(write!(w, "}}"));
@@ -1721,15 +1727,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     // Trait documentation
     try!(document(w, it));
 
-    fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitMethod)
+    fn trait_item(w: &mut fmt::Formatter, m: &clean::Item)
                   -> fmt::Result {
         try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>",
-                    shortty(m.item()),
-                    *m.item().name.as_ref().unwrap(),
-                    ConciseStability(&m.item().stability)));
-        try!(render_method(w, m.item()));
+                    shortty(m),
+                    *m.name.as_ref().unwrap(),
+                    ConciseStability(&m.stability)));
+        try!(render_method(w, m));
         try!(write!(w, "</code></h3>"));
-        try!(document(w, m.item()));
+        try!(document(w, m));
         Ok(())
     }
 
@@ -1798,12 +1804,14 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
 }
 
 fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
-              typ: &clean::TyParam) -> fmt::Result {
+              bounds: &Vec<clean::TyParamBound>,
+              default: &Option<clean::Type>)
+              -> fmt::Result {
     try!(write!(w, "type {}", it.name.as_ref().unwrap()));
-    if typ.bounds.len() > 0 {
-        try!(write!(w, ": {}", TyParamBounds(&*typ.bounds)))
+    if bounds.len() > 0 {
+        try!(write!(w, ": {}", TyParamBounds(bounds)))
     }
-    if let Some(ref default) = typ.default {
+    if let Some(ref default) = *default {
         try!(write!(w, " = {}", default));
     }
     Ok(())
@@ -1839,8 +1847,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
         clean::MethodItem(ref m) => {
             method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl)
         }
-        clean::AssociatedTypeItem(ref typ) => {
-            assoc_type(w, meth, typ)
+        clean::AssociatedTypeItem(ref bounds, ref default) => {
+            assoc_type(w, meth, bounds, default)
         }
         _ => panic!("render_method called on non-method")
     }
@@ -2138,13 +2146,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
                 try!(write!(w, "type {} = {}", name, tydef.type_));
                 try!(write!(w, "</code></h4>\n"));
             }
-            clean::AssociatedTypeItem(ref typaram) => {
+            clean::AssociatedTypeItem(ref bounds, ref default) => {
                 let name = item.name.as_ref().unwrap();
                 try!(write!(w, "<h4 id='assoc_type.{}' class='{}'>{}<code>",
                             *name,
                             shortty(item),
                             ConciseStability(&item.stability)));
-                try!(assoc_type(w, item, typaram));
+                try!(assoc_type(w, item, bounds, default));
                 try!(write!(w, "</code></h4>\n"));
             }
             _ => panic!("can't make docs for trait item with name {:?}", item.name)
@@ -2167,13 +2175,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
                               t: &clean::Trait,
                               i: &clean::Impl) -> fmt::Result {
         for trait_item in &t.items {
-            let n = trait_item.item().name.clone();
+            let n = trait_item.name.clone();
             match i.items.iter().find(|m| { m.name == n }) {
                 Some(..) => continue,
                 None => {}
             }
 
-            try!(doctraititem(w, trait_item.item(), false));
+            try!(doctraititem(w, trait_item, false));
         }
         Ok(())
     }
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 47918ba78a2..0726a822b59 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -20,8 +20,8 @@ use syntax::attr::{Unstable, Stable};
 use syntax::ast::Public;
 
 use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
-use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
-use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
+use clean::{ImplItem, Impl, Trait, TraitItem};
+use clean::{ExternCrateItem, ImportItem, PrimitiveItem, Stability};
 
 use html::render::cache;
 
@@ -140,11 +140,11 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
     // considered to have no children.
     match item.inner {
         // Require explicit `pub` to be visible
-        ImplItem(Impl { items: ref subitems, trait_: None, .. }) => {
-            let subcounts = subitems.iter().filter(|i| visible(*i))
-                                           .map(summarize_item)
-                                           .map(|s| s.0)
-                                           .fold(Counts::zero(), |acc, x| acc + x);
+        ImplItem(Impl { ref items, trait_: None, .. }) => {
+            let subcounts = items.iter().filter(|i| visible(*i))
+                                        .map(summarize_item)
+                                        .map(|s| s.0)
+                                        .fold(Counts::zero(), |acc, x| acc + x);
             (subcounts, None)
         }
         // `pub` automatically
@@ -154,22 +154,10 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
                                            .fold(Counts::zero(), |acc, x| acc + x);
             (item_counts + subcounts, None)
         }
-        TraitItem(Trait {
-            items: ref trait_items,
-            ..
-        }) => {
-            fn extract_item<'a>(trait_item: &'a TraitMethod) -> &'a Item {
-                match *trait_item {
-                    ProvidedMethod(ref item) |
-                    RequiredMethod(ref item) |
-                    TypeTraitItem(ref item) => item
-                }
-            }
-            let subcounts = trait_items.iter()
-                                       .map(extract_item)
-                                       .map(summarize_item)
-                                       .map(|s| s.0)
-                                       .fold(Counts::zero(), |acc, x| acc + x);
+        TraitItem(Trait { ref items, .. }) => {
+            let subcounts = items.iter().map(summarize_item)
+                                        .map(|s| s.0)
+                                        .fold(Counts::zero(), |acc, x| acc + x);
             (item_counts + subcounts, None)
         }
         ModuleItem(Module { ref items, .. }) => {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 550ce3bb8c8..657ffcaece9 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -22,7 +22,7 @@ pub use self::Expr_::*;
 pub use self::FloatTy::*;
 pub use self::FunctionRetTy::*;
 pub use self::ForeignItem_::*;
-pub use self::ImplItem::*;
+pub use self::ImplItem_::*;
 pub use self::InlinedItem::*;
 pub use self::IntTy::*;
 pub use self::Item_::*;
@@ -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_::*;
@@ -44,7 +43,7 @@ pub use self::Stmt_::*;
 pub use self::StrStyle::*;
 pub use self::StructFieldKind::*;
 pub use self::TokenTree::*;
-pub use self::TraitItem::*;
+pub use self::TraitItem_::*;
 pub use self::Ty_::*;
 pub use self::TyParamBound::*;
 pub use self::UintTy::*;
@@ -1058,20 +1057,15 @@ pub struct TypeField {
     pub span: Span,
 }
 
-/// Represents a required method in a trait declaration,
-/// one without a default implementation
+/// Represents a method's signature in a trait declaration,
+/// or in an implementation.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TypeMethod {
-    pub ident: Ident,
-    pub attrs: Vec<Attribute>,
+pub struct MethodSig {
     pub unsafety: Unsafety,
     pub abi: Abi,
     pub decl: P<FnDecl>,
     pub generics: Generics,
     pub explicit_self: ExplicitSelf,
-    pub id: NodeId,
-    pub span: Span,
-    pub vis: Visibility,
 }
 
 /// Represents a method declaration in a trait declaration, possibly including
@@ -1079,32 +1073,35 @@ pub struct TypeMethod {
 /// doesn't have an implementation, just a signature) or provided (meaning it
 /// has a default implementation).
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitItem {
-    RequiredMethod(TypeMethod),
-    ProvidedMethod(P<Method>),
-    TypeTraitItem(P<AssociatedType>),
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum ImplItem {
-    MethodImplItem(P<Method>),
-    TypeImplItem(P<Typedef>),
+pub struct TraitItem {
+    pub id: NodeId,
+    pub ident: Ident,
+    pub attrs: Vec<Attribute>,
+    pub node: TraitItem_,
+    pub span: Span,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct AssociatedType {
-    pub attrs: Vec<Attribute>,
-    pub ty_param: TyParam,
+pub enum TraitItem_ {
+    MethodTraitItem(MethodSig, Option<P<Block>>),
+    TypeTraitItem(TyParamBounds, Option<P<Ty>>),
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Typedef {
+pub struct ImplItem {
     pub id: NodeId,
-    pub span: Span,
     pub ident: Ident,
     pub vis: Visibility,
     pub attrs: Vec<Attribute>,
-    pub typ: P<Ty>,
+    pub node: ImplItem_,
+    pub span: Span,
+}
+
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum ImplItem_ {
+    MethodImplItem(MethodSig, P<Block>),
+    TypeImplItem(P<Ty>),
+    MacImplItem(Mac),
 }
 
 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
@@ -1419,29 +1416,6 @@ pub enum ExplicitSelf_ {
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Method {
-    pub attrs: Vec<Attribute>,
-    pub id: NodeId,
-    pub span: Span,
-    pub node: Method_,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Method_ {
-    /// Represents a method declaration
-    MethDecl(Ident,
-             Generics,
-             Abi,
-             ExplicitSelf,
-             Unsafety,
-             P<FnDecl>,
-             P<Block>,
-             Visibility),
-    /// 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
@@ -1659,7 +1633,7 @@ pub enum Item_ {
     ItemTrait(Unsafety,
               Generics,
               TyParamBounds,
-              Vec<TraitItem>),
+              Vec<P<TraitItem>>),
 
     // Default trait implementations
     // `impl Trait for ..`
@@ -1669,7 +1643,7 @@ pub enum Item_ {
              Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
-             Vec<ImplItem>),
+             Vec<P<ImplItem>>),
     /// A macro invocation (which includes macro definition)
     ItemMac(Mac),
 }
@@ -1726,8 +1700,8 @@ impl ForeignItem_ {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum InlinedItem {
     IIItem(P<Item>),
-    IITraitItem(DefId /* impl id */, TraitItem),
-    IIImplItem(DefId /* impl id */, ImplItem),
+    IITraitItem(DefId /* impl id */, P<TraitItem>),
+    IIImplItem(DefId /* impl id */, P<ImplItem>),
     IIForeign(P<ForeignItem>),
 }
 
diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
index 1a537c7a5b8..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 { 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_fn_decl(),
+                    |_, _, sig: &'a ast::MethodSig, _, _|  &sig.decl,
                     |c: ClosureParts<'a>| c.decl)
     }
 
     pub fn span(self) -> Span {
         self.handle(|i: ItemFnParts|     i.span,
-                    |m: &'a ast::Method| m.span,
+                    |_, _, _: &'a ast::MethodSig, _, span| span,
                     |c: ClosureParts|    c.span)
     }
 
     pub fn id(self) -> NodeId {
         self.handle(|i: ItemFnParts|     i.id,
-                    |m: &'a ast::Method| m.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 = |m: &'a ast::Method| {
-            visit::FkMethod(m.pe_ident(), m.pe_generics(), 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(&'a ast::Method) -> A,
+        M: FnOnce(NodeId, ast::Ident, &'a ast::MethodSig, &'a ast::Block, Span) -> A,
         C: FnOnce(ClosureParts<'a>) -> A,
     {
         match self.node {
@@ -205,14 +204,19 @@ impl<'a> FnLikeNode<'a> {
                     }),
                 _ => panic!("item FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeTraitItem(t) => match *t {
-                ast::ProvidedMethod(ref m) => method(&**m),
+            ast_map::NodeTraitItem(ti) => match ti.node {
+                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 {
-                    ast::MethodImplItem(ref m) => method(&**m),
-                    ast::TypeImplItem(_) => {
+                match ii.node {
+                    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 b96d735d92d..48bb044cb18 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -19,7 +19,6 @@ use codemap::{DUMMY_SP, Span, Spanned};
 use fold::Folder;
 use parse::token;
 use print::pprust;
-use ptr::P;
 use visit::{self, Visitor};
 
 use arena::TypedArena;
@@ -375,35 +374,8 @@ impl<'ast> Map<'ast> {
                 }
             }
             NodeForeignItem(i) => PathName(i.ident.name),
-            NodeImplItem(ii) => {
-                match *ii {
-                    MethodImplItem(ref m) => {
-                        match m.node {
-                            MethDecl(ident, _, _, _, _, _, _, _) => {
-                                PathName(ident.name)
-                            }
-                            MethMac(_) => {
-                                panic!("no path elem for {:?}", node)
-                            }
-                        }
-                    }
-                    TypeImplItem(ref t) => PathName(t.ident.name),
-                }
-            },
-            NodeTraitItem(tm) => match *tm {
-                RequiredMethod(ref m) => PathName(m.ident.name),
-                ProvidedMethod(ref m) => {
-                    match m.node {
-                        MethDecl(ident, _, _, _, _, _, _, _) => {
-                            PathName(ident.name)
-                        }
-                        MethMac(_) => panic!("no path elem for {:?}", node),
-                    }
-                }
-                TypeTraitItem(ref m) => {
-                    PathName(m.ty_param.ident.name)
-                }
-            },
+            NodeImplItem(ii) => PathName(ii.ident.name),
+            NodeTraitItem(ti) => PathName(ti.ident.name),
             NodeVariant(v) => PathName(v.node.name.name),
             _ => panic!("no path elem for {:?}", node)
         }
@@ -459,21 +431,12 @@ impl<'ast> Map<'ast> {
 
     /// Given a node ID, get a list of of attributes associated with the AST
     /// corresponding to the Node ID
-    pub fn attrs(&self, id: NodeId) -> &[Attribute] {
+    pub fn attrs(&self, id: NodeId) -> &'ast [Attribute] {
         let attrs = match self.find(id) {
             Some(NodeItem(i)) => Some(&i.attrs[..]),
             Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]),
-            Some(NodeTraitItem(ref tm)) => match **tm {
-                RequiredMethod(ref type_m) => Some(&type_m.attrs[..]),
-                ProvidedMethod(ref m) => Some(&m.attrs[..]),
-                TypeTraitItem(ref typ) => Some(&typ.attrs[..]),
-            },
-            Some(NodeImplItem(ref ii)) => {
-                match **ii {
-                    MethodImplItem(ref m) => Some(&m.attrs[..]),
-                    TypeImplItem(ref t) => Some(&t.attrs[..]),
-                }
-            }
+            Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]),
+            Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]),
             Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
@@ -506,19 +469,8 @@ impl<'ast> Map<'ast> {
         let sp = match self.find(id) {
             Some(NodeItem(item)) => item.span,
             Some(NodeForeignItem(foreign_item)) => foreign_item.span,
-            Some(NodeTraitItem(trait_method)) => {
-                match *trait_method {
-                    RequiredMethod(ref type_method) => type_method.span,
-                    ProvidedMethod(ref method) => method.span,
-                    TypeTraitItem(ref typedef) => typedef.ty_param.span,
-                }
-            }
-            Some(NodeImplItem(ref impl_item)) => {
-                match **impl_item {
-                    MethodImplItem(ref method) => method.span,
-                    TypeImplItem(ref typedef) => typedef.span,
-                }
-            }
+            Some(NodeTraitItem(trait_method)) => trait_method.span,
+            Some(NodeImplItem(ref impl_item)) => impl_item.span,
             Some(NodeVariant(variant)) => variant.span,
             Some(NodeExpr(expr)) => expr.span,
             Some(NodeStmt(stmt)) => stmt.span,
@@ -651,31 +603,8 @@ impl<T:Named> Named for Spanned<T> { fn name(&self) -> Name { self.node.name() }
 impl Named for Item { fn name(&self) -> Name { self.ident.name } }
 impl Named for ForeignItem { fn name(&self) -> Name { self.ident.name } }
 impl Named for Variant_ { fn name(&self) -> Name { self.name.name } }
-impl Named for TraitItem {
-    fn name(&self) -> Name {
-        match *self {
-            RequiredMethod(ref tm) => tm.ident.name,
-            ProvidedMethod(ref m) => m.name(),
-            TypeTraitItem(ref at) => at.ty_param.ident.name,
-        }
-    }
-}
-impl Named for ImplItem {
-    fn name(&self) -> Name {
-        match *self {
-            MethodImplItem(ref m) => m.name(),
-            TypeImplItem(ref td) => td.ident.name,
-        }
-    }
-}
-impl Named for Method {
-    fn name(&self) -> Name {
-        match self.node {
-            MethDecl(i, _, _, _, _, _, _, _) => i.name,
-            MethMac(_) => panic!("encountered unexpanded method macro."),
-        }
-    }
-}
+impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
+impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
 
 pub trait FoldOps {
     fn new_id(&self, id: NodeId) -> NodeId {
@@ -740,15 +669,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
         self.parent = i.id;
         match i.node {
             ItemImpl(_, _, _, _, _, ref impl_items) => {
-                for impl_item in impl_items {
-                    match *impl_item {
-                        MethodImplItem(ref m) => {
-                            self.insert(m.id, NodeImplItem(impl_item));
-                        }
-                        TypeImplItem(ref t) => {
-                            self.insert(t.id, NodeImplItem(impl_item));
-                        }
-                    }
+                for ii in impl_items {
+                    self.insert(ii.id, NodeImplItem(ii));
                 }
             }
             ItemEnum(ref enum_definition, _) => {
@@ -777,18 +699,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
                     }
                 }
 
-                for tm in trait_items {
-                    match *tm {
-                        RequiredMethod(ref m) => {
-                            self.insert(m.id, NodeTraitItem(tm));
-                        }
-                        ProvidedMethod(ref m) => {
-                            self.insert(m.id, NodeTraitItem(tm));
-                        }
-                        TypeTraitItem(ref typ) => {
-                            self.insert(typ.ty_param.id, NodeTraitItem(tm));
-                        }
-                    }
+                for ti in trait_items {
+                    self.insert(ti.id, NodeTraitItem(ti));
                 }
             }
             _ => {}
@@ -797,6 +709,20 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
         self.parent = parent;
     }
 
+    fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
+        let parent = self.parent;
+        self.parent = ti.id;
+        visit::walk_trait_item(self, ti);
+        self.parent = parent;
+    }
+
+    fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
+        let parent = self.parent;
+        self.parent = ii.id;
+        visit::walk_impl_item(self, ii);
+        self.parent = parent;
+    }
+
     fn visit_pat(&mut self, pat: &'ast Pat) {
         self.insert(pat.id, match pat.node {
             // Note: this is at least *potentially* a pattern...
@@ -816,29 +742,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
         visit::walk_stmt(self, stmt);
     }
 
-    fn visit_ty_method(&mut self, m: &'ast TypeMethod) {
-        let parent = self.parent;
-        self.parent = m.id;
-        self.visit_fn_decl(&*m.decl);
-        visit::walk_ty_method(self, m);
-        self.parent = parent;
-    }
-
     fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl,
-                b: &'ast Block, s: Span, id: NodeId) {
-        match fk {
-            visit::FkMethod(..) => {
-                let parent = self.parent;
-                self.parent = id;
-                self.visit_fn_decl(fd);
-                visit::walk_fn(self, fk, fd, b, s);
-                self.parent = parent;
-            }
-            _ => {
-                self.visit_fn_decl(fd);
-                visit::walk_fn(self, fk, fd, b, s);
-            }
-        }
+                b: &'ast Block, s: Span, _: NodeId) {
+        self.visit_fn_decl(fd);
+        visit::walk_fn(self, fk, fd, b, s);
     }
 
     fn visit_ty(&mut self, ty: &'ast Ty) {
@@ -920,33 +827,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
     let mut fld = IdAndSpanUpdater { fold_ops: fold_ops };
     let ii = match ii {
         IIItem(i) => IIItem(fld.fold_item(i).expect_one("expected one item")),
-        IITraitItem(d, ti) => match ti {
-            ProvidedMethod(m) => {
-                IITraitItem(fld.fold_ops.new_def_id(d),
-                            ProvidedMethod(fld.fold_method(m)
-                                              .expect_one("expected one method")))
-            }
-            RequiredMethod(ty_m) => {
-                IITraitItem(fld.fold_ops.new_def_id(d),
-                            RequiredMethod(fld.fold_type_method(ty_m)))
-            }
-            TypeTraitItem(at) => {
-                IITraitItem(
-                    fld.fold_ops.new_def_id(d),
-                    TypeTraitItem(P(fld.fold_associated_type((*at).clone()))))
-            }
-        },
-        IIImplItem(d, m) => match m {
-            MethodImplItem(m) => {
-                IIImplItem(fld.fold_ops.new_def_id(d),
-                           MethodImplItem(fld.fold_method(m)
-                                             .expect_one("expected one method")))
-            }
-            TypeImplItem(t) => {
-                IIImplItem(fld.fold_ops.new_def_id(d),
-                           TypeImplItem(P(fld.fold_typedef((*t).clone()))))
-            }
-        },
+        IITraitItem(d, ti) => {
+            IITraitItem(fld.fold_ops.new_def_id(d),
+                        fld.fold_trait_item(ti).expect_one("expected one trait item"))
+        }
+        IIImplItem(d, ii) => {
+            IIImplItem(fld.fold_ops.new_def_id(d),
+                       fld.fold_impl_item(ii).expect_one("expected one impl item"))
+        }
         IIForeign(i) => IIForeign(fld.fold_foreign_item(i))
     };
 
@@ -968,25 +856,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
     // add it to the table now. Likewise with foreign items.
     match ii_parent.ii {
         IIItem(_) => {}
-        IITraitItem(_, ref trait_item) => {
-            let trait_item_id = match *trait_item {
-                ProvidedMethod(ref m) => m.id,
-                RequiredMethod(ref m) => m.id,
-                TypeTraitItem(ref ty) => ty.ty_param.id,
-            };
-
-            collector.insert(trait_item_id, NodeTraitItem(trait_item));
+        IITraitItem(_, ref ti) => {
+            collector.insert(ti.id, NodeTraitItem(ti));
         }
-        IIImplItem(_, ref impl_item) => {
-            let impl_item_id = match *impl_item {
-                MethodImplItem(ref m) => m.id,
-                TypeImplItem(ref ti) => ti.id,
-            };
-
-            collector.insert(impl_item_id, NodeImplItem(impl_item));
+        IIImplItem(_, ref ii) => {
+            collector.insert(ii.id, NodeImplItem(ii));
         }
         IIForeign(ref i) => {
-            collector.insert(i.id, NodeForeignItem(&**i));
+            collector.insert(i.id, NodeForeignItem(i));
         }
     }
     *map.map.borrow_mut() = collector.map;
@@ -1002,8 +879,8 @@ impl<'a> NodePrinter for pprust::State<'a> {
         match *node {
             NodeItem(a)        => self.print_item(&*a),
             NodeForeignItem(a) => self.print_foreign_item(&*a),
-            NodeTraitItem(a)   => self.print_trait_method(&*a),
-            NodeImplItem(a)    => self.print_impl_item(&*a),
+            NodeTraitItem(a)   => self.print_trait_item(a),
+            NodeImplItem(a)    => self.print_impl_item(a),
             NodeVariant(a)     => self.print_variant(&*a),
             NodeExpr(a)        => self.print_expr(&*a),
             NodeStmt(a)        => self.print_stmt(&*a),
@@ -1050,44 +927,38 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
             let path_str = map.path_to_str_with_ident(id, item.ident);
             format!("foreign item {}{}", path_str, id_str)
         }
-        Some(NodeImplItem(ref ii)) => {
-            match **ii {
-                MethodImplItem(ref m) => {
-                    match m.node {
-                        MethDecl(ident, _, _, _, _, _, _, _) =>
-                            format!("method {} in {}{}",
-                                    token::get_ident(ident),
-                                    map.path_to_string(id), id_str),
-                        MethMac(ref mac) =>
-                            format!("method macro {}{}",
-                                    pprust::mac_to_string(mac), id_str)
-                    }
-                }
-                TypeImplItem(ref t) => {
-                    format!("typedef {} in {}{}",
-                            token::get_ident(t.ident),
-                            map.path_to_string(id),
-                            id_str)
-                }
-            }
-        }
-        Some(NodeTraitItem(ref tm)) => {
-            match **tm {
-                RequiredMethod(_) | ProvidedMethod(_) => {
-                    let m = ast_util::trait_item_to_ty_method(&**tm);
+        Some(NodeImplItem(ii)) => {
+            match ii.node {
+                MethodImplItem(..) => {
                     format!("method {} in {}{}",
-                            token::get_ident(m.ident),
-                            map.path_to_string(id),
-                            id_str)
+                            token::get_ident(ii.ident),
+                            map.path_to_string(id), id_str)
                 }
-                TypeTraitItem(ref t) => {
-                    format!("type item {} in {}{}",
-                            token::get_ident(t.ty_param.ident),
+                TypeImplItem(_) => {
+                    format!("assoc type {} in {}{}",
+                            token::get_ident(ii.ident),
                             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 {
+                MethodTraitItem(..) => "trait method",
+                TypeTraitItem(..) => "assoc type",
+//                 ConstTraitItem(..) => "assoc constant"
+            };
+
+            format!("{} {} in {}{}",
+                    kind,
+                    token::get_ident(ti.ident),
+                    map.path_to_string(id),
+                    id_str)
+        }
         Some(NodeVariant(ref variant)) => {
             format!("variant {} in {}{}",
                     token::get_ident(variant.node.name),
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 26d7562cdb2..cec824e79ff 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use abi::Abi;
 use ast::*;
 use ast;
 use ast_util;
@@ -268,62 +267,6 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident
     token::gensym_ident(&pretty[..])
 }
 
-pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
-    match method.node {
-        MethDecl(ident,
-                 ref generics,
-                 abi,
-                 ref explicit_self,
-                 unsafety,
-                 ref decl,
-                 _,
-                 vis) => {
-            TypeMethod {
-                ident: ident,
-                attrs: method.attrs.clone(),
-                unsafety: unsafety,
-                decl: (*decl).clone(),
-                generics: generics.clone(),
-                explicit_self: (*explicit_self).clone(),
-                id: method.id,
-                span: method.span,
-                vis: vis,
-                abi: abi,
-            }
-        },
-        MethMac(_) => panic!("expected non-macro method declaration")
-    }
-}
-
-/// extract a TypeMethod from a TraitItem. if the TraitItem is
-/// a default, pull out the useful fields to make a TypeMethod
-//
-// NB: to be used only after expansion is complete, and macros are gone.
-pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod {
-    match *method {
-        RequiredMethod(ref m) => (*m).clone(),
-        ProvidedMethod(ref m) => trait_method_to_ty_method(&**m),
-        TypeTraitItem(_) => {
-            panic!("trait_method_to_ty_method(): expected method but found \
-                   typedef")
-        }
-    }
-}
-
-pub fn split_trait_methods(trait_methods: &[TraitItem])
-                           -> (Vec<TypeMethod>, Vec<P<Method>> ) {
-    let mut reqd = Vec::new();
-    let mut provd = Vec::new();
-    for trt_method in trait_methods {
-        match *trt_method {
-            RequiredMethod(ref tm) => reqd.push((*tm).clone()),
-            ProvidedMethod(ref m) => provd.push((*m).clone()),
-            TypeTraitItem(_) => {}
-        }
-    };
-    (reqd, provd)
-}
-
 pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
     match field.node.kind {
         ast::NamedField(_, v) | ast::UnnamedField(v) => v
@@ -513,10 +456,12 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
         self.operation.visit_id(node_id);
 
         match function_kind {
-            visit::FkItemFn(_, generics, _, _) |
-            visit::FkMethod(_, generics, _) => {
+            visit::FkItemFn(_, generics, _, _) => {
                 self.visit_generics_helper(generics)
             }
+            visit::FkMethod(_, sig) => {
+                self.visit_generics_helper(&sig.generics)
+            }
             visit::FkFnBlock => {}
         }
 
@@ -552,13 +497,14 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
         visit::walk_struct_def(self, struct_def);
     }
 
-    fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
-        match *tm {
-            ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
-            ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
-            ast::TypeTraitItem(ref typ) => self.operation.visit_id(typ.ty_param.id),
-        }
-        visit::walk_trait_item(self, tm);
+    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+        self.operation.visit_id(ti.id);
+        visit::walk_trait_item(self, ti);
+    }
+
+    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+        self.operation.visit_id(ii.id);
+        visit::walk_impl_item(self, ii);
     }
 
     fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) {
@@ -701,52 +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_ident(&self) -> ast::Ident;
-    fn pe_generics<'a>(&'a self) -> &'a ast::Generics;
-    fn pe_abi(&self) -> Abi;
-    fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf;
-    fn pe_unsafety(&self) -> ast::Unsafety;
-    fn pe_fn_decl<'a>(&'a self) -> &'a ast::FnDecl;
-    fn pe_body<'a>(&'a self) -> &'a ast::Block;
-    fn pe_vis(&self) -> ast::Visibility;
-}
-
-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.node {
-                $field_pat => $result,
-                MethMac(_) => {
-                    panic!("expected an AST without macro invocations");
-                }
-            }
-        }
-    }
-}
-
-
-impl PostExpansionMethod for Method {
-    mf_method! { pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_,_),ident }
-    mf_method! {
-        pe_generics,&'a ast::Generics,
-        MethDecl(_,ref generics,_,_,_,_,_,_),generics
-    }
-    mf_method! { pe_abi,Abi,MethDecl(_,_,abi,_,_,_,_,_),abi }
-    mf_method! {
-        pe_explicit_self,&'a ast::ExplicitSelf,
-        MethDecl(_,_,_,ref explicit_self,_,_,_,_),explicit_self
-    }
-    mf_method! { pe_unsafety,ast::Unsafety,MethDecl(_,_,_,_,unsafety,_,_,_),unsafety }
-    mf_method! { pe_fn_decl,&'a ast::FnDecl,MethDecl(_,_,_,_,_,ref decl,_,_),&**decl }
-    mf_method! { pe_body,&'a ast::Block,MethDecl(_,_,_,_,_,_,ref body,_),&**body }
-    mf_method! { pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,_,vis),vis }
-}
-
 #[cfg(test)]
 mod test {
     use ast::*;
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index dfe3477bddc..489a7721d7b 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -118,13 +118,13 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
     let item = match item {
         ast::ItemImpl(u, o, a, b, c, impl_items) => {
             let impl_items = impl_items.into_iter()
-                                       .filter(|ii| impl_item_in_cfg(cx, ii))
+                                       .filter(|ii| (cx.in_cfg)(&ii.attrs))
                                        .collect();
             ast::ItemImpl(u, o, a, b, c, impl_items)
         }
         ast::ItemTrait(u, a, b, methods) => {
             let methods = methods.into_iter()
-                                 .filter(|m| trait_method_in_cfg(cx, m))
+                                 .filter(|ti| (cx.in_cfg)(&ti.attrs))
                                  .collect();
             ast::ItemTrait(u, a, b, methods)
         }
@@ -246,25 +246,6 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool
     return (cx.in_cfg)(&item.attrs);
 }
 
-fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
-    F: FnMut(&[ast::Attribute]) -> bool
-{
-    match *meth {
-        ast::RequiredMethod(ref meth) => (cx.in_cfg)(&meth.attrs),
-        ast::ProvidedMethod(ref meth) => (cx.in_cfg)(&meth.attrs),
-        ast::TypeTraitItem(ref typ) => (cx.in_cfg)(&typ.attrs),
-    }
-}
-
-fn impl_item_in_cfg<F>(cx: &mut Context<F>, impl_item: &ast::ImplItem) -> bool where
-    F: FnMut(&[ast::Attribute]) -> bool
-{
-    match *impl_item {
-        ast::MethodImplItem(ref meth) => (cx.in_cfg)(&meth.attrs),
-        ast::TypeImplItem(ref typ) => (cx.in_cfg)(&typ.attrs),
-    }
-}
-
 // Determine if an item should be translated in the current crate
 // configuration based on the item's attributes
 fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 8aeafe419da..35449bde0b2 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -77,51 +77,31 @@ impl<F> ItemModifier for F
 #[derive(Debug,Clone)]
 pub enum Annotatable {
     Item(P<ast::Item>),
-    TraitItem(ast::TraitItem),
-    ImplItem(ast::ImplItem),
+    TraitItem(P<ast::TraitItem>),
+    ImplItem(P<ast::ImplItem>),
 }
 
 impl Annotatable {
     pub fn attrs(&self) -> &[ast::Attribute] {
         match *self {
             Annotatable::Item(ref i) => &i.attrs,
-            Annotatable::TraitItem(ref i) => match *i {
-                ast::TraitItem::RequiredMethod(ref tm) => &tm.attrs,
-                ast::TraitItem::ProvidedMethod(ref m) => &m.attrs,
-                ast::TraitItem::TypeTraitItem(ref at) => &at.attrs,
-            },
-            Annotatable::ImplItem(ref i) => match *i {
-                ast::ImplItem::MethodImplItem(ref m) => &m.attrs,
-                ast::ImplItem::TypeImplItem(ref t) => &t.attrs,
-            }
+            Annotatable::TraitItem(ref ti) => &ti.attrs,
+            Annotatable::ImplItem(ref ii) => &ii.attrs,
         }
     }
 
     pub fn fold_attrs(self, attrs: Vec<ast::Attribute>) -> Annotatable {
         match self {
-            Annotatable::Item(i) => Annotatable::Item(P(ast::Item {
+            Annotatable::Item(i) => Annotatable::Item(i.map(|i| ast::Item {
                 attrs: attrs,
-                ..(*i).clone()
+                ..i
+            })),
+            Annotatable::TraitItem(i) => Annotatable::TraitItem(i.map(|ti| {
+                ast::TraitItem { attrs: attrs, ..ti }
+            })),
+            Annotatable::ImplItem(i) => Annotatable::ImplItem(i.map(|ii| {
+                ast::ImplItem { attrs: attrs, ..ii }
             })),
-            Annotatable::TraitItem(i) => match i {
-                ast::TraitItem::RequiredMethod(tm) => Annotatable::TraitItem(
-                    ast::TraitItem::RequiredMethod(
-                        ast::TypeMethod { attrs: attrs, ..tm })),
-                ast::TraitItem::ProvidedMethod(m) => Annotatable::TraitItem(
-                    ast::TraitItem::ProvidedMethod(P(
-                        ast::Method { attrs: attrs, ..(*m).clone() }))),
-                ast::TraitItem::TypeTraitItem(at) => Annotatable::TraitItem(
-                    ast::TraitItem::TypeTraitItem(P(
-                        ast::AssociatedType { attrs: attrs, ..(*at).clone() }))),
-            },
-            Annotatable::ImplItem(i) => match i {
-                ast::ImplItem::MethodImplItem(m) => Annotatable::ImplItem(
-                    ast::ImplItem::MethodImplItem(P(
-                        ast::Method { attrs: attrs, ..(*m).clone() }))),
-                ast::ImplItem::TypeImplItem(t) => Annotatable::ImplItem(
-                    ast::ImplItem::TypeImplItem(P(
-                        ast::Typedef { attrs: attrs, ..(*t).clone() }))),
-            }
         }
     }
 
@@ -132,14 +112,14 @@ impl Annotatable {
         }
     }
 
-    pub fn expect_trait_item(self) -> ast::TraitItem {
+    pub fn expect_trait_item(self) -> P<ast::TraitItem> {
         match self {
             Annotatable::TraitItem(i) => i,
             _ => panic!("expected Item")
         }
     }
 
-    pub fn expect_impl_item(self) -> ast::ImplItem {
+    pub fn expect_impl_item(self) -> P<ast::ImplItem> {
         match self {
             Annotatable::ImplItem(i) => i,
             _ => panic!("expected Item")
@@ -248,8 +228,8 @@ pub trait MacResult {
         None
     }
 
-    /// Create zero or more methods.
-    fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> {
+    /// Create zero or more impl items.
+    fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
         None
     }
 
@@ -295,7 +275,7 @@ make_MacEager! {
     expr: P<ast::Expr>,
     pat: P<ast::Pat>,
     items: SmallVector<P<ast::Item>>,
-    methods: SmallVector<P<ast::Method>>,
+    impl_items: SmallVector<P<ast::ImplItem>>,
     stmt: P<ast::Stmt>,
 }
 
@@ -308,8 +288,8 @@ impl MacResult for MacEager {
         self.items
     }
 
-    fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> {
-        self.methods
+    fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
+        self.impl_items
     }
 
     fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> {
@@ -397,7 +377,7 @@ impl MacResult for DummyResult {
             Some(SmallVector::zero())
         }
     }
-    fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::Method>>> {
+    fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> {
         if self.expr_only {
             None
         } else {
@@ -505,9 +485,6 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
         syntax_expanders.insert(intern("quote_ty"),
                            builtin_normal_expander(
                                 ext::quote::expand_quote_ty));
-        syntax_expanders.insert(intern("quote_method"),
-                           builtin_normal_expander(
-                                ext::quote::expand_quote_method));
         syntax_expanders.insert(intern("quote_item"),
                            builtin_normal_expander(
                                 ext::quote::expand_quote_item));
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index 9cd965a8138..58b6d96607d 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -386,22 +386,22 @@ impl<'a> TraitDef<'a> {
                            cx: &mut ExtCtxt,
                            type_ident: Ident,
                            generics: &Generics,
-                           methods: Vec<P<ast::Method>>) -> P<ast::Item> {
+                           methods: Vec<P<ast::ImplItem>>) -> P<ast::Item> {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
-        // Transform associated types from `deriving::ty::Ty` into `ast::Typedef`
+        // Transform associated types from `deriving::ty::Ty` into `ast::ImplItem`
         let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| {
-            P(ast::Typedef {
+            P(ast::ImplItem {
                 id: ast::DUMMY_NODE_ID,
                 span: self.span,
                 ident: ident,
                 vis: ast::Inherited,
                 attrs: Vec::new(),
-                typ: type_def.to_ty(cx,
+                node: ast::TypeImplItem(type_def.to_ty(cx,
                     self.span,
                     type_ident,
                     generics
-                ),
+                )),
             })
         });
 
@@ -510,14 +510,7 @@ impl<'a> TraitDef<'a> {
                           trait_generics,
                           opt_trait_ref,
                           self_type,
-                          methods.into_iter()
-                                 .map(|method| {
-                                     ast::MethodImplItem(method)
-                                 }).chain(
-                                     associated_types.map(|type_| {
-                                         ast::TypeImplItem(type_)
-                                     })
-                                 ).collect()))
+                          methods.into_iter().chain(associated_types).collect()))
     }
 
     fn expand_struct_def(&self,
@@ -702,7 +695,7 @@ impl<'a> MethodDef<'a> {
                      abi: Abi,
                      explicit_self: ast::ExplicitSelf,
                      arg_types: Vec<(Ident, P<ast::Ty>)> ,
-                     body: P<Expr>) -> P<ast::Method> {
+                     body: P<Expr>) -> P<ast::ImplItem> {
         // create the generics that aren't for Self
         let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
 
@@ -725,18 +718,19 @@ impl<'a> MethodDef<'a> {
         let body_block = cx.block_expr(body);
 
         // Create the method.
-        P(ast::Method {
-            attrs: self.attributes.clone(),
+        P(ast::ImplItem {
             id: ast::DUMMY_NODE_ID,
+            attrs: self.attributes.clone(),
             span: trait_.span,
-            node: ast::MethDecl(method_ident,
-                                fn_generics,
-                                abi,
-                                explicit_self,
-                                ast::Unsafety::Normal,
-                                fn_decl,
-                                body_block,
-                                ast::Inherited)
+            vis: ast::Inherited,
+            ident: method_ident,
+            node: ast::MethodImplItem(ast::MethodSig {
+                generics: fn_generics,
+                abi: abi,
+                explicit_self: explicit_self,
+                unsafety: ast::Unsafety::Normal,
+                decl: fn_decl
+            }, body_block)
         })
     }
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 6883395933e..ee2cf9017bb 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1174,29 +1174,26 @@ fn expand_annotatable(a: Annotatable,
                 noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect()
             }
         },
-        Annotatable::TraitItem(it) => match it {
-            ast::TraitItem::ProvidedMethod(m) => {
-                expand_method(m, fld).into_iter().map(|m|
-                    Annotatable::TraitItem(ast::TraitItem::ProvidedMethod(m))).collect()
-            }
-            ast::TraitItem::RequiredMethod(m) => {
-                SmallVector::one(Annotatable::TraitItem(
-                    ast::TraitItem::RequiredMethod(fld.fold_type_method(m))))
-            }
-            ast::TraitItem::TypeTraitItem(t) => {
-                SmallVector::one(Annotatable::TraitItem(
-                    ast::TraitItem::TypeTraitItem(P(fld.fold_associated_type((*t).clone())))))
-            }
-        },
-        Annotatable::ImplItem(it) => match it {
-            ast::ImplItem::MethodImplItem(m) => {
-                expand_method(m, fld).into_iter().map(|m|
-                    Annotatable::ImplItem(ast::ImplItem::MethodImplItem(m))).collect()
-            }
-            ast::ImplItem::TypeImplItem(t) => {
-                SmallVector::one(Annotatable::ImplItem(
-                    ast::ImplItem::TypeImplItem(P(fld.fold_typedef((*t).clone())))))
-            }
+
+        Annotatable::TraitItem(it) => match it.node {
+            ast::MethodTraitItem(_, Some(_)) => SmallVector::one(it.map(|ti| ast::TraitItem {
+                id: ti.id,
+                ident: ti.ident,
+                attrs: ti.attrs,
+                node: match ti.node  {
+                    ast::MethodTraitItem(sig, Some(body)) => {
+                        let (sig, body) = expand_and_rename_method(sig, body, fld);
+                        ast::MethodTraitItem(sig, Some(body))
+                    }
+                    _ => unreachable!()
+                },
+                span: fld.new_span(ti.span)
+            })),
+            _ => fold::noop_fold_trait_item(it, fld)
+        }.into_iter().map(Annotatable::TraitItem).collect(),
+
+        Annotatable::ImplItem(ii) => {
+            expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect()
         }
     };
 
@@ -1204,21 +1201,6 @@ fn expand_annotatable(a: Annotatable,
     new_items
 }
 
-fn expand_trait_item(i: ast::TraitItem,
-                     fld: &mut MacroExpander)
-                     -> SmallVector<ast::TraitItem> {
-    expand_annotatable(Annotatable::TraitItem(i), fld)
-        .into_iter().map(|i| i.expect_trait_item()).collect()
-
-}
-
-fn expand_impl_item(i: ast::ImplItem,
-                    fld: &mut MacroExpander)
-                    -> SmallVector<ast::ImplItem> {
-    expand_annotatable(Annotatable::ImplItem(i), fld)
-        .into_iter().map(|i| i.expect_impl_item()).collect()
-}
-
 // partition the attributes into ItemModifiers and others
 fn modifiers(attrs: &Vec<ast::Attribute>,
              fld: &MacroExpander)
@@ -1292,54 +1274,48 @@ fn expand_item_multi_modifier(mut it: Annotatable,
     expand_item_multi_modifier(it, fld)
 }
 
-// expand a method
-fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<ast::Method>> {
-    m.and_then(|m| match m.node {
-        ast::MethDecl(ident,
-                      generics,
-                      abi,
-                      explicit_self,
-                      fn_style,
-                      decl,
-                      body,
-                      vis) => {
-            let id = fld.new_id(m.id);
-            let (rewritten_fn_decl, rewritten_body)
-                = expand_and_rename_fn_decl_and_block(decl, body, fld);
-            SmallVector::one(P(ast::Method {
-                    attrs: fold::fold_attrs(m.attrs, fld),
-                    id: id,
-                    span: fld.new_span(m.span),
-                    node: ast::MethDecl(fld.fold_ident(ident),
-                                        noop_fold_generics(generics, fld),
-                                        abi,
-                                        fld.fold_explicit_self(explicit_self),
-                                        fn_style,
-                                        rewritten_fn_decl,
-                                        rewritten_body,
-                                        vis)
-                }))
-        },
-        ast::MethMac(mac) => {
-            let maybe_new_methods =
-                expand_mac_invoc(mac, m.span,
-                                 |r| r.make_methods(),
-                                 |meths, mark| meths.move_map(|m| mark_method(m, mark)),
+fn expand_impl_item(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
+                 -> SmallVector<P<ast::ImplItem>> {
+    match ii.node {
+        ast::MethodImplItem(..) => SmallVector::one(ii.map(|ii| ast::ImplItem {
+            id: ii.id,
+            ident: ii.ident,
+            attrs: ii.attrs,
+            vis: ii.vis,
+            node: match ii.node  {
+                ast::MethodImplItem(sig, body) => {
+                    let (sig, body) = expand_and_rename_method(sig, body, fld);
+                    ast::MethodImplItem(sig, body)
+                }
+                _ => unreachable!()
+            },
+            span: fld.new_span(ii.span)
+        })),
+        ast::MacImplItem(_) => {
+            let (span, mac) = ii.and_then(|ii| match ii.node {
+                ast::MacImplItem(mac) => (ii.span, mac),
+                _ => unreachable!()
+            });
+            let maybe_new_items =
+                expand_mac_invoc(mac, span,
+                                 |r| r.make_impl_items(),
+                                 |meths, mark| meths.move_map(|m| mark_impl_item(m, mark)),
                                  fld);
 
-            match maybe_new_methods {
-                Some(methods) => {
+            match maybe_new_items {
+                Some(impl_items) => {
                     // expand again if necessary
-                    let new_methods = methods.into_iter()
-                                             .flat_map(|m| fld.fold_method(m).into_iter())
-                                             .collect();
+                    let new_items = impl_items.into_iter().flat_map(|ii| {
+                        expand_impl_item(ii, fld).into_iter()
+                    }).collect();
                     fld.cx.bt_pop();
-                    new_methods
+                    new_items
                 }
                 None => SmallVector::zero()
             }
         }
-    })
+        _ => fold::noop_fold_impl_item(ii, fld)
+    }
 }
 
 /// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
@@ -1347,7 +1323,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as
 /// the block, returning both the new FnDecl and the new Block.
 fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Block>,
                                        fld: &mut MacroExpander)
-    -> (P<ast::FnDecl>, P<ast::Block>) {
+                                       -> (P<ast::FnDecl>, P<ast::Block>) {
     let expanded_decl = fld.fold_fn_decl(fn_decl);
     let idents = fn_decl_arg_bindings(&*expanded_decl);
     let renames =
@@ -1361,6 +1337,20 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl
     (rewritten_fn_decl,rewritten_body)
 }
 
+fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
+                            fld: &mut MacroExpander)
+                            -> (ast::MethodSig, P<ast::Block>) {
+    let (rewritten_fn_decl, rewritten_body)
+        = expand_and_rename_fn_decl_and_block(sig.decl, body, fld);
+    (ast::MethodSig {
+        generics: fld.fold_generics(sig.generics),
+        abi: sig.abi,
+        explicit_self: fld.fold_explicit_self(sig.explicit_self),
+        unsafety: sig.unsafety,
+        decl: rewritten_fn_decl
+    }, rewritten_body)
+}
+
 /// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b:'a> {
     pub cx: &'a mut ExtCtxt<'b>,
@@ -1410,16 +1400,14 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         expand_arm(arm, self)
     }
 
-    fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem> {
-        expand_trait_item(i, self)
-    }
-
-    fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector<ast::ImplItem> {
-        expand_impl_item(i, self)
+    fn fold_trait_item(&mut self, i: P<ast::TraitItem>) -> SmallVector<P<ast::TraitItem>> {
+        expand_annotatable(Annotatable::TraitItem(i), self)
+            .into_iter().map(|i| i.expect_trait_item()).collect()
     }
 
-    fn fold_method(&mut self, method: P<ast::Method>) -> SmallVector<P<ast::Method>> {
-        expand_method(method, self)
+    fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem>> {
+        expand_annotatable(Annotatable::ImplItem(i), self)
+            .into_iter().map(|i| i.expect_impl_item()).collect()
     }
 
     fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> {
@@ -1565,9 +1553,9 @@ fn mark_item(expr: P<ast::Item>, m: Mrk) -> P<ast::Item> {
 }
 
 // apply a given mark to the given item. Used following the expansion of a macro.
-fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> {
-    Marker{mark:m}.fold_method(expr)
-        .expect_one("marking an item didn't return exactly one method")
+fn mark_impl_item(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
+    Marker{mark:m}.fold_impl_item(ii)
+        .expect_one("marking an impl item didn't return exactly one impl item")
 }
 
 /// Check that there are no macro invocations left in the AST:
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 737648cd90c..48c045ee4f9 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -176,7 +176,6 @@ pub mod rt {
     impl_to_source! { ast::Arg, arg_to_string }
     impl_to_source! { Generics, generics_to_string }
     impl_to_source! { P<ast::Item>, item_to_string }
-    impl_to_source! { P<ast::Method>, method_to_string }
     impl_to_source! { P<ast::Stmt>, stmt_to_string }
     impl_to_source! { P<ast::Expr>, expr_to_string }
     impl_to_source! { P<ast::Pat>, pat_to_string }
@@ -311,7 +310,6 @@ pub mod rt {
     impl_to_tokens! { P<ast::Item> }
     impl_to_tokens! { P<ast::Pat> }
     impl_to_tokens! { ast::Arm }
-    impl_to_tokens! { P<ast::Method> }
     impl_to_tokens_lifetime! { &'a [P<ast::Item>] }
     impl_to_tokens! { ast::Ty }
     impl_to_tokens_lifetime! { &'a [ast::Ty] }
@@ -446,15 +444,6 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
     base::MacEager::expr(expanded)
 }
 
-pub fn expand_quote_method(cx: &mut ExtCtxt,
-                           sp: Span,
-                           tts: &[ast::TokenTree])
-                           -> Box<base::MacResult+'static> {
-    let expanded = expand_parse_call(cx, sp, "parse_method_with_outer_attributes",
-                                     vec!(), tts);
-    base::MacEager::expr(expanded)
-}
-
 pub fn expand_quote_stmt(cx: &mut ExtCtxt,
                          sp: Span,
                          tts: &[ast::TokenTree])
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 644c6cd7e28..7575d4b5ecd 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -71,7 +71,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
         loop {
             let mut parser = self.parser.borrow_mut();
             // so... do outer attributes attached to the macro invocation
-            // just disappear? This question applies to make_methods, as
+            // just disappear? This question applies to make_impl_items, as
             // well.
             match parser.parse_item_with_outer_attributes() {
                 Some(item) => ret.push(item),
@@ -82,15 +82,14 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
         Some(ret)
     }
 
-    fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Method>>> {
+    fn make_impl_items(self: Box<ParserAnyMacro<'a>>)
+                       -> Option<SmallVector<P<ast::ImplItem>>> {
         let mut ret = SmallVector::zero();
         loop {
             let mut parser = self.parser.borrow_mut();
             match parser.token {
                 token::Eof => break,
-                _ => {
-                    ret.push(parser.parse_method_with_outer_attributes());
-                }
+                _ => ret.push(parser.parse_impl_item_with_outer_attributes())
             }
         }
         self.ensure_complete_parse(false);
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 959e3bdb314..105a61d0857 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -98,11 +98,11 @@ pub trait Folder : Sized {
         noop_fold_item_underscore(i, self)
     }
 
-    fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> {
+    fn fold_trait_item(&mut self, i: P<TraitItem>) -> SmallVector<P<TraitItem>> {
         noop_fold_trait_item(i, self)
     }
 
-    fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> {
+    fn fold_impl_item(&mut self, i: P<ImplItem>) -> SmallVector<P<ImplItem>> {
         noop_fold_impl_item(i, self)
     }
 
@@ -110,14 +110,6 @@ pub trait Folder : Sized {
         noop_fold_fn_decl(d, self)
     }
 
-    fn fold_type_method(&mut self, m: TypeMethod) -> TypeMethod {
-        noop_fold_type_method(m, self)
-    }
-
-    fn fold_method(&mut self, m: P<Method>) -> SmallVector<P<Method>> {
-        noop_fold_method(m, self)
-    }
-
     fn fold_block(&mut self, b: P<Block>) -> P<Block> {
         noop_fold_block(b, self)
     }
@@ -315,15 +307,6 @@ pub trait Folder : Sized {
         noop_fold_where_predicate(where_predicate, self)
     }
 
-    fn fold_typedef(&mut self, typedef: Typedef) -> Typedef {
-        noop_fold_typedef(typedef, self)
-    }
-
-    fn fold_associated_type(&mut self, associated_type: AssociatedType)
-                            -> AssociatedType {
-        noop_fold_associated_type(associated_type, self)
-    }
-
     fn new_id(&mut self, i: NodeId) -> NodeId {
         i
     }
@@ -829,41 +812,6 @@ pub fn noop_fold_where_predicate<T: Folder>(
     }
 }
 
-pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T)
-                            -> Typedef
-                            where T: Folder {
-    let new_id = folder.new_id(t.id);
-    let new_span = folder.new_span(t.span);
-    let new_attrs = t.attrs.iter().flat_map(|attr| {
-        folder.fold_attribute((*attr).clone()).into_iter()
-    }).collect();
-    let new_ident = folder.fold_ident(t.ident);
-    let new_type = folder.fold_ty(t.typ);
-    ast::Typedef {
-        ident: new_ident,
-        typ: new_type,
-        id: new_id,
-        span: new_span,
-        vis: t.vis,
-        attrs: new_attrs,
-    }
-}
-
-pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
-                                    -> AssociatedType
-                                    where T: Folder
-{
-    let new_attrs = at.attrs
-                      .iter()
-                      .flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter())
-                      .collect();
-    let new_param = folder.fold_ty_param(at.ty_param);
-    ast::AssociatedType {
-        attrs: new_attrs,
-        ty_param: new_param,
-    }
-}
-
 pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) -> P<StructDef> {
     struct_def.map(|StructDef { fields, ctor_id }| StructDef {
         fields: fields.move_map(|f| fld.fold_struct_field(f)),
@@ -1018,61 +966,43 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
     }
 }
 
-pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T) -> SmallVector<TraitItem> {
-    match i {
-        RequiredMethod(m) => {
-                SmallVector::one(RequiredMethod(
-                        folder.fold_type_method(m)))
-        }
-        ProvidedMethod(method) => {
-            folder.fold_method(method).into_iter()
-                .map(|m| ProvidedMethod(m)).collect()
-        }
-        TypeTraitItem(at) => {
-            SmallVector::one(TypeTraitItem(P(
-                        folder.fold_associated_type(
-                            (*at).clone()))))
-        }
-    }
-}
-
-pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T) -> SmallVector<ImplItem> {
-    match i {
-        MethodImplItem(ref x) => {
-            folder.fold_method((*x).clone()).into_iter().map(|m| MethodImplItem(m)).collect()
-        }
-        TypeImplItem(ref t) => {
-            SmallVector::one(TypeImplItem(
-                    P(folder.fold_typedef((**t).clone()))))
-        }
-    }
+pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T)
+                                       -> SmallVector<P<TraitItem>> {
+    SmallVector::one(i.map(|TraitItem {id, ident, attrs, node, span}| TraitItem {
+        id: folder.new_id(id),
+        ident: folder.fold_ident(ident),
+        attrs: fold_attrs(attrs, folder),
+        node: match node {
+            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)))
+            }
+        },
+        span: folder.new_span(span)
+    }))
 }
 
-pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMethod {
-    let TypeMethod {
-        id,
-        ident,
-        attrs,
-        unsafety,
-        abi,
-        decl,
-        generics,
-        explicit_self,
-        vis,
-        span
-    } = m;
-    TypeMethod {
-        id: fld.new_id(id),
-        ident: fld.fold_ident(ident),
-        attrs: fold_attrs(attrs, fld),
-        unsafety: unsafety,
-        abi: abi,
-        decl: fld.fold_fn_decl(decl),
-        generics: fld.fold_generics(generics),
-        explicit_self: fld.fold_explicit_self(explicit_self),
+pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T)
+                                      -> SmallVector<P<ImplItem>> {
+    SmallVector::one(i.map(|ImplItem {id, ident, attrs, node, vis, span}| ImplItem {
+        id: folder.new_id(id),
+        ident: folder.fold_ident(ident),
+        attrs: fold_attrs(attrs, folder),
         vis: vis,
-        span: fld.new_span(span)
-    }
+        node: match node  {
+            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)
+    }))
 }
 
 pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
@@ -1171,34 +1101,14 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
     })
 }
 
-// Default fold over a method.
-// Invariant: produces exactly one method.
-pub fn noop_fold_method<T: Folder>(m: P<Method>, folder: &mut T) -> SmallVector<P<Method>> {
-    SmallVector::one(m.map(|Method {id, attrs, node, span}| Method {
-        id: folder.new_id(id),
-        attrs: fold_attrs(attrs, folder),
-        node: match node {
-            MethDecl(ident,
-                     generics,
-                     abi,
-                     explicit_self,
-                     unsafety,
-                     decl,
-                     body,
-                     vis) => {
-                MethDecl(folder.fold_ident(ident),
-                         folder.fold_generics(generics),
-                         abi,
-                         folder.fold_explicit_self(explicit_self),
-                         unsafety,
-                         folder.fold_fn_decl(decl),
-                         folder.fold_block(body),
-                         vis)
-            },
-            MethMac(mac) => MethMac(folder.fold_mac(mac)),
-        },
-        span: folder.new_span(span)
-    }))
+pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
+    MethodSig {
+        generics: folder.fold_generics(sig.generics),
+        abi: sig.abi,
+        explicit_self: folder.fold_explicit_self(sig.explicit_self),
+        unsafety: sig.unsafety,
+        decl: folder.fold_fn_decl(sig.decl)
+    }
 }
 
 pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ea413ac0dc8..39c43ff1e75 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -11,9 +11,9 @@
 pub use self::PathParsingMode::*;
 
 use abi;
-use ast::{AssociatedType, BareFnTy};
+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};
@@ -38,12 +38,11 @@ use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitStr, LitInt, Local, LocalLet};
 use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource};
-use ast::{Method, MutTy, BiMul, Mutability};
+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};
@@ -51,11 +50,10 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
 use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
 use ast::{TtDelimited, TtSequence, TtToken};
 use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
-use ast::{TyFixedLengthVec, TyBareFn};
-use ast::{TyTypeof, TyInfer, TypeMethod};
+use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer};
 use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr};
 use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
-use ast::{TypeImplItem, TypeTraitItem, Typedef,};
+use ast::{TypeImplItem, TypeTraitItem};
 use ast::{UnnamedField, UnsafeBlock};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause};
@@ -1244,52 +1242,53 @@ impl<'a> Parser<'a> {
 
     /// Parses `type Foo;` in a trait declaration only. The `type` keyword has
     /// already been parsed.
-    fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
-                             -> AssociatedType
-    {
-        let ty_param = self.parse_ty_param();
+    fn parse_assoc_ty_in_trait(&mut self, attrs: Vec<Attribute>)
+                               -> P<TraitItem> {
+        let TyParam {id, ident, bounds, default, span} = self.parse_ty_param();
         self.expect(&token::Semi);
-        AssociatedType {
+        P(TraitItem {
+            id: id,
+            ident: ident,
             attrs: attrs,
-            ty_param: ty_param,
-        }
+            node: TypeTraitItem(bounds, default),
+            span: span,
+        })
     }
 
     /// Parses `type Foo = TYPE;` in an implementation declaration only. The
     /// `type` keyword has already been parsed.
-    fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility)
-                     -> Typedef {
+    fn parse_assoc_ty_in_impl(&mut self, attrs: Vec<Attribute>, vis: Visibility)
+                              -> P<ImplItem> {
         let lo = self.span.lo;
         let ident = self.parse_ident();
         self.expect(&token::Eq);
         let typ = self.parse_ty_sum();
         let hi = self.span.hi;
         self.expect(&token::Semi);
-        Typedef {
+        P(ImplItem {
             id: ast::DUMMY_NODE_ID,
             span: mk_sp(lo, hi),
             ident: ident,
             vis: vis,
             attrs: attrs,
-            typ: typ,
-        }
+            node: TypeImplItem(typ),
+        })
     }
 
     /// Parse the items in a trait declaration
-    pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
+    pub fn parse_trait_items(&mut self) -> Vec<P<TraitItem>> {
         self.parse_unspanned_seq(
             &token::OpenDelim(token::Brace),
             &token::CloseDelim(token::Brace),
             seq_sep_none(),
             |p| {
-            let attrs = p.parse_outer_attributes();
+            let mut attrs = p.parse_outer_attributes();
 
             if p.eat_keyword(keywords::Type) {
-                TypeTraitItem(P(p.parse_associated_type(attrs)))
+                p.parse_assoc_ty_in_trait(attrs)
             } else {
                 let lo = p.span.lo;
 
-                let vis = p.parse_visibility();
                 let style = p.parse_unsafety();
                 let abi = if p.eat_keyword(keywords::Extern) {
                     p.parse_opt_abi().unwrap_or(abi::C)
@@ -1309,44 +1308,27 @@ impl<'a> Parser<'a> {
                 });
 
                 p.parse_where_clause(&mut generics);
+                let sig = ast::MethodSig {
+                    unsafety: style,
+                    decl: d,
+                    generics: generics,
+                    abi: abi,
+                    explicit_self: explicit_self,
+                };
 
                 let hi = p.last_span.hi;
-                match p.token {
+                let body = match p.token {
                   token::Semi => {
                     p.bump();
                     debug!("parse_trait_methods(): parsing required method");
-                    RequiredMethod(TypeMethod {
-                        ident: ident,
-                        attrs: attrs,
-                        unsafety: style,
-                        decl: d,
-                        generics: generics,
-                        abi: abi,
-                        explicit_self: explicit_self,
-                        id: ast::DUMMY_NODE_ID,
-                        span: mk_sp(lo, hi),
-                        vis: vis,
-                    })
+                    None
                   }
                   token::OpenDelim(token::Brace) => {
                     debug!("parse_trait_methods(): parsing provided method");
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
-                    let mut attrs = attrs;
                     attrs.push_all(&inner_attrs[..]);
-                    ProvidedMethod(P(ast::Method {
-                        attrs: attrs,
-                        id: ast::DUMMY_NODE_ID,
-                        span: mk_sp(lo, hi),
-                        node: ast::MethDecl(ident,
-                                            generics,
-                                            abi,
-                                            explicit_self,
-                                            style,
-                                            d,
-                                            body,
-                                            vis)
-                    }))
+                    Some(body)
                   }
 
                   _ => {
@@ -1354,7 +1336,15 @@ impl<'a> Parser<'a> {
                       p.fatal(&format!("expected `;` or `{{`, found `{}`",
                                        token_str)[..])
                   }
-                }
+                };
+
+                P(TraitItem {
+                    id: ast::DUMMY_NODE_ID,
+                    ident: ident,
+                    attrs: attrs,
+                    node: ast::MethodTraitItem(sig, body),
+                    span: mk_sp(lo, hi),
+                })
             }
         })
     }
@@ -4635,11 +4625,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<Method> {
+    /// 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) {
@@ -4656,12 +4650,12 @@ impl<'a> Parser<'a> {
     /// Parse a method in a trait impl, starting with `attrs` attributes.
     pub fn parse_method(&mut self,
                         attrs: Vec<Attribute>,
-                        visa: Visibility)
-                        -> P<Method> {
+                        vis: Visibility)
+                        -> P<ImplItem> {
         let lo = self.span.lo;
 
         // code copied from parse_macro_use_or_failure... abstraction!
-        let (method_, hi, new_attrs) = {
+        let (method_, hi, new_attrs, ident) = {
             if !self.token.is_any_keyword()
                 && self.look_ahead(1, |t| *t == token::Not)
                 && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
@@ -4669,7 +4663,7 @@ impl<'a> Parser<'a> {
                 // method macro.
 
                 let last_span = self.last_span;
-                self.complain_if_pub_macro(visa, last_span);
+                self.complain_if_pub_macro(vis, last_span);
 
                 let pth = self.parse_path(NoTypesAllowed);
                 self.expect(&token::Not);
@@ -4686,7 +4680,8 @@ 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();
                 let abi = if self.eat_keyword(keywords::Extern) {
@@ -4705,22 +4700,22 @@ impl<'a> Parser<'a> {
                 let body_span = body.span;
                 let mut new_attrs = attrs;
                 new_attrs.push_all(&inner_attrs[..]);
-                (ast::MethDecl(ident,
-                               generics,
-                               abi,
-                               explicit_self,
-                               unsafety,
-                               decl,
-                               body,
-                               visa),
-                 body_span.hi, new_attrs)
+                (MethodImplItem(ast::MethodSig {
+                    generics: generics,
+                    abi: abi,
+                    explicit_self: explicit_self,
+                    unsafety: unsafety,
+                    decl: decl
+                 }, body), body_span.hi, new_attrs, ident)
             }
         };
-        P(ast::Method {
-            attrs: new_attrs,
+        P(ImplItem {
             id: ast::DUMMY_NODE_ID,
-            span: mk_sp(lo, hi),
+            attrs: new_attrs,
+            vis: vis,
+            ident: ident,
             node: method_,
+            span: mk_sp(lo, hi),
         })
     }
 
@@ -4752,7 +4747,7 @@ impl<'a> Parser<'a> {
         (ident, ItemTrait(unsafety, tps, bounds, meths), None)
     }
 
-    fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
+    fn parse_impl_items(&mut self) -> (Vec<P<ImplItem>>, Vec<Attribute>) {
         let mut impl_items = Vec::new();
         self.expect(&token::OpenDelim(token::Brace));
         let (inner_attrs, mut method_attrs) =
@@ -4764,15 +4759,11 @@ impl<'a> Parser<'a> {
             }
 
             let vis = self.parse_visibility();
-            if self.eat_keyword(keywords::Type) {
-                impl_items.push(TypeImplItem(P(self.parse_typedef(
-                            method_attrs,
-                            vis))))
+            impl_items.push(if self.eat_keyword(keywords::Type) {
+                self.parse_assoc_ty_in_impl(method_attrs, vis)
             } else {
-                impl_items.push(MethodImplItem(self.parse_method(
-                            method_attrs,
-                            vis)));
-            }
+                self.parse_method(method_attrs, vis)
+            });
             method_attrs = vec![];
         }
         (impl_items, inner_attrs)
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 883c2295a36..07303ba51ff 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -12,8 +12,7 @@ pub use self::AnnNode::*;
 
 use abi;
 use ast;
-use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
-use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem};
+use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
 use ast_util;
 use attr;
 use owned_slice::OwnedSlice;
@@ -360,14 +359,6 @@ pub fn generics_to_string(generics: &ast::Generics) -> String {
     $to_string(|s| s.print_generics(generics))
 }
 
-pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
-    $to_string(|s| s.print_ty_method(p))
-}
-
-pub fn method_to_string(p: &ast::Method) -> String {
-    $to_string(|s| s.print_method(p))
-}
-
 pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
     $to_string(|s| s.print_fn_block_args(p))
 }
@@ -384,8 +375,9 @@ pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ide
                   opt_explicit_self: Option<&ast::ExplicitSelf_>,
                   generics: &ast::Generics) -> String {
     $to_string(|s| {
-        try!(s.print_fn(decl, Some(unsafety), abi::Rust,
-                        name, generics, opt_explicit_self, ast::Inherited));
+        try!(s.head(""));
+        try!(s.print_fn(decl, unsafety, abi::Rust, Some(name),
+                        generics, opt_explicit_self, ast::Inherited));
         try!(s.end()); // Close the head box
         s.end() // Close the outer box
     })
@@ -768,8 +760,10 @@ impl<'a> State<'a> {
         try!(self.print_outer_attributes(&item.attrs));
         match item.node {
             ast::ForeignItemFn(ref decl, ref generics) => {
-                try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics,
-                                   None, item.vis));
+                try!(self.head(""));
+                try!(self.print_fn(&**decl, ast::Unsafety::Normal,
+                                   abi::Rust, Some(item.ident),
+                                   generics, None, item.vis));
                 try!(self.end()); // end head-ibox
                 try!(word(&mut self.s, ";"));
                 self.end() // end the outer fn box
@@ -790,23 +784,24 @@ impl<'a> State<'a> {
         }
     }
 
-    fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
-                             -> io::Result<()>
-    {
-        try!(self.print_outer_attributes(&typedef.attrs));
+    fn print_associated_type(&mut self,
+                             ident: ast::Ident,
+                             bounds: Option<&ast::TyParamBounds>,
+                             ty: Option<&ast::Ty>)
+                             -> io::Result<()> {
         try!(self.word_space("type"));
-        try!(self.print_ty_param(&typedef.ty_param));
+        try!(self.print_ident(ident));
+        if let Some(bounds) = bounds {
+            try!(self.print_bounds(":", bounds));
+        }
+        if let Some(ty) = ty {
+            try!(space(&mut self.s));
+            try!(self.word_space("="));
+            try!(self.print_type(ty));
+        }
         word(&mut self.s, ";")
     }
 
-    fn print_typedef(&mut self, typedef: &ast::Typedef) -> io::Result<()> {
-        try!(self.word_space("type"));
-        try!(self.print_ident(typedef.ident));
-        try!(space(&mut self.s));
-        try!(self.word_space("="));
-        try!(self.print_type(&*typedef.typ));
-        word(&mut self.s, ";")
-    }
 
     /// Pretty-print an item
     pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
@@ -869,11 +864,12 @@ impl<'a> State<'a> {
                 try!(self.end()); // end the outer cbox
             }
             ast::ItemFn(ref decl, unsafety, abi, ref typarams, ref body) => {
+                try!(self.head(""));
                 try!(self.print_fn(
-                    &**decl,
-                    Some(unsafety),
+                    decl,
+                    unsafety,
                     abi,
-                    item.ident,
+                    Some(item.ident),
                     typarams,
                     None,
                     item.vis
@@ -977,18 +973,11 @@ impl<'a> State<'a> {
                 try!(self.bopen());
                 try!(self.print_inner_attributes(&item.attrs));
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref meth) => {
-                            try!(self.print_method(&**meth));
-                        }
-                        ast::TypeImplItem(ref typ) => {
-                            try!(self.print_typedef(&**typ));
-                        }
-                    }
+                    try!(self.print_impl_item(impl_item));
                 }
                 try!(self.bclose(item.span));
             }
-            ast::ItemTrait(unsafety, ref generics, ref bounds, ref methods) => {
+            ast::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => {
                 try!(self.head(""));
                 try!(self.print_visibility(item.vis));
                 try!(self.print_unsafety(unsafety));
@@ -1009,8 +998,8 @@ impl<'a> State<'a> {
                 try!(self.print_where_clause(generics));
                 try!(word(&mut self.s, " "));
                 try!(self.bopen());
-                for meth in methods {
-                    try!(self.print_trait_method(meth));
+                for trait_item in trait_items {
+                    try!(self.print_trait_item(trait_item));
                 }
                 try!(self.bclose(item.span));
             }
@@ -1242,60 +1231,61 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> io::Result<()> {
-        try!(self.hardbreak_if_not_bol());
-        try!(self.maybe_print_comment(m.span.lo));
-        try!(self.print_outer_attributes(&m.attrs));
-        try!(self.print_ty_fn(m.abi,
-                              m.unsafety,
-                              &*m.decl,
-                              Some(m.ident),
-                              &m.generics,
-                              Some(&m.explicit_self.node)));
-        word(&mut self.s, ";")
+    pub fn print_method_sig(&mut self,
+                            ident: ast::Ident,
+                            m: &ast::MethodSig,
+                            vis: ast::Visibility)
+                            -> io::Result<()> {
+        self.print_fn(&m.decl,
+                      m.unsafety,
+                      m.abi,
+                      Some(ident),
+                      &m.generics,
+                      Some(&m.explicit_self.node),
+                      vis)
     }
 
-    pub fn print_trait_method(&mut self,
-                              m: &ast::TraitItem) -> io::Result<()> {
-        match *m {
-            RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
-            ProvidedMethod(ref m) => self.print_method(&**m),
-            TypeTraitItem(ref t) => self.print_associated_type(&**t),
+    pub fn print_trait_item(&mut self, ti: &ast::TraitItem)
+                            -> io::Result<()> {
+        try!(self.hardbreak_if_not_bol());
+        try!(self.maybe_print_comment(ti.span.lo));
+        try!(self.print_outer_attributes(&ti.attrs));
+        match ti.node {
+            ast::MethodTraitItem(ref sig, ref body) => {
+                if body.is_some() {
+                    try!(self.head(""));
+                }
+                try!(self.print_method_sig(ti.ident, sig, ast::Inherited));
+                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),
+                                           default.as_ref().map(|ty| &**ty))
+            }
         }
     }
 
     pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
-        match *ii {
-            MethodImplItem(ref m) => self.print_method(&**m),
-            TypeImplItem(ref td) => self.print_typedef(&**td),
-        }
-    }
-
-    pub fn print_method(&mut self, meth: &ast::Method) -> io::Result<()> {
         try!(self.hardbreak_if_not_bol());
-        try!(self.maybe_print_comment(meth.span.lo));
-        try!(self.print_outer_attributes(&meth.attrs));
-        match meth.node {
-            ast::MethDecl(ident,
-                          ref generics,
-                          abi,
-                          ref explicit_self,
-                          unsafety,
-                          ref decl,
-                          ref body,
-                          vis) => {
-                try!(self.print_fn(&**decl,
-                                   Some(unsafety),
-                                   abi,
-                                   ident,
-                                   generics,
-                                   Some(&explicit_self.node),
-                                   vis));
-                try!(word(&mut self.s, " "));
-                self.print_block_with_attrs(&**body, &meth.attrs)
-            },
-            ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
-                                            ..}) => {
+        try!(self.maybe_print_comment(ii.span.lo));
+        try!(self.print_outer_attributes(&ii.attrs));
+        match ii.node {
+            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))
+            }
+            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, "! "));
@@ -2326,16 +2316,18 @@ impl<'a> State<'a> {
 
     pub fn print_fn(&mut self,
                     decl: &ast::FnDecl,
-                    unsafety: Option<ast::Unsafety>,
+                    unsafety: ast::Unsafety,
                     abi: abi::Abi,
-                    name: ast::Ident,
+                    name: Option<ast::Ident>,
                     generics: &ast::Generics,
                     opt_explicit_self: Option<&ast::ExplicitSelf_>,
                     vis: ast::Visibility) -> io::Result<()> {
-        try!(self.head(""));
         try!(self.print_fn_header_info(unsafety, abi, vis));
-        try!(self.nbsp());
-        try!(self.print_ident(name));
+
+        if let Some(name) = name {
+            try!(self.nbsp());
+            try!(self.print_ident(name));
+        }
         try!(self.print_generics(generics));
         try!(self.print_fn_args_and_ret(decl, opt_explicit_self));
         self.print_where_clause(generics)
@@ -2702,25 +2694,14 @@ impl<'a> State<'a> {
                        abi: abi::Abi,
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
-                       id: Option<ast::Ident>,
+                       name: Option<ast::Ident>,
                        generics: &ast::Generics,
                        opt_explicit_self: Option<&ast::ExplicitSelf_>)
                        -> io::Result<()> {
         try!(self.ibox(indent_unit));
-        try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited));
-
-        match id {
-            Some(id) => {
-                try!(word(&mut self.s, " "));
-                try!(self.print_ident(id));
-            }
-            _ => ()
-        }
-
-        try!(self.print_generics(generics));
-        try!(zerobreak(&mut self.s));
-        try!(self.print_fn_args_and_ret(decl, opt_explicit_self));
-        try!(self.print_where_clause(generics));
+        try!(self.print_fn(decl, unsafety, abi, name,
+                           generics, opt_explicit_self,
+                           ast::Inherited));
         self.end()
     }
 
@@ -2942,14 +2923,6 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_opt_unsafety(&mut self,
-                            opt_unsafety: Option<ast::Unsafety>) -> io::Result<()> {
-        match opt_unsafety {
-            Some(unsafety) => self.print_unsafety(unsafety),
-            None => Ok(())
-        }
-    }
-
     pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
                                                   opt_abi: Option<abi::Abi>)
         -> io::Result<()> {
@@ -2975,11 +2948,11 @@ impl<'a> State<'a> {
     }
 
     pub fn print_fn_header_info(&mut self,
-                                opt_unsafety: Option<ast::Unsafety>,
+                                unsafety: ast::Unsafety,
                                 abi: abi::Abi,
                                 vis: ast::Visibility) -> io::Result<()> {
         try!(word(&mut self.s, &visibility_qualified(vis, "")));
-        try!(self.print_opt_unsafety(opt_unsafety));
+        try!(self.print_unsafety(unsafety));
 
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 33d8d56b4b1..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 Generics, &'a Method),
+    FkMethod(Ident, &'a MethodSig),
 
     /// |x, y| ...
     /// proc(x, y) ...
@@ -77,8 +77,8 @@ pub trait Visitor<'v> : Sized {
     fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
         walk_fn(self, fk, fd, b, s)
     }
-    fn visit_ty_method(&mut self, t: &'v TypeMethod) { walk_ty_method(self, t) }
-    fn visit_trait_item(&mut self, t: &'v TraitItem) { walk_trait_item(self, t) }
+    fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) }
+    fn visit_impl_item(&mut self, ii: &'v ImplItem) { walk_impl_item(self, ii) }
     fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) }
     fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
         walk_ty_param_bound(self, bounds)
@@ -143,13 +143,7 @@ pub fn walk_inlined_item<'v,V>(visitor: &mut V, item: &'v InlinedItem)
         IIItem(ref i) => visitor.visit_item(&**i),
         IIForeign(ref i) => visitor.visit_foreign_item(&**i),
         IITraitItem(_, ref ti) => visitor.visit_trait_item(ti),
-        IIImplItem(_, MethodImplItem(ref m)) => {
-            walk_method_helper(visitor, &**m)
-        }
-        IIImplItem(_, TypeImplItem(ref typedef)) => {
-            visitor.visit_ident(typedef.span, typedef.ident);
-            visitor.visit_ty(&*typedef.typ);
-        }
+        IIImplItem(_, ref ii) => visitor.visit_impl_item(ii),
     }
 }
 
@@ -202,8 +196,6 @@ pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
     }
 }
 
-/// Like with walk_method_helper this doesn't correspond to a method
-/// in Visitor, and so it gets a _helper suffix.
 pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
                                   trait_ref: &'v PolyTraitRef,
                                   _modifier: &'v TraitBoundModifier)
@@ -213,8 +205,6 @@ pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
     visitor.visit_trait_ref(&trait_ref.trait_ref);
 }
 
-/// Like with walk_method_helper this doesn't correspond to a method
-/// in Visitor, and so it gets a _helper suffix.
 pub fn walk_trait_ref<'v,V>(visitor: &mut V,
                                    trait_ref: &'v TraitRef)
     where V: Visitor<'v>
@@ -294,15 +284,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             }
             visitor.visit_ty(&**typ);
             for impl_item in impl_items {
-                match *impl_item {
-                    MethodImplItem(ref method) => {
-                        walk_method_helper(visitor, &**method)
-                    }
-                    TypeImplItem(ref typedef) => {
-                        visitor.visit_ident(typedef.span, typedef.ident);
-                        visitor.visit_ty(&*typedef.typ);
-                    }
-                }
+                visitor.visit_impl_item(impl_item);
             }
         }
         ItemStruct(ref struct_definition, ref generics) => {
@@ -561,15 +543,11 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
     }
 }
 
-pub fn walk_ty_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v TyParam) {
-    visitor.visit_ident(param.span, param.ident);
-    walk_ty_param_bounds_helper(visitor, &param.bounds);
-    walk_ty_opt(visitor, &param.default);
-}
-
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
-    for type_parameter in &*generics.ty_params {
-        walk_ty_param(visitor, type_parameter);
+    for param in &*generics.ty_params {
+        visitor.visit_ident(param.span, param.ident);
+        walk_ty_param_bounds_helper(visitor, &param.bounds);
+        walk_ty_opt(visitor, &param.default);
     }
     walk_lifetime_decls_helper(visitor, &generics.lifetimes);
     for predicate in &generics.where_clause.predicates {
@@ -614,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
-pub fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, method: &'v Method) {
-    match method.node {
-        MethDecl(ident, ref generics, _, _, _, ref decl, ref body, _) => {
-            visitor.visit_ident(method.span, ident);
-            visitor.visit_fn(FkMethod(ident, generics, method),
-                             &**decl,
-                             &**body,
-                             method.span,
-                             method.id);
-            for attr in &method.attrs {
-                visitor.visit_attribute(attr);
-            }
-
-        },
-        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,
@@ -647,14 +603,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
         FkItemFn(_, generics, _, _) => {
             visitor.visit_generics(generics);
         }
-        FkMethod(_, generics, method) => {
-            visitor.visit_generics(generics);
-            match method.node {
-                MethDecl(_, _, _, ref explicit_self, _, _, _, _) =>
-                    visitor.visit_explicit_self(explicit_self),
-                MethMac(ref mac) =>
-                    visitor.visit_mac(mac)
-            }
+        FkMethod(_, sig) => {
+            visitor.visit_generics(&sig.generics);
+            visitor.visit_explicit_self(&sig.explicit_self);
         }
         FkFnBlock(..) => {}
     }
@@ -662,25 +613,43 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
     visitor.visit_block(function_body)
 }
 
-pub fn walk_ty_method<'v, V: Visitor<'v>>(visitor: &mut V, method_type: &'v TypeMethod) {
-    visitor.visit_ident(method_type.span, method_type.ident);
-    visitor.visit_explicit_self(&method_type.explicit_self);
-    for argument_type in &method_type.decl.inputs {
-        visitor.visit_ty(&*argument_type.ty)
-    }
-    visitor.visit_generics(&method_type.generics);
-    walk_fn_ret_ty(visitor, &method_type.decl.output);
-    for attr in &method_type.attrs {
+pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
+    visitor.visit_ident(trait_item.span, trait_item.ident);
+    for attr in &trait_item.attrs {
         visitor.visit_attribute(attr);
     }
+    match trait_item.node {
+        MethodTraitItem(ref sig, None) => {
+            visitor.visit_explicit_self(&sig.explicit_self);
+            visitor.visit_generics(&sig.generics);
+            walk_fn_decl(visitor, &sig.decl);
+        }
+        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);
+            walk_ty_opt(visitor, default);
+        }
+    }
 }
 
-pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_method: &'v TraitItem) {
-    match *trait_method {
-        RequiredMethod(ref method_type) => visitor.visit_ty_method(method_type),
-        ProvidedMethod(ref method) => walk_method_helper(visitor, &**method),
-        TypeTraitItem(ref associated_type) => {
-            walk_ty_param(visitor, &associated_type.ty_param);
+pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
+    visitor.visit_ident(impl_item.span, impl_item.ident);
+    for attr in &impl_item.attrs {
+        visitor.visit_attribute(attr);
+    }
+    match impl_item.node {
+        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 d9afc1df28e..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;
@@ -82,14 +82,24 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
             }))
         }
         Annotatable::ImplItem(it) => {
-            Annotatable::ImplItem(ImplItem::MethodImplItem(
-                quote_method!(cx, fn foo(&self) -> i32 { 42 })
-            ))
+            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) => {
-            Annotatable::TraitItem(TraitItem::ProvidedMethod(
-                quote_method!(cx, fn foo(&self) -> i32 { 0 })
-            ))
+            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/impl-duplicate-methods.rs b/src/test/compile-fail/impl-duplicate-methods.rs
index c0c951dd8b1..3b4def8c508 100644
--- a/src/test/compile-fail/impl-duplicate-methods.rs
+++ b/src/test/compile-fail/impl-duplicate-methods.rs
@@ -11,7 +11,7 @@
 struct Foo;
 impl Foo {
     fn orange(&self){}
-    fn orange(&self){}   //~ ERROR error: duplicate method in trait impl
+    fn orange(&self){}   //~ ERROR error: duplicate method
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-4265.rs b/src/test/compile-fail/issue-4265.rs
index ab18e0bcddc..553436607d1 100644
--- a/src/test/compile-fail/issue-4265.rs
+++ b/src/test/compile-fail/issue-4265.rs
@@ -17,7 +17,7 @@ impl Foo {
         Foo { baz: 0 }.bar();
     }
 
-    fn bar() { //~ ERROR duplicate method in trait impl
+    fn bar() { //~ ERROR duplicate method
     }
 }
 
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index cb2d4e10e6e..04db6c8c8f3 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -59,8 +59,8 @@ trait B {
 }
 
 pub trait C { //~ ERROR: missing documentation for a trait
-    fn foo(&self); //~ ERROR: missing documentation for a type method
-    fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a method
+    fn foo(&self); //~ ERROR: missing documentation for a trait method
+    fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a trait method
 }
 
 #[allow(missing_docs)]
diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs
index 5f3744712cc..113393490cb 100644
--- a/src/test/compile-fail/unnecessary-private.rs
+++ b/src/test/compile-fail/unnecessary-private.rs
@@ -13,7 +13,7 @@ fn main() {
     pub struct A; //~ ERROR: visibility has no effect
     pub enum B {} //~ ERROR: visibility has no effect
     pub trait C { //~ ERROR: visibility has no effect
-        pub fn foo(&self) {} //~ ERROR: visibility has no effect
+        fn foo(&self) {}
     }
     impl A {
         pub fn foo(&self) {} //~ ERROR: visibility has no effect
diff --git a/src/test/compile-fail/useless-priv.rs b/src/test/compile-fail/useless-priv.rs
index b1120e54434..59964d0df95 100644
--- a/src/test/compile-fail/useless-priv.rs
+++ b/src/test/compile-fail/useless-priv.rs
@@ -12,10 +12,7 @@ struct A { pub i: isize }
 pub enum C { pub Variant }      //~ ERROR: unnecessary `pub`
 
 pub trait E {
-    pub fn foo(&self) {}         //~ ERROR: unnecessary visibility
-}
-trait F {
-    pub fn foo(&self) {}     //~ ERROR: unnecessary visibility
+    fn foo(&self);
 }
 
 impl E for A {
diff --git a/src/test/parse-fail/issue-21153.rs b/src/test/parse-fail/issue-21153.rs
index e2b6deb0ad9..6496ffebbc8 100644
--- a/src/test/parse-fail/issue-21153.rs
+++ b/src/test/parse-fail/issue-21153.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 trait MyTrait<T>: Iterator {
-    Item = T; //~ ERROR expected one of `extern`, `fn`, `pub`, `type`, or `unsafe`, found `Item`
+    Item = T; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `Item`
 }
diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/parse-fail/trait-pub-assoc-ty.rs
index a404d09248f..02d76234d4e 100644
--- a/src/test/compile-fail/useless-priv2.rs
+++ b/src/test/parse-fail/trait-pub-assoc-ty.rs
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,11 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait E {
-    pub fn foo(&self);               //~ ERROR: unnecessary visibility
-}
-trait F {
-    pub fn foo(&self);               //~ ERROR: unnecessary visibility
+trait Foo {
+    pub type Foo; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub`
 }
 
 fn main() {}
diff --git a/src/test/parse-fail/trait-pub-method.rs b/src/test/parse-fail/trait-pub-method.rs
new file mode 100644
index 00000000000..e76802d2ea0
--- /dev/null
+++ b/src/test/parse-fail/trait-pub-method.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {
+    pub fn foo(); //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub`
+}
+
+fn main() {}
diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs
index a9b77419b9a..7f7ed586878 100644
--- a/src/test/run-pass-fulldeps/quote-tokens.rs
+++ b/src/test/run-pass-fulldeps/quote-tokens.rs
@@ -36,9 +36,6 @@ fn syntax_extension(cx: &ExtCtxt) {
     let i: Option<P<syntax::ast::Item>> = quote_item!(cx, #[derive(Eq)] struct Foo; );
     assert!(i.is_some());
 
-    let _j: P<syntax::ast::Method> = quote_method!(cx, fn foo(&self) {});
-    let _k: P<syntax::ast::Method> = quote_method!(cx, #[doc = "hello"] fn foo(&self) {});
-
     let _l: P<syntax::ast::Ty> = quote_ty!(cx, &int);
 
     let _m: Vec<syntax::ast::TokenTree> = quote_matcher!(cx, $($foo:tt,)* bar);