about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2015-03-11 08:38:27 +0200
committerEduard Burtescu <edy.burt@gmail.com>2015-03-11 23:39:16 +0200
commitce10fa8d12cb20d9eee59fffeeaadfcca8badf4a (patch)
treec39add1b10d1a2f80d727c3f6db839760a525b97
parentf98b1763140e4c9b0f122bde2f5cbd24227554a2 (diff)
downloadrust-ce10fa8d12cb20d9eee59fffeeaadfcca8badf4a.tar.gz
rust-ce10fa8d12cb20d9eee59fffeeaadfcca8badf4a.zip
syntax: rename TypeMethod to MethodSig and use it in MethDecl.
-rw-r--r--src/librustc/metadata/encoder.rs4
-rw-r--r--src/librustc/middle/effect.rs2
-rw-r--r--src/librustc/middle/infer/error_reporting.rs20
-rw-r--r--src/librustc/middle/reachable.rs4
-rw-r--r--src/librustc/middle/resolve_lifetime.rs2
-rw-r--r--src/librustc_lint/builtin.rs4
-rw-r--r--src/librustc_privacy/lib.rs4
-rw-r--r--src/librustc_resolve/lib.rs16
-rw-r--r--src/librustc_trans/save/mod.rs8
-rw-r--r--src/librustc_trans/trans/debuginfo.rs12
-rw-r--r--src/librustc_trans/trans/inline.rs4
-rw-r--r--src/librustc_trans/trans/meth.rs4
-rw-r--r--src/librustc_trans/trans/monomorphize.rs4
-rw-r--r--src/librustc_typeck/astconv.rs15
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/collect.rs409
-rw-r--r--src/librustdoc/clean/mod.rs16
-rw-r--r--src/libsyntax/ast.rs15
-rw-r--r--src/libsyntax/ast_map/blocks.rs2
-rw-r--r--src/libsyntax/ast_util.rs23
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs14
-rw-r--r--src/libsyntax/ext/expand.rs17
-rw-r--r--src/libsyntax/fold.rs33
-rw-r--r--src/libsyntax/parse/parser.rs39
-rw-r--r--src/libsyntax/print/pprust.rs107
-rw-r--r--src/libsyntax/visit.rs20
-rw-r--r--src/test/compile-fail/impl-duplicate-methods.rs2
-rw-r--r--src/test/compile-fail/issue-4265.rs2
28 files changed, 291 insertions, 513 deletions
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 0c220ab8766..eb41a26fa77 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -838,7 +838,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
             if !any_types {
                 encode_symbol(ecx, rbml_w, m.def_id.node);
             }
-            encode_method_argument_names(rbml_w, ast_method.pe_fn_decl());
+            encode_method_argument_names(rbml_w, &ast_method.pe_sig().decl);
         }
     }
 
@@ -1383,7 +1383,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                     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());
+                    encode_method_argument_names(rbml_w, &*m.pe_sig().decl);
                 }
 
                 ast::TypeTraitItem(..) => {
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index 5b5e5b6555b..02f2908a9e6 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -91,7 +91,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
             visit::FkItemFn(_, _, fn_style, _) =>
                 (true, fn_style == ast::Unsafety::Unsafe),
             visit::FkMethod(_, method) =>
-                (true, method.pe_unsafety() == ast::Unsafety::Unsafe),
+                (true, method.pe_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 cf3715bc3fb..823acdc1691 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -841,7 +841,7 @@ 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
                     }
@@ -849,11 +849,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 ast_map::NodeImplItem(item) => {
                     match item.node {
                         ast::MethodImplItem(ref m) => {
-                            Some((m.pe_fn_decl(),
-                                  m.pe_generics(),
-                                  m.pe_unsafety(),
+                            Some((&m.pe_sig().decl,
+                                  &m.pe_sig().generics,
+                                  m.pe_sig().unsafety,
                                   item.ident,
-                                  Some(&m.pe_explicit_self().node),
+                                  Some(&m.pe_sig().explicit_self.node),
                                   item.span))
                         }
                         ast::TypeImplItem(_) => None,
@@ -862,11 +862,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 ast_map::NodeTraitItem(item) => {
                     match item.node {
                         ast::ProvidedMethod(ref m) => {
-                            Some((m.pe_fn_decl(),
-                                  m.pe_generics(),
-                                  m.pe_unsafety(),
+                            Some((&m.pe_sig().decl,
+                                  &m.pe_sig().generics,
+                                  m.pe_sig().unsafety,
                                   item.ident,
-                                  Some(&m.pe_explicit_self().node),
+                                  Some(&m.pe_sig().explicit_self.node),
                                   item.span))
                         }
                         _ => None
@@ -1732,7 +1732,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
             ast_map::NodeImplItem(ii) => {
                 match ii.node {
                     ast::MethodImplItem(ref m) => {
-                        taken.push_all(&m.pe_generics().lifetimes);
+                        taken.push_all(&m.pe_sig().generics.lifetimes);
                         Some(ii.id)
                     }
                     ast::TypeImplItem(_) => None,
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index fd6b28fd292..75e9c60698b 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -57,7 +57,7 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
                            impl_item: &ast::ImplItem,
                            impl_src: ast::DefId) -> bool {
     if attr::requests_inline(&impl_item.attrs) ||
-        generics_require_inlining(method.pe_generics()) {
+        generics_require_inlining(&method.pe_sig().generics) {
         return true
     }
     if is_local(impl_src) {
@@ -191,7 +191,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
             Some(ast_map::NodeImplItem(impl_item)) => {
                 match impl_item.node {
                     ast::MethodImplItem(ref method) => {
-                        if generics_require_inlining(method.pe_generics()) ||
+                        if generics_require_inlining(&method.pe_sig().generics) ||
                                 attr::requests_inline(&impl_item.attrs) {
                             true
                         } else {
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index e02f7861285..32d52bcbf74 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -149,7 +149,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                 })
             }
             visit::FkMethod(_, m) => {
-                self.visit_early_late(subst::FnSpace, m.pe_generics(), |this| {
+                self.visit_early_late(subst::FnSpace, &m.pe_sig().generics, |this| {
                     visit::walk_fn(this, fk, fd, b, s)
                 })
             }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 259a9acadc6..687b4cb8723 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -46,7 +46,7 @@ use std::{cmp, slice};
 use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
 
 use syntax::{abi, ast, ast_map};
-use syntax::ast_util::{self, is_shift_binop, local_def};
+use syntax::ast_util::{self, is_shift_binop, local_def, PostExpansionMethod};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::codemap::{self, Span};
 use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
@@ -1319,7 +1319,7 @@ impl LintPass for UnsafeCode {
                 cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
 
             visit::FkMethod(_, m) => {
-                if let ast::MethDecl(_, _, _, ast::Unsafety::Unsafe, _, _) = *m {
+                if m.pe_sig().unsafety == ast::Unsafety::Unsafe {
                     cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
                 }
             },
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 9cb9c1f2f85..9b069962de4 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -275,7 +275,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
                         match impl_item.node {
                             ast::MethodImplItem(ref method) => {
                                 let meth_public =
-                                    match method.pe_explicit_self().node {
+                                    match method.pe_sig().explicit_self.node {
                                         ast::SelfStatic => public_ty,
                                         _ => true,
                                     } && impl_item.vis == ast::Public;
@@ -1355,7 +1355,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     for impl_item in impl_items {
                         match impl_item.node {
                             ast::MethodImplItem(ref method) => {
-                                if method.pe_explicit_self().node ==
+                                if method.pe_sig().explicit_self.node ==
                                         ast::SelfStatic &&
                                         self.exported_items
                                             .contains(&impl_item.id) {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 67675a5a1ae..296a9794f1c 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -243,8 +243,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
                 ItemRibKind
             }
             visit::FkMethod(_, method) => {
-                self.visit_generics(method.pe_generics());
-                self.visit_explicit_self(method.pe_explicit_self());
+                self.visit_generics(&method.pe_sig().generics);
+                self.visit_explicit_self(&method.pe_sig().explicit_self);
                 MethodRibKind
             }
             visit::FkFnBlock(..) => ClosureRibKind(node_id)
@@ -2814,13 +2814,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         // FIXME #4951: Do we need a node ID here?
 
                         let type_parameters = match trait_item.node {
-                            ast::RequiredMethod(ref ty_m) => {
-                                HasTypeParameters(&ty_m.generics,
+                            ast::RequiredMethod(ref sig) => {
+                                HasTypeParameters(&sig.generics,
                                                   FnSpace,
                                                   MethodRibKind)
                             }
                             ast::ProvidedMethod(ref m) => {
-                                HasTypeParameters(m.pe_generics(),
+                                HasTypeParameters(&m.pe_sig().generics,
                                                   FnSpace,
                                                   MethodRibKind)
                             }
@@ -3075,7 +3075,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 // We also need a new scope for the method-
                                 // specific type parameters.
                                 let type_parameters =
-                                    HasTypeParameters(method.pe_generics(),
+                                    HasTypeParameters(&method.pe_sig().generics,
                                                       FnSpace,
                                                       MethodRibKind);
                                 this.with_type_parameter_rib(type_parameters, |this| {
@@ -3956,11 +3956,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 let explicit_self = match this.ast_map.get(did.node) {
                     ast_map::NodeTraitItem(trait_item) => match trait_item.node {
                         ast::RequiredMethod(ref m) => &m.explicit_self,
-                        ast::ProvidedMethod(ref m) => m.pe_explicit_self(),
+                        ast::ProvidedMethod(ref m) => &m.pe_sig().explicit_self,
                         _ => return false
                     },
                     ast_map::NodeImplItem(impl_item) => match impl_item.node {
-                        ast::MethodImplItem(ref m) => m.pe_explicit_self(),
+                        ast::MethodImplItem(ref m) => &m.pe_sig().explicit_self,
                         _ => return false
                     },
                     _ => return false
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 95365020964..2b1def22ed9 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -382,21 +382,21 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             decl_id,
                             scope_id);
 
-        self.process_formals(&method.pe_fn_decl().inputs, qualname);
+        self.process_formals(&method.pe_sig().decl.inputs, qualname);
 
         // walk arg and return types
-        for arg in &method.pe_fn_decl().inputs {
+        for arg in &method.pe_sig().decl.inputs {
             self.visit_ty(&*arg.ty);
         }
 
-        if let ast::Return(ref ret_ty) = method.pe_fn_decl().output {
+        if let ast::Return(ref ret_ty) = method.pe_sig().decl.output {
             self.visit_ty(&**ret_ty);
         }
 
         // walk the fn body
         self.nest(id, |v| v.visit_block(&*method.pe_body()));
 
-        self.process_generic_params(method.pe_generics(),
+        self.process_generic_params(&method.pe_sig().generics,
                                     span,
                                     qualname,
                                     id);
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 0b98beb53c5..11495c7e6a3 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -1292,7 +1292,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,
@@ -1308,8 +1308,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                     }
 
                     (impl_item.ident,
-                     method.pe_fn_decl(),
-                     method.pe_generics(),
+                     &method.pe_sig().decl,
+                     &method.pe_sig().generics,
                      method.pe_body(),
                      impl_item.span,
                      true)
@@ -1326,7 +1326,7 @@ 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,
@@ -1347,8 +1347,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                     }
 
                     (trait_item.ident,
-                     method.pe_fn_decl(),
-                     method.pe_generics(),
+                     &method.pe_sig().decl,
+                     &method.pe_sig().generics,
                      method.pe_body(),
                      trait_item.span,
                      true)
diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs
index 6c1401a4c02..eacc40edcc6 100644
--- a/src/librustc_trans/trans/inline.rs
+++ b/src/librustc_trans/trans/inline.rs
@@ -149,11 +149,11 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             if let ast::MethodImplItem(ref mth) = impl_item.node {
                 let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
                 if impl_tpt.generics.types.is_empty() &&
-                        mth.pe_generics().ty_params.is_empty() {
+                        mth.pe_sig().generics.ty_params.is_empty() {
                     let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
                     let llfn = get_item_val(ccx, impl_item.id);
                     trans_fn(ccx,
-                            &*mth.pe_fn_decl(),
+                            &*mth.pe_sig().decl,
                             &*mth.pe_body(),
                             llfn,
                             empty_substs,
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index aea922d9f9f..8df086fd232 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -80,13 +80,13 @@ pub fn trans_impl(ccx: &CrateContext,
     for impl_item in impl_items {
         match impl_item.node {
             ast::MethodImplItem(ref method) => {
-                if method.pe_generics().ty_params.len() == 0 {
+                if method.pe_sig().generics.ty_params.len() == 0 {
                     let trans_everywhere = attr::requests_inline(&impl_item.attrs);
                     for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
                         let llfn = get_item_val(ccx, impl_item.id);
                         let empty_substs = tcx.mk_substs(Substs::trans_empty());
                         trans_fn(ccx,
-                                 method.pe_fn_decl(),
+                                 &method.pe_sig().decl,
                                  method.pe_body(),
                                  llfn,
                                  empty_substs,
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 1af783373f9..80271a72c68 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -223,7 +223,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     let needs_body = setup_lldecl(d, &impl_item.attrs);
                     if needs_body {
                         trans_fn(ccx,
-                                 mth.pe_fn_decl(),
+                                 &mth.pe_sig().decl,
                                  mth.pe_body(),
                                  d,
                                  psubsts,
@@ -243,7 +243,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     let d = mk_lldecl(abi::Rust);
                     let needs_body = setup_lldecl(d, &trait_item.attrs);
                     if needs_body {
-                        trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d,
+                        trans_fn(ccx, &mth.pe_sig().decl, mth.pe_body(), d,
                                  psubsts, trait_item.id, &[]);
                     }
                     d
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 9c2bc4da64f..28e7027b212 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1442,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 3ffc36d3acb..470e1d54c7f 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -867,7 +867,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     debug!("check_method_body: fty={}", fty.repr(ccx.tcx));
 
     check_bare_fn(ccx,
-                  &*method.pe_fn_decl(),
+                  &*method.pe_sig().decl,
                   &*method.pe_body(),
                   id,
                   span,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index b90129f7ab7..a2ca228b11a 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -621,152 +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.node {
-                    ast::RequiredMethod(_) |
-                    ast::ProvidedMethod(_) => {
-                        let ty_method = Rc::new(match trait_item.node {
-                            ast::RequiredMethod(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &trait_predicates,
-                                    trait_item.id,
-                                    trait_item.ident,
-                                    &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_item.id,
-                                    trait_item.ident,
-                                    m.pe_explicit_self(),
-                                    m.pe_abi(),
-                                    m.pe_generics(),
-                                    &m.pe_unsafety(),
-                                    &*m.pe_fn_decl())
-                            }
-                            ast::TypeTraitItem(..) => unreachable!()
-                        });
-
-                        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(..) => {
-                        let trait_did = local_def(trait_id);
-                        let associated_type = ty::AssociatedType {
-                            name: trait_item.ident.name,
-                            vis: ast::Public,
-                            def_id: local_def(trait_item.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(|trait_item| {
-                let def_id = local_def(trait_item.id);
-                match trait_item.node {
-                    ast::RequiredMethod(_) |
-                    ast::ProvidedMethod(_) => {
-                        ty::MethodTraitItemId(def_id)
-                    }
-                    ast::TypeTraitItem(..) => {
-                        ty::TypeTraitItemId(def_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());
-    }
+    debug!("writing method type: def_id={:?} mty={}",
+            def_id, ty_method.repr(ccx.tcx));
 
-    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>,
-                                           m_id: ast::NodeId,
-                                           m_ident: ast::Ident,
-                                           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)
-        };
-
-        ty::Method::new(
-            m_ident.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>,
@@ -809,20 +709,19 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 }
 
 fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                                     trait_def: &ty::TraitDef<'tcx>,
+                                     container: ImplOrTraitItemContainer,
                                      ident: ast::Ident,
-                                     id: ast::NodeId)
+                                     id: ast::NodeId,
+                                     vis: ast::Visibility)
 {
     let associated_type = Rc::new(ty::AssociatedType {
         name: ident.name,
-        vis: ast::Public,
+        vis: vis,
         def_id: local_def(id),
-        container: TraitContainer(trait_def.trait_ref.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>,
@@ -830,9 +729,8 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
                                  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, ast::NodeId, ast::Ident, ast::Visibility, Span)>
+                                 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),
@@ -841,87 +739,20 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
 
     let tcx = ccx.tcx;
     let mut seen_methods = FnvHashSet();
-    for (m, id, ident, vis, span) in methods {
+    for (sig, id, ident, vis, span) in methods {
         if !seen_methods.insert(ident.name) {
-            span_err!(tcx.sess, span, E0201, "duplicate method in trait impl");
+            span_err!(tcx.sess, span, E0201, "duplicate method");
         }
 
-        let m_def_id = local_def(id);
-
-        let mty = Rc::new(ty_of_method(ccx,
-                                       container,
-                                       m,
-                                       id,
-                                       ident,
-                                       vis,
-                                       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 {}",
-                ident.repr(tcx),
-                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, 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,
-                              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>,
-                              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 = vis.inherit_from(rcvr_visibility);
-
-        ty::Method::new(ident.name,
-                        m_ty_generics,
-                        m_ty_generic_predicates,
-                        fty,
-                        explicit_self_category,
-                        method_vis,
-                        local_def(id),
-                        container,
-                        None)
+        convert_method(ccx,
+                       container,
+                       sig,
+                       id,
+                       ident,
+                       vis,
+                       untransformed_rcvr_ty,
+                       rcvr_ty_generics,
+                       rcvr_ty_predicates);
     }
 }
 
@@ -1013,6 +844,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                 it.vis
             };
 
+            // Convert all the associated types.
             for impl_item in impl_items {
                 match impl_item.node {
                     ast::MethodImplItem(_) => {}
@@ -1022,6 +854,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                                               "associated items are not allowed in inherent impls");
                         }
 
+                        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 {
@@ -1031,17 +866,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                         tcx.predicates.borrow_mut().insert(local_def(impl_item.id),
                                                            ty::GenericPredicates::empty());
                         write_ty_to_tcx(tcx, impl_item.id, typ);
-
-                        let associated_type = Rc::new(ty::AssociatedType {
-                            name: impl_item.ident.name,
-                            vis: impl_item.vis,
-                            def_id: local_def(impl_item.id),
-                            container: ty::ImplContainer(local_def(it.id)),
-                        });
-                        tcx.impl_or_trait_items
-                           .borrow_mut()
-                           .insert(local_def(impl_item.id),
-                                   ty::TypeTraitItem(associated_type));
                     }
                 }
             }
@@ -1049,7 +873,12 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             let methods = impl_items.iter().filter_map(|ii| {
                 match ii.node {
                     ast::MethodImplItem(ref m) => {
-                        Some((m, ii.id, ii.ident, ii.vis, ii.span))
+                        // if the method specifies a visibility, use that, otherwise
+                        // inherit the visibility from the impl (so `foo` in `pub impl
+                        // { fn foo(); }` is public, but private in `priv impl { fn
+                        // foo(); }`).
+                        let method_vis = ii.vis.inherit_from(parent_visibility);
+                        Some((m.pe_sig(), ii.id, ii.ident, method_vis, ii.span))
                     }
                     ast::TypeImplItem(_) => None
                 }
@@ -1059,8 +888,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                             methods,
                             selfty,
                             &ty_generics,
-                            &ty_predicates,
-                            parent_visibility);
+                            &ty_predicates);
 
             for impl_item in impl_items {
                 match impl_item.node {
@@ -1070,7 +898,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                                                &BindingRscope::new(),
                                                ccx.method_ty(impl_item.id),
                                                selfty,
-                                               method.pe_explicit_self(),
+                                               &method.pe_sig().explicit_self,
                                                body_id);
                     }
                     ast::TypeImplItem(_) => {}
@@ -1095,63 +923,68 @@ 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);
 
-            let methods = trait_items.iter().filter_map(|ti| {
-                match ti.node {
-                    ast::ProvidedMethod(ref m) => {
-                        Some((m, ti.id, ti.ident, ast::Inherited, ti.span))
-                    }
+            // Convert all the associated types.
+            for trait_item in trait_items {
+                match trait_item.node {
                     ast::RequiredMethod(_) |
-                    ast::TypeTraitItem(..) => None,
+                    ast::ProvidedMethod(_) => {}
+                    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::RequiredMethod(ref sig) => sig,
+                    ast::ProvidedMethod(ref m) => m.pe_sig(),
+                    ast::TypeTraitItem(..) => return None,
+                };
+                Some((sig, ti.id, ti.ident, ast::Inherited, ti.span))
             });
-            // Run convert_methods on the provided methods.
-            let untransformed_rcvr_ty = ty::mk_self_type(tcx);
+
+            // Run convert_methods on the trait methods.
             convert_methods(ccx,
                             TraitContainer(local_def(it.id)),
                             methods,
-                            untransformed_rcvr_ty,
+                            ty::mk_self_type(tcx),
                             &trait_def.generics,
-                            &trait_predicates,
-                            it.vis);
-
-            // 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);
+                            &trait_predicates);
 
-            // 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);
+            // 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::RequiredMethod(ref type_method) => {
-                        let rscope = BindingRscope::new();
-                        check_method_self_type(ccx,
-                                               &rscope,
-                                               ccx.method_ty(trait_item.id),
-                                               self_type,
-                                               &type_method.explicit_self,
-                                               it.id)
-                    }
-                    ast::ProvidedMethod(ref method) => {
-                        check_method_self_type(ccx,
-                                               &BindingRscope::new(),
-                                               ccx.method_ty(trait_item.id),
-                                               self_type,
-                                               method.pe_explicit_self(),
-                                               it.id)
+                    ast::RequiredMethod(_) |
+                    ast::ProvidedMethod(_) => {
+                        ty::MethodTraitItemId(def_id)
                     }
                     ast::TypeTraitItem(..) => {
-                        convert_associated_type(ccx,
-                                                &*trait_def,
-                                                trait_item.ident,
-                                                trait_item.id);
+                        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 sig = match trait_item.node {
+                    ast::RequiredMethod(ref sig) => sig,
+                    ast::ProvidedMethod(ref method) => method.pe_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, _) => {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 202b5f59fb7..05139bf1eab 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -951,8 +951,8 @@ pub struct Method {
 
 impl Clean<Method> for ast::Method {
     fn clean(&self, cx: &DocContext) -> Method {
-        let all_inputs = &self.pe_fn_decl().inputs;
-        let inputs = match self.pe_explicit_self().node {
+        let all_inputs = &self.pe_sig().decl.inputs;
+        let inputs = match self.pe_sig().explicit_self.node {
             ast::SelfStatic => &**all_inputs,
             _ => &all_inputs[1..]
         };
@@ -960,15 +960,15 @@ impl Clean<Method> for ast::Method {
             inputs: Arguments {
                 values: inputs.clean(cx),
             },
-            output: self.pe_fn_decl().output.clean(cx),
+            output: self.pe_sig().decl.output.clean(cx),
             attrs: Vec::new()
         };
         Method {
-            generics: self.pe_generics().clean(cx),
-            self_: self.pe_explicit_self().node.clean(cx),
-            unsafety: self.pe_unsafety().clone(),
+            generics: self.pe_sig().generics.clean(cx),
+            self_: self.pe_sig().explicit_self.node.clean(cx),
+            unsafety: self.pe_sig().unsafety.clone(),
             decl: decl,
-            abi: self.pe_abi()
+            abi: self.pe_sig().abi
         }
     }
 }
@@ -982,7 +982,7 @@ pub struct TyMethod {
     pub abi: abi::Abi
 }
 
-impl Clean<TyMethod> for ast::TypeMethod {
+impl Clean<TyMethod> for ast::MethodSig {
     fn clean(&self, cx: &DocContext) -> TyMethod {
         let inputs = match self.explicit_self.node {
             ast::SelfStatic => &*self.decl.inputs,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index bc1767fa3a4..0a08b0b1207 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1058,10 +1058,10 @@ 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 struct MethodSig {
     pub unsafety: Unsafety,
     pub abi: Abi,
     pub decl: P<FnDecl>,
@@ -1084,7 +1084,7 @@ pub struct TraitItem {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum TraitItem_ {
-    RequiredMethod(TypeMethod),
+    RequiredMethod(MethodSig),
     ProvidedMethod(Method),
     TypeTraitItem(TyParamBounds, Option<P<Ty>>),
 }
@@ -1419,12 +1419,7 @@ pub type ExplicitSelf = Spanned<ExplicitSelf_>;
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Method {
     /// Represents a method declaration
-    MethDecl(Generics,
-             Abi,
-             ExplicitSelf,
-             Unsafety,
-             P<FnDecl>,
-             P<Block>),
+    MethDecl(MethodSig, P<Block>),
     /// Represents a macro in method position
     MethMac(Mac),
 }
diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
index 053c3153340..345ccf902cd 100644
--- a/src/libsyntax/ast_map/blocks.rs
+++ b/src/libsyntax/ast_map/blocks.rs
@@ -162,7 +162,7 @@ impl<'a> FnLikeNode<'a> {
 
     pub fn decl(self) -> &'a FnDecl {
         self.handle(|i: ItemFnParts<'a>|  &*i.decl,
-                    |_, _, m: &'a ast::Method, _|  m.pe_fn_decl(),
+                    |_, _, m: &'a ast::Method, _|  &m.pe_sig().decl,
                     |c: ClosureParts<'a>| c.decl)
     }
 
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 673ea4ac431..91ddc8beec8 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;
@@ -461,7 +460,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
                 self.visit_generics_helper(generics)
             }
             visit::FkMethod(_, m) => {
-                self.visit_generics_helper(m.pe_generics())
+                self.visit_generics_helper(&m.pe_sig().generics)
             }
             visit::FkFnBlock => {}
         }
@@ -653,11 +652,7 @@ pub fn lit_is_str(lit: &Lit) -> bool {
 /// not a macro invocation. This check is guaranteed to succeed, assuming
 /// that the invocations are indeed gone.
 pub trait PostExpansionMethod {
-    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_sig<'a>(&'a self) -> &'a ast::MethodSig;
     fn pe_body<'a>(&'a self) -> &'a ast::Block;
 }
 
@@ -676,18 +671,8 @@ macro_rules! mf_method{
 
 
 impl PostExpansionMethod for Method {
-    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_sig, &'a ast::MethodSig,MethDecl(ref sig, _), sig }
+    mf_method! { pe_body, &'a ast::Block,MethDecl(_, ref body), body }
 }
 
 #[cfg(test)]
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index a4962afff3c..d4b0f7d1dcb 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -724,13 +724,13 @@ impl<'a> MethodDef<'a> {
             span: trait_.span,
             vis: ast::Inherited,
             ident: method_ident,
-            node: ast::MethodImplItem(
-                ast::MethDecl(fn_generics,
-                              abi,
-                              explicit_self,
-                              ast::Unsafety::Normal,
-                              fn_decl,
-                              body_block))
+            node: ast::MethodImplItem(ast::MethDecl(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 5fb0126cdd0..fa0b747f45b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1393,15 +1393,16 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
 
     fn fold_method(&mut self, m: ast::Method) -> ast::Method {
         match m {
-            ast::MethDecl(generics, abi, explicit_self, fn_style, decl, body) => {
+            ast::MethDecl(sig, body) => {
                 let (rewritten_fn_decl, rewritten_body)
-                    = expand_and_rename_fn_decl_and_block(decl, body, self);
-                ast::MethDecl(self.fold_generics(generics),
-                              abi,
-                              self.fold_explicit_self(explicit_self),
-                              fn_style,
-                              rewritten_fn_decl,
-                              rewritten_body)
+                    = expand_and_rename_fn_decl_and_block(sig.decl, body, self);
+                ast::MethDecl(ast::MethodSig {
+                    generics: self.fold_generics(sig.generics),
+                    abi: sig.abi,
+                    explicit_self: self.fold_explicit_self(sig.explicit_self),
+                    unsafety: sig.unsafety,
+                    decl: rewritten_fn_decl
+                }, rewritten_body)
             }
             ast::MethMac(mac) => ast::MethMac(mac)
         }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index d99f1600cb3..d7982ef8399 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -977,15 +977,7 @@ pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T)
         ident: folder.fold_ident(ident),
         attrs: fold_attrs(attrs, folder),
         node: match node {
-            RequiredMethod(TypeMethod { unsafety, abi, decl, generics, explicit_self }) => {
-                RequiredMethod(TypeMethod {
-                    unsafety: unsafety,
-                    abi: abi,
-                    decl: folder.fold_fn_decl(decl),
-                    generics: folder.fold_generics(generics),
-                    explicit_self: folder.fold_explicit_self(explicit_self)
-                })
-            }
+            RequiredMethod(sig) => RequiredMethod(noop_fold_method_sig(sig, folder)),
             ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)),
             TypeTraitItem(bounds, default) => {
                 TypeTraitItem(folder.fold_bounds(bounds),
@@ -1110,23 +1102,24 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
 // Default fold over a method.
 pub fn noop_fold_method<T: Folder>(method: Method, folder: &mut T) -> Method {
     match method {
-        MethDecl(generics,
-                 abi,
-                 explicit_self,
-                 unsafety,
-                 decl,
-                 body) => {
-            MethDecl(folder.fold_generics(generics),
-                     abi,
-                     folder.fold_explicit_self(explicit_self),
-                     unsafety,
-                     folder.fold_fn_decl(decl),
+        MethDecl(sig, body) => {
+            MethDecl(noop_fold_method_sig(sig, folder),
                      folder.fold_block(body))
         },
         MethMac(mac) => MethMac(folder.fold_mac(mac))
     }
 }
 
+pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
+    MethodSig {
+        generics: folder.fold_generics(sig.generics),
+        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> {
     p.map(|Pat {id, node, span}| Pat {
         id: folder.new_id(id),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index a38508d2cf5..2e77bd6df18 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -51,8 +51,7 @@ 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};
@@ -1341,31 +1340,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;
                 let node = match p.token {
                   token::Semi => {
                     p.bump();
                     debug!("parse_trait_methods(): parsing required method");
-                    RequiredMethod(TypeMethod {
-                        unsafety: style,
-                        decl: d,
-                        generics: generics,
-                        abi: abi,
-                        explicit_self: explicit_self,
-                    })
+                    RequiredMethod(sig)
                   }
                   token::OpenDelim(token::Brace) => {
                     debug!("parse_trait_methods(): parsing provided method");
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
                     attrs.push_all(&inner_attrs[..]);
-                    ProvidedMethod(ast::MethDecl(generics,
-                                                 abi,
-                                                 explicit_self,
-                                                 style,
-                                                 d,
-                                                 body))
+                    ProvidedMethod(ast::MethDecl(sig, body))
                   }
 
                   _ => {
@@ -4758,13 +4753,13 @@ impl<'a> Parser<'a> {
                 let body_span = body.span;
                 let mut new_attrs = attrs;
                 new_attrs.push_all(&inner_attrs[..]);
-                (ast::MethDecl(generics,
-                               abi,
-                               explicit_self,
-                               unsafety,
-                               decl,
-                               body),
-                 body_span.hi, new_attrs, ident)
+                (ast::MethDecl(ast::MethodSig {
+                    generics: generics,
+                    abi: abi,
+                    explicit_self: explicit_self,
+                    unsafety: unsafety,
+                    decl: decl
+                 }, body), body_span.hi, new_attrs, ident)
             }
         };
         P(ImplItem {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index a457355698d..20c8df42993 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -375,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
     })
@@ -759,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
@@ -861,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
@@ -1227,17 +1231,18 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_ty_method(&mut self,
-                           ident: ast::Ident,
-                           m: &ast::TypeMethod)
-                           -> io::Result<()> {
-        try!(self.print_ty_fn(m.abi,
-                              m.unsafety,
-                              &*m.decl,
-                              Some(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_item(&mut self, ti: &ast::TraitItem)
@@ -1246,8 +1251,9 @@ impl<'a> State<'a> {
         try!(self.maybe_print_comment(ti.span.lo));
         try!(self.print_outer_attributes(&ti.attrs));
         match ti.node {
-            ast::RequiredMethod(ref ty_m) => {
-                self.print_ty_method(ti.ident, ty_m)
+            ast::RequiredMethod(ref sig) => {
+                try!(self.print_method_sig(ti.ident, sig, ast::Inherited));
+                word(&mut self.s, ";")
             }
             ast::ProvidedMethod(ref m) => {
                 self.print_method(ti.ident, &ti.attrs, ast::Inherited, m)
@@ -1280,20 +1286,10 @@ impl<'a> State<'a> {
                         meth: &ast::Method)
                         -> io::Result<()> {
         match *meth {
-            ast::MethDecl(ref generics,
-                          abi,
-                          ref explicit_self,
-                          unsafety,
-                          ref decl,
-                          ref body) => {
-                try!(self.print_fn(&**decl,
-                                   Some(unsafety),
-                                   abi,
-                                   ident,
-                                   generics,
-                                   Some(&explicit_self.node),
-                                   vis));
-                try!(word(&mut self.s, " "));
+            ast::MethDecl(ref sig, ref body) => {
+                try!(self.head(""));
+                try!(self.print_method_sig(ident, sig, vis));
+                try!(self.nbsp());
                 self.print_block_with_attrs(&**body, attrs)
             },
             ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
@@ -2328,16 +2324,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)
@@ -2704,25 +2702,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()
     }
 
@@ -2944,14 +2931,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<()> {
@@ -2977,11 +2956,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 867f98f6077..4375e17ce0b 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -602,11 +602,11 @@ fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V,
                                           span: Span,
                                           method: &'v Method) {
     match *method {
-        MethDecl(_, _, _, _, ref decl, ref body) => {
+        MethDecl(ref sig, ref body) => {
             visitor.visit_ident(span, ident);
             visitor.visit_fn(FkMethod(ident, method),
-                             &**decl,
-                             &**body,
+                             &sig.decl,
+                             body,
                              span,
                              id);
         },
@@ -627,9 +627,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
         }
         FkMethod(_, method) => {
             match *method {
-                MethDecl(ref generics, _, ref explicit_self, _, _, _) => {
-                    visitor.visit_generics(generics);
-                    visitor.visit_explicit_self(explicit_self);
+                MethDecl(ref sig, _) => {
+                    visitor.visit_generics(&sig.generics);
+                    visitor.visit_explicit_self(&sig.explicit_self);
                 }
                 MethMac(ref mac) => visitor.visit_mac(mac)
             }
@@ -646,10 +646,10 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
         visitor.visit_attribute(attr);
     }
     match trait_item.node {
-        RequiredMethod(ref method_type) => {
-            visitor.visit_explicit_self(&method_type.explicit_self);
-            visitor.visit_generics(&method_type.generics);
-            walk_fn_decl(visitor, &method_type.decl);
+        RequiredMethod(ref sig) => {
+            visitor.visit_explicit_self(&sig.explicit_self);
+            visitor.visit_generics(&sig.generics);
+            walk_fn_decl(visitor, &sig.decl);
         }
         ProvidedMethod(ref method) => {
             walk_method_helper(visitor,
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
     }
 }