about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-08-04 13:56:56 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-08-14 11:40:22 -0700
commit9907fa4acc2af5b2b07d1362b3ceb29171954c58 (patch)
tree6acf4c541c9321d8a304eb16f486b09755983c52
parent404978ea722c0257cc763540c93243e8a21f82ed (diff)
downloadrust-9907fa4acc2af5b2b07d1362b3ceb29171954c58.tar.gz
rust-9907fa4acc2af5b2b07d1362b3ceb29171954c58.zip
librustc: Stop assuming that implementations and traits only contain
methods.

This paves the way to associated items by introducing an extra level of
abstraction ("impl-or-trait item") between traits/implementations and
methods. This new abstraction is encoded in the metadata and used
throughout the compiler where appropriate.

There are no functional changes; this is purely a refactoring.
-rw-r--r--src/librustc/front/config.rs26
-rw-r--r--src/librustc/lint/builtin.rs28
-rw-r--r--src/librustc/lint/context.rs4
-rw-r--r--src/librustc/lint/mod.rs2
-rw-r--r--src/librustc/metadata/common.rs16
-rw-r--r--src/librustc/metadata/csearch.rs44
-rw-r--r--src/librustc/metadata/decoder.rs181
-rw-r--r--src/librustc/metadata/encoder.rs265
-rw-r--r--src/librustc/middle/astencode.rs59
-rw-r--r--src/librustc/middle/dead.rs50
-rw-r--r--src/librustc/middle/expr_use_visitor.rs6
-rw-r--r--src/librustc/middle/privacy.rs136
-rw-r--r--src/librustc/middle/reachable.rs61
-rw-r--r--src/librustc/middle/resolve.rs213
-rw-r--r--src/librustc/middle/save/mod.rs153
-rw-r--r--src/librustc/middle/stability.rs17
-rw-r--r--src/librustc/middle/trans/base.rs62
-rw-r--r--src/librustc/middle/trans/callee.rs72
-rw-r--r--src/librustc/middle/trans/debuginfo.rs22
-rw-r--r--src/librustc/middle/trans/inline.rs51
-rw-r--r--src/librustc/middle/trans/meth.rs143
-rw-r--r--src/librustc/middle/trans/monomorphize.rs24
-rw-r--r--src/librustc/middle/trans/reflect.rs18
-rw-r--r--src/librustc/middle/ty.rs248
-rw-r--r--src/librustc/middle/typeck/check/method.rs98
-rw-r--r--src/librustc/middle/typeck/check/mod.rs141
-rw-r--r--src/librustc/middle/typeck/coherence.rs82
-rw-r--r--src/librustc/middle/typeck/collect.rs146
-rw-r--r--src/librustc/middle/typeck/infer/error_reporting.rs29
-rw-r--r--src/librustc/middle/typeck/variance.rs16
-rw-r--r--src/librustc/util/ppaux.rs4
-rw-r--r--src/librustc_back/svh.rs4
-rw-r--r--src/librustdoc/clean/inline.rs60
-rw-r--r--src/librustdoc/clean/mod.rs57
-rw-r--r--src/librustdoc/doctree.rs4
-rw-r--r--src/librustdoc/fold.rs20
-rw-r--r--src/librustdoc/html/render.rs45
-rw-r--r--src/librustdoc/passes.rs2
-rw-r--r--src/librustdoc/stability_summary.rs25
-rw-r--r--src/librustdoc/visit_ast.rs8
-rw-r--r--src/libsyntax/ast.rs23
-rw-r--r--src/libsyntax/ast_map/blocks.rs18
-rw-r--r--src/libsyntax/ast_map/mod.rs152
-rw-r--r--src/libsyntax/ast_util.rs75
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs9
-rw-r--r--src/libsyntax/fold.rs25
-rw-r--r--src/libsyntax/parse/parser.rs40
-rw-r--r--src/libsyntax/print/pprust.rs29
-rw-r--r--src/libsyntax/visit.rs33
49 files changed, 1926 insertions, 1120 deletions
diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs
index ab363a88db2..93320caf5f2 100644
--- a/src/librustc/front/config.rs
+++ b/src/librustc/front/config.rs
@@ -109,10 +109,14 @@ fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
 
 fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
     let item = match *item {
-        ast::ItemImpl(ref a, ref b, c, ref methods) => {
-            let methods = methods.iter().filter(|m| method_in_cfg(cx, &***m))
-                .map(|x| *x).collect();
-            ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
+        ast::ItemImpl(ref a, ref b, c, ref impl_items) => {
+            let impl_items = impl_items.iter()
+                                       .filter(|ii| {
+                                           impl_item_in_cfg(cx, &**ii)
+                                       })
+                                       .map(|x| *x)
+                                       .collect();
+            ast::ItemImpl((*a).clone(), (*b).clone(), c, impl_items)
         }
         ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
             let methods = methods.iter()
@@ -230,14 +234,16 @@ fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn method_in_cfg(cx: &mut Context, meth: &ast::Method) -> bool {
-    return (cx.in_cfg)(meth.attrs.as_slice());
+fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
+    match *meth {
+        ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
+        ast::ProvidedMethod(meth) => (cx.in_cfg)(meth.attrs.as_slice())
+    }
 }
 
-fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitMethod) -> bool {
-    match *meth {
-        ast::Required(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
-        ast::Provided(meth) => (cx.in_cfg)(meth.attrs.as_slice())
+fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool {
+    match *impl_item {
+        ast::MethodImplItem(meth) => (cx.in_cfg)(meth.attrs.as_slice()),
     }
 }
 
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index f929860c686..d08e2ce527f 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -801,15 +801,19 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
         node: m.id
     };
 
-    match cx.tcx.methods.borrow().find_copy(&did) {
+    match cx.tcx.impl_or_trait_items.borrow().find_copy(&did) {
         None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
         Some(md) => {
-            match md.container {
-                ty::TraitContainer(..) => TraitDefaultImpl,
-                ty::ImplContainer(cid) => {
-                    match ty::impl_trait_ref(cx.tcx, cid) {
-                        Some(..) => TraitImpl,
-                        None => PlainImpl
+            match md {
+                ty::MethodTraitItem(md) => {
+                    match md.container {
+                        ty::TraitContainer(..) => TraitDefaultImpl,
+                        ty::ImplContainer(cid) => {
+                            match ty::impl_trait_ref(cx.tcx, cid) {
+                                Some(..) => TraitImpl,
+                                None => PlainImpl
+                            }
+                        }
                     }
                 }
             }
@@ -1470,7 +1474,15 @@ impl LintPass for Stability {
                                 trait_id: trait_id,
                                 method_num: index,
                                 ..
-                            }) => ty::trait_method(cx.tcx, trait_id, index).def_id
+                            }) => {
+                                match ty::trait_item(cx.tcx,
+                                                     trait_id,
+                                                     index) {
+                                    ty::MethodTraitItem(method) => {
+                                        method.def_id
+                                    }
+                                }
+                            }
                         }
                     }
                     None => return
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 59a6b08638e..cf018927f70 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -563,9 +563,9 @@ impl<'a> Visitor<()> for Context<'a> {
         visit::walk_generics(self, g, ());
     }
 
-    fn visit_trait_method(&mut self, m: &ast::TraitMethod, _: ()) {
+    fn visit_trait_item(&mut self, m: &ast::TraitItem, _: ()) {
         run_lints!(self, check_trait_method, m);
-        visit::walk_trait_method(self, m, ());
+        visit::walk_trait_item(self, m, ());
     }
 
     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 1bf77b42bec..dbdda96dcb8 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -141,7 +141,7 @@ pub trait LintPass {
     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_method(&mut self, _: &Context, _: &ast::TraitMethod) { }
+    fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { }
     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/common.rs b/src/librustc/metadata/common.rs
index 7d0a21b2f8e..6a1c7c6c951 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -77,7 +77,7 @@ pub static tag_crate_dep_hash: uint = 0x1e;
 
 pub static tag_mod_impl: uint = 0x1f;
 
-pub static tag_item_trait_method: uint = 0x20;
+pub static tag_item_trait_item: uint = 0x20;
 
 pub static tag_item_trait_ref: uint = 0x21;
 pub static tag_item_super_trait_ref: uint = 0x22;
@@ -95,14 +95,14 @@ pub static tag_item_field_origin: uint = 0x29;
 
 pub static tag_item_variances: uint = 0x2a;
 /*
-  trait items contain tag_item_trait_method elements,
-  impl items contain tag_item_impl_method elements, and classes
+  trait items contain tag_item_trait_item elements,
+  impl items contain tag_item_impl_item elements, and classes
   have both. That's because some code treats classes like traits,
   and other code treats them like impls. Because classes can contain
-  both, tag_item_trait_method and tag_item_impl_method have to be two
+  both, tag_item_trait_item and tag_item_impl_item have to be two
   different tags.
  */
-pub static tag_item_impl_method: uint = 0x30;
+pub static tag_item_impl_item: uint = 0x30;
 pub static tag_item_trait_method_explicit_self: uint = 0x31;
 
 
@@ -154,9 +154,11 @@ impl astencode_tag {
     }
 }
 
-pub static tag_item_trait_method_sort: uint = 0x60;
+pub static tag_item_trait_item_sort: uint = 0x60;
 
-pub static tag_item_impl_type_basename: uint = 0x61;
+pub static tag_item_trait_parent_sort: uint = 0x61;
+
+pub static tag_item_impl_type_basename: uint = 0x62;
 
 pub static tag_crate_triple: uint = 0x66;
 
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 252d19bbb23..ac161ef8bde 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -16,6 +16,7 @@ use metadata::common::*;
 use metadata::cstore;
 use metadata::decoder;
 use middle::lang_items;
+use middle::resolve;
 use middle::ty;
 use middle::typeck;
 use middle::subst::VecPerParamSpace;
@@ -121,30 +122,33 @@ pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
 }
 
 /// Returns information about the given implementation.
-pub fn get_impl_methods(cstore: &cstore::CStore, impl_def_id: ast::DefId)
-                        -> Vec<ast::DefId> {
+pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: ast::DefId)
+                      -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(impl_def_id.krate);
-    decoder::get_impl_methods(&*cdata, impl_def_id.node)
+    decoder::get_impl_items(&*cdata, impl_def_id.node)
 }
 
-pub fn get_method(tcx: &ty::ctxt, def: ast::DefId) -> ty::Method {
+pub fn get_impl_or_trait_item(tcx: &ty::ctxt, def: ast::DefId)
+                              -> ty::ImplOrTraitItem {
     let cdata = tcx.sess.cstore.get_crate_data(def.krate);
-    decoder::get_method(tcx.sess.cstore.intr.clone(), &*cdata, def.node, tcx)
+    decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
+                                    &*cdata,
+                                    def.node,
+                                    tcx)
 }
 
-pub fn get_method_name_and_explicit_self(cstore: &cstore::CStore,
-                                         def: ast::DefId)
-                                         -> (ast::Ident,
-                                             ty::ExplicitSelfCategory)
-{
+pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
+                                    -> (ast::Ident, resolve::TraitItemKind) {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_method_name_and_explicit_self(cstore.intr.clone(), &*cdata, def.node)
+    decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
+                                          &*cdata,
+                                          def.node)
 }
 
-pub fn get_trait_method_def_ids(cstore: &cstore::CStore,
-                                def: ast::DefId) -> Vec<ast::DefId> {
+pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId)
+                              -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_method_def_ids(&*cdata, def.node)
+    decoder::get_trait_item_def_ids(&*cdata, def.node)
 }
 
 pub fn get_item_variances(cstore: &cstore::CStore,
@@ -286,15 +290,15 @@ pub fn each_implementation_for_trait(cstore: &cstore::CStore,
     decoder::each_implementation_for_trait(&*cdata, def_id.node, callback)
 }
 
-/// If the given def ID describes a method belonging to a trait (either a
+/// If the given def ID describes an item belonging to a trait (either a
 /// default method or an implementation of a trait method), returns the ID of
 /// the trait that the method belongs to. Otherwise, returns `None`.
-pub fn get_trait_of_method(cstore: &cstore::CStore,
-                           def_id: ast::DefId,
-                           tcx: &ty::ctxt)
-                           -> Option<ast::DefId> {
+pub fn get_trait_of_item(cstore: &cstore::CStore,
+                         def_id: ast::DefId,
+                         tcx: &ty::ctxt)
+                         -> Option<ast::DefId> {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_trait_of_method(&*cdata, def_id.node, tcx)
+    decoder::get_trait_of_item(&*cdata, def_id.node, tcx)
 }
 
 pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index c9807a18383..74810261d4a 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -18,11 +18,12 @@ use metadata::common::*;
 use metadata::csearch::StaticMethodInfo;
 use metadata::csearch;
 use metadata::cstore;
-use metadata::tydecode::{parse_ty_data, parse_def_id,
-                         parse_type_param_def_data,
-                         parse_bare_fn_ty_data, parse_trait_ref_data};
-use middle::lang_items;
+use metadata::tydecode::{parse_ty_data, parse_def_id};
+use metadata::tydecode::{parse_type_param_def_data, parse_bare_fn_ty_data};
+use metadata::tydecode::{parse_trait_ref_data};
 use middle::def;
+use middle::lang_items;
+use middle::resolve::TraitItemKind;
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty;
@@ -165,9 +166,9 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
     }
 }
 
-fn item_method_sort(item: rbml::Doc) -> char {
+fn item_sort(item: rbml::Doc) -> char {
     let mut ret = 'r';
-    reader::tagged_docs(item, tag_item_trait_method_sort, |doc| {
+    reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
         ret = doc.as_str_slice().as_bytes()[0] as char;
         false
     });
@@ -338,15 +339,18 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         UnsafeFn  => DlDef(def::DefFn(did, ast::UnsafeFn)),
         Fn        => DlDef(def::DefFn(did, ast::NormalFn)),
         StaticMethod | UnsafeStaticMethod => {
-            let fn_style = if fam == UnsafeStaticMethod { ast::UnsafeFn } else
-                { ast::NormalFn };
+            let fn_style = if fam == UnsafeStaticMethod {
+                ast::UnsafeFn
+            } else {
+                ast::NormalFn
+            };
             // def_static_method carries an optional field of its enclosing
             // trait or enclosing impl (if this is an inherent static method).
             // So we need to detect whether this is in a trait or not, which
             // we do through the mildly hacky way of checking whether there is
-            // a trait_method_sort.
+            // a trait_parent_sort.
             let provenance = if reader::maybe_get_doc(
-                  item, tag_item_trait_method_sort).is_some() {
+                  item, tag_item_trait_parent_sort).is_some() {
                 def::FromTrait(item_reqd_and_translated_parent_item(cnum,
                                                                     item))
             } else {
@@ -536,14 +540,11 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
             None => {}
             Some(inherent_impl_doc) => {
                 let _ = reader::tagged_docs(inherent_impl_doc,
-                                            tag_item_impl_method,
-                                            |impl_method_def_id_doc| {
-                    let impl_method_def_id =
-                        reader::with_doc_data(impl_method_def_id_doc,
-                                              parse_def_id);
-                    let impl_method_def_id =
-                        translate_def_id(cdata, impl_method_def_id);
-                    match maybe_find_item(impl_method_def_id.node, items) {
+                                            tag_item_impl_item,
+                                            |impl_item_def_id_doc| {
+                    let impl_item_def_id = item_def_id(impl_item_def_id_doc,
+                                                       cdata);
+                    match maybe_find_item(impl_item_def_id.node, items) {
                         None => {}
                         Some(impl_method_doc) => {
                             match item_family(impl_method_doc) {
@@ -554,7 +555,7 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
                                         item_name(&*intr, impl_method_doc);
                                     let static_method_def_like =
                                         item_to_def_like(impl_method_doc,
-                                                         impl_method_def_id,
+                                                         impl_item_def_id,
                                                          cdata.cnum);
                                     callback(static_method_def_like,
                                              static_method_name,
@@ -752,33 +753,46 @@ fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
     }
 }
 
-/// Returns information about the given implementation.
-pub fn get_impl_methods(cdata: Cmd, impl_id: ast::NodeId) -> Vec<ast::DefId> {
-    let mut methods = Vec::new();
+/// Returns the def IDs of all the items in the given implementation.
+pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
+                      -> Vec<ty::ImplOrTraitItemId> {
+    let mut impl_items = Vec::new();
     reader::tagged_docs(lookup_item(impl_id, cdata.data()),
-                        tag_item_impl_method, |doc| {
-        let m_did = reader::with_doc_data(doc, parse_def_id);
-        methods.push(translate_def_id(cdata, m_did));
+                        tag_item_impl_item, |doc| {
+        let def_id = item_def_id(doc, cdata);
+        match item_sort(doc) {
+            'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
+            _ => fail!("unknown impl item sort"),
+        }
         true
     });
 
-    methods
+    impl_items
 }
 
-pub fn get_method_name_and_explicit_self(intr: Rc<IdentInterner>,
-                                         cdata: Cmd,
-                                         id: ast::NodeId)
-                                         -> (ast::Ident,
-                                             ty::ExplicitSelfCategory) {
-    let method_doc = lookup_item(id, cdata.data());
-    let name = item_name(&*intr, method_doc);
-    let explicit_self = get_explicit_self(method_doc);
-    (name, explicit_self)
+pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
+                                    cdata: Cmd,
+                                    id: ast::NodeId)
+                                    -> (ast::Ident, TraitItemKind) {
+    let doc = lookup_item(id, cdata.data());
+    let name = item_name(&*intr, doc);
+    match item_sort(doc) {
+        'r' | 'p' => {
+            let explicit_self = get_explicit_self(doc);
+            (name, TraitItemKind::from_explicit_self_category(explicit_self))
+        }
+        c => {
+            fail!("get_trait_item_name_and_kind(): unknown trait item kind \
+                   in metadata: `{}`", c)
+        }
+    }
 }
 
-pub fn get_method(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
-                  tcx: &ty::ctxt) -> ty::Method
-{
+pub fn get_impl_or_trait_item(intr: Rc<IdentInterner>,
+                              cdata: Cmd,
+                              id: ast::NodeId,
+                              tcx: &ty::ctxt)
+                              -> ty::ImplOrTraitItem {
     let method_doc = lookup_item(id, cdata.data());
     let def_id = item_def_id(method_doc, cdata);
 
@@ -791,36 +805,45 @@ pub fn get_method(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
     };
 
     let name = item_name(&*intr, method_doc);
-    let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
-                                             tag_item_method_tps);
-    let rp_defs = item_region_param_defs(method_doc, cdata);
-    let fty = doc_method_fty(method_doc, tcx, cdata);
-    let vis = item_visibility(method_doc);
-    let explicit_self = get_explicit_self(method_doc);
-    let provided_source = get_provided_source(method_doc, cdata);
-
-    ty::Method::new(
-        name,
-        ty::Generics {
-            types: type_param_defs,
-            regions: rp_defs,
-        },
-        fty,
-        explicit_self,
-        vis,
-        def_id,
-        container,
-        provided_source
-    )
-}
-
-pub fn get_trait_method_def_ids(cdata: Cmd,
-                                id: ast::NodeId) -> Vec<ast::DefId> {
+
+    match item_sort(method_doc) {
+        'r' | 'p' => {
+            let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
+                                                     tag_item_method_tps);
+            let rp_defs = item_region_param_defs(method_doc, cdata);
+            let fty = doc_method_fty(method_doc, tcx, cdata);
+            let vis = item_visibility(method_doc);
+            let explicit_self = get_explicit_self(method_doc);
+            let provided_source = get_provided_source(method_doc, cdata);
+
+            let generics = ty::Generics {
+                types: type_param_defs,
+                regions: rp_defs,
+            };
+            ty::MethodTraitItem(Rc::new(ty::Method::new(name,
+                                                        generics,
+                                                        fty,
+                                                        explicit_self,
+                                                        vis,
+                                                        def_id,
+                                                        container,
+                                                        provided_source)))
+        }
+        _ => fail!("unknown impl/trait item sort"),
+    }
+}
+
+pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
+                              -> Vec<ty::ImplOrTraitItemId> {
     let data = cdata.data();
     let item = lookup_item(id, data);
     let mut result = Vec::new();
-    reader::tagged_docs(item, tag_item_trait_method, |mth| {
-        result.push(item_def_id(mth, cdata));
+    reader::tagged_docs(item, tag_item_trait_item, |mth| {
+        let def_id = item_def_id(mth, cdata);
+        match item_sort(mth) {
+            'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
+            _ => fail!("unknown trait item sort"),
+        }
         true
     });
     result
@@ -834,19 +857,29 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
     Decodable::decode(&mut decoder).unwrap()
 }
 
-pub fn get_provided_trait_methods(intr: Rc<IdentInterner>, cdata: Cmd,
-                                  id: ast::NodeId, tcx: &ty::ctxt)
+pub fn get_provided_trait_methods(intr: Rc<IdentInterner>,
+                                  cdata: Cmd,
+                                  id: ast::NodeId,
+                                  tcx: &ty::ctxt)
                                   -> Vec<Rc<ty::Method>> {
     let data = cdata.data();
     let item = lookup_item(id, data);
     let mut result = Vec::new();
 
-    reader::tagged_docs(item, tag_item_trait_method, |mth_id| {
+    reader::tagged_docs(item, tag_item_trait_item, |mth_id| {
         let did = item_def_id(mth_id, cdata);
         let mth = lookup_item(did.node, data);
 
-        if item_method_sort(mth) == 'p' {
-            result.push(Rc::new(get_method(intr.clone(), cdata, did.node, tcx)));
+        if item_sort(mth) == 'p' {
+            let trait_item = get_impl_or_trait_item(intr.clone(),
+                                                    cdata,
+                                                    did.node,
+                                                    tcx);
+            match trait_item {
+                ty::MethodTraitItem(ref method) => {
+                    result.push((*method).clone())
+                }
+            }
         }
         true
     });
@@ -905,8 +938,8 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
     if !ret { return None }
 
     let mut impl_method_ids = Vec::new();
-    reader::tagged_docs(item, tag_item_impl_method, |impl_method_doc| {
-        impl_method_ids.push(reader::with_doc_data(impl_method_doc, parse_def_id));
+    reader::tagged_docs(item, tag_item_impl_item, |impl_method_doc| {
+        impl_method_ids.push(item_def_id(impl_method_doc, cdata));
         true
     });
 
@@ -1230,8 +1263,8 @@ pub fn each_implementation_for_trait(cdata: Cmd,
     });
 }
 
-pub fn get_trait_of_method(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
-                           -> Option<ast::DefId> {
+pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
+                         -> Option<ast::DefId> {
     let item_doc = lookup_item(id, cdata.data());
     let parent_item_id = match item_parent_item(item_doc) {
         None => return None,
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 1b47227fea4..1d426aaaf5c 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -54,13 +54,19 @@ use syntax;
 use rbml::writer;
 use rbml::io::SeekableMemWriter;
 
-/// A borrowed version of ast::InlinedItem.
+/// A borrowed version of `ast::InlinedItem`.
 pub enum InlinedItemRef<'a> {
     IIItemRef(&'a ast::Item),
-    IIMethodRef(ast::DefId, bool, &'a ast::Method),
+    IITraitItemRef(ast::DefId, InlinedTraitItemRef<'a>),
     IIForeignRef(&'a ast::ForeignItem)
 }
 
+/// A borrowed version of `ast::InlinedTraitItem`.
+pub enum InlinedTraitItemRef<'a> {
+    ProvidedInlinedTraitItemRef(&'a Method),
+    RequiredInlinedTraitItemRef(&'a Method),
+}
+
 pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
 
 pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
@@ -403,14 +409,24 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
                                          rbml_w: &mut Encoder,
                                          exp: &middle::resolve::Export2)
                                          -> bool {
-    let impl_methods = ecx.tcx.impl_methods.borrow();
+    let impl_items = ecx.tcx.impl_items.borrow();
     match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) {
         Some(implementations) => {
             for base_impl_did in implementations.borrow().iter() {
-                for &method_did in impl_methods.get(base_impl_did).iter() {
-                    let m = ty::method(ecx.tcx, method_did);
-                    if m.explicit_self == ty::StaticExplicitSelfCategory {
-                        encode_reexported_static_method(rbml_w, exp, m.def_id, m.ident);
+                for &method_did in impl_items.get(base_impl_did).iter() {
+                    let impl_item = ty::impl_or_trait_item(
+                        ecx.tcx,
+                        method_did.def_id());
+                    match impl_item {
+                        ty::MethodTraitItem(ref m) => {
+                            if m.explicit_self ==
+                                    ty::StaticExplicitSelfCategory {
+                                encode_reexported_static_method(rbml_w,
+                                                                exp,
+                                                                m.def_id,
+                                                                m.ident);
+                            }
+                        }
                     }
                 }
             }
@@ -425,11 +441,18 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
                                           rbml_w: &mut Encoder,
                                           exp: &middle::resolve::Export2)
                                           -> bool {
-    match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
-        Some(methods) => {
-            for m in methods.iter() {
-                if m.explicit_self == ty::StaticExplicitSelfCategory {
-                    encode_reexported_static_method(rbml_w, exp, m.def_id, m.ident);
+    match ecx.tcx.trait_items_cache.borrow().find(&exp.def_id) {
+        Some(trait_items) => {
+            for trait_item in trait_items.iter() {
+                match *trait_item {
+                    ty::MethodTraitItem(ref m) if m.explicit_self ==
+                            ty::StaticExplicitSelfCategory => {
+                        encode_reexported_static_method(rbml_w,
+                                                        exp,
+                                                        m.def_id,
+                                                        m.ident);
+                    }
+                    _ => {}
                 }
             }
 
@@ -675,8 +698,14 @@ fn encode_explicit_self(rbml_w: &mut Encoder,
     }
 }
 
-fn encode_method_sort(rbml_w: &mut Encoder, sort: char) {
-    rbml_w.start_tag(tag_item_trait_method_sort);
+fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
+    rbml_w.start_tag(tag_item_trait_item_sort);
+    rbml_w.writer.write(&[ sort as u8 ]);
+    rbml_w.end_tag();
+}
+
+fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
+    rbml_w.start_tag(tag_item_trait_parent_sort);
     rbml_w.writer.write(&[ sort as u8 ]);
     rbml_w.end_tag();
 }
@@ -799,6 +828,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
 
     encode_method_ty_fields(ecx, rbml_w, m);
     encode_parent_item(rbml_w, local_def(parent_id));
+    encode_item_sort(rbml_w, 'r');
 
     let stab = stability::lookup(ecx.tcx, m.def_id);
     encode_stability(rbml_w, stab);
@@ -819,9 +849,11 @@ fn encode_info_for_method(ecx: &EncodeContext,
     for &ast_method in ast_method_opt.iter() {
         let any_types = !pty.generics.types.is_empty();
         if any_types || is_default_impl || should_inline(ast_method.attrs.as_slice()) {
-            encode_inlined_item(ecx, rbml_w,
-                                IIMethodRef(local_def(parent_id), false,
-                                            &*ast_method));
+            encode_inlined_item(ecx,
+                                rbml_w,
+                                IITraitItemRef(local_def(parent_id),
+                                               RequiredInlinedTraitItemRef(
+                                                   &*ast_method)));
         } else {
             encode_symbol(ecx, rbml_w, m.def_id.node);
         }
@@ -1106,11 +1138,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
             None => {}
         }
       }
-      ItemImpl(_, ref opt_trait, ty, ref ast_methods) => {
+      ItemImpl(_, ref opt_trait, ty, ref ast_items) => {
         // We need to encode information about the default methods we
         // have inherited, so we drive this based on the impl structure.
-        let impl_methods = tcx.impl_methods.borrow();
-        let methods = impl_methods.get(&def_id);
+        let impl_items = tcx.impl_items.borrow();
+        let items = impl_items.get(&def_id);
 
         add_to_index(item, rbml_w, index);
         rbml_w.start_tag(tag_items_data_item);
@@ -1128,10 +1160,14 @@ fn encode_info_for_item(ecx: &EncodeContext,
             }
             _ => {}
         }
-        for &method_def_id in methods.iter() {
-            rbml_w.start_tag(tag_item_impl_method);
-            let s = def_to_string(method_def_id);
-            rbml_w.writer.write(s.as_bytes());
+        for &item_def_id in items.iter() {
+            rbml_w.start_tag(tag_item_impl_item);
+            match item_def_id {
+                ty::MethodTraitItemId(item_def_id) => {
+                    encode_def_id(rbml_w, item_def_id);
+                    encode_item_sort(rbml_w, 'r');
+                }
+            }
             rbml_w.end_tag();
         }
         for ast_trait_ref in opt_trait.iter() {
@@ -1145,27 +1181,46 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_stability(rbml_w, stab);
         rbml_w.end_tag();
 
-        // Iterate down the methods, emitting them. We rely on the
-        // assumption that all of the actually implemented methods
+        // Iterate down the trait items, emitting them. We rely on the
+        // assumption that all of the actually implemented trait items
         // appear first in the impl structure, in the same order they do
         // in the ast. This is a little sketchy.
-        let num_implemented_methods = ast_methods.len();
-        for (i, &method_def_id) in methods.iter().enumerate() {
-            let ast_method = if i < num_implemented_methods {
-                Some(*ast_methods.get(i))
-            } else { None };
+        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.get(i))
+            } else {
+                None
+            };
 
             index.push(entry {
-                val: method_def_id.node as i64,
+                val: trait_item_def_id.def_id().node as i64,
                 pos: rbml_w.writer.tell().unwrap(),
             });
-            encode_info_for_method(ecx,
-                                   rbml_w,
-                                   &*ty::method(tcx, method_def_id),
-                                   path.clone(),
-                                   false,
-                                   item.id,
-                                   ast_method)
+
+            let trait_item_type =
+                ty::impl_or_trait_item(tcx, trait_item_def_id.def_id());
+            match (trait_item_type, ast_item) {
+                (ty::MethodTraitItem(method_type),
+                 Some(ast::MethodImplItem(ast_method))) => {
+                    encode_info_for_method(ecx,
+                                           rbml_w,
+                                           &*method_type,
+                                           path.clone(),
+                                           false,
+                                           item.id,
+                                           Some(ast_method))
+                }
+                (ty::MethodTraitItem(method_type), None) => {
+                    encode_info_for_method(ecx,
+                                           rbml_w,
+                                           &*method_type,
+                                           path.clone(),
+                                           false,
+                                           item.id,
+                                           None)
+                }
+            }
         }
       }
       ItemTrait(_, _, ref super_traits, ref ms) => {
@@ -1184,13 +1239,18 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_attributes(rbml_w, item.attrs.as_slice());
         encode_visibility(rbml_w, vis);
         encode_stability(rbml_w, stab);
-        for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
-            rbml_w.start_tag(tag_item_trait_method);
-            encode_def_id(rbml_w, method_def_id);
+        for &method_def_id in ty::trait_item_def_ids(tcx, def_id).iter() {
+            rbml_w.start_tag(tag_item_trait_item);
+            match method_def_id {
+                ty::MethodTraitItemId(method_def_id) => {
+                    encode_def_id(rbml_w, method_def_id);
+                    encode_item_sort(rbml_w, 'r');
+                }
+            }
             rbml_w.end_tag();
 
             rbml_w.start_tag(tag_mod_child);
-            rbml_w.wr_str(def_to_string(method_def_id).as_slice());
+            rbml_w.wr_str(def_to_string(method_def_id.def_id()).as_slice());
             rbml_w.end_tag();
         }
         encode_path(rbml_w, path.clone());
@@ -1207,66 +1267,83 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
         rbml_w.end_tag();
 
-        // Now output the method info for each method.
-        let r = ty::trait_method_def_ids(tcx, def_id);
-        for (i, &method_def_id) in r.iter().enumerate() {
-            assert_eq!(method_def_id.krate, ast::LOCAL_CRATE);
-
-            let method_ty = ty::method(tcx, method_def_id);
+        // Now output the trait item info for each trait item.
+        let r = ty::trait_item_def_ids(tcx, def_id);
+        for (i, &item_def_id) in r.iter().enumerate() {
+            assert_eq!(item_def_id.def_id().krate, ast::LOCAL_CRATE);
 
             index.push(entry {
-                val: method_def_id.node as i64,
+                val: item_def_id.def_id().node as i64,
                 pos: rbml_w.writer.tell().unwrap(),
             });
 
             rbml_w.start_tag(tag_items_data_item);
 
-            encode_method_ty_fields(ecx, rbml_w, &*method_ty);
-            encode_parent_item(rbml_w, def_id);
-
-            let stab = stability::lookup(tcx, method_def_id);
-            encode_stability(rbml_w, stab);
-
-            let elem = ast_map::PathName(method_ty.ident.name);
-            encode_path(rbml_w, path.clone().chain(Some(elem).move_iter()));
-
-            match method_ty.explicit_self {
-                ty::StaticExplicitSelfCategory => {
-                    encode_family(rbml_w,
-                                  fn_style_static_method_family(
-                                      method_ty.fty.fn_style));
-
-                    let pty = ty::lookup_item_type(tcx, method_def_id);
-                    encode_bounds_and_type(rbml_w, ecx, &pty);
-                }
-
-                _ => {
-                    encode_family(rbml_w,
-                                  style_fn_family(
-                                      method_ty.fty.fn_style));
-                }
-            }
-
-            match ms.get(i) {
-                &Required(ref tm) => {
-                    encode_attributes(rbml_w, tm.attrs.as_slice());
-                    encode_method_sort(rbml_w, 'r');
-                    encode_method_argument_names(rbml_w, &*tm.decl);
-                }
+            let trait_item_type =
+                ty::impl_or_trait_item(tcx, item_def_id.def_id());
+            match trait_item_type {
+                 ty::MethodTraitItem(method_ty) => {
+                    let method_def_id = item_def_id.def_id();
+
+                    encode_method_ty_fields(ecx, rbml_w, &*method_ty);
+                    encode_parent_item(rbml_w, def_id);
+
+                    let stab = stability::lookup(tcx, method_def_id);
+                    encode_stability(rbml_w, stab);
+
+                    let elem = ast_map::PathName(method_ty.ident.name);
+                    encode_path(rbml_w,
+                                path.clone().chain(Some(elem).move_iter()));
+
+                    match method_ty.explicit_self {
+                        ty::StaticExplicitSelfCategory => {
+                            encode_family(rbml_w,
+                                          fn_style_static_method_family(
+                                              method_ty.fty.fn_style));
+
+                            let pty = ty::lookup_item_type(tcx,
+                                                           method_def_id);
+                            encode_bounds_and_type(rbml_w, ecx, &pty);
+                        }
+
+                        _ => {
+                            encode_family(rbml_w,
+                                          style_fn_family(
+                                              method_ty.fty.fn_style));
+                        }
+                    }
 
-                &Provided(m) => {
-                    encode_attributes(rbml_w, m.attrs.as_slice());
-                    // If this is a static method, we've already encoded
-                    // this.
-                    if method_ty.explicit_self != ty::StaticExplicitSelfCategory {
-                        // FIXME: I feel like there is something funny going on.
-                        let pty = ty::lookup_item_type(tcx, method_def_id);
-                        encode_bounds_and_type(rbml_w, ecx, &pty);
+                    match ms.get(i) {
+                        &RequiredMethod(ref tm) => {
+                            encode_attributes(rbml_w, tm.attrs.as_slice());
+                            encode_item_sort(rbml_w, 'r');
+                            encode_parent_sort(rbml_w, 't');
+                            encode_method_argument_names(rbml_w, &*tm.decl);
+                        }
+
+                        &ProvidedMethod(m) => {
+                            encode_attributes(rbml_w, m.attrs.as_slice());
+                            // If this is a static method, we've already
+                            // encoded this.
+                            if method_ty.explicit_self !=
+                                    ty::StaticExplicitSelfCategory {
+                                // FIXME: I feel like there is something funny
+                                // going on.
+                                let pty = ty::lookup_item_type(tcx, method_def_id);
+                                encode_bounds_and_type(rbml_w, ecx, &pty);
+                            }
+                            encode_item_sort(rbml_w, 'p');
+                            encode_parent_sort(rbml_w, 't');
+                            encode_inlined_item(
+                                ecx,
+                                rbml_w,
+                                IITraitItemRef(
+                                    def_id,
+                                    ProvidedInlinedTraitItemRef(&*m)));
+                            encode_method_argument_names(rbml_w,
+                                                         &*m.pe_fn_decl());
+                        }
                     }
-                    encode_method_sort(rbml_w, 'p');
-                    encode_inlined_item(ecx, rbml_w,
-                                        IIMethodRef(def_id, true, &*m));
-                    encode_method_argument_names(rbml_w, &*m.pe_fn_decl());
                 }
             }
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index b1ce2ece4af..26cb2f25129 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -84,7 +84,8 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     let id = match ii {
         e::IIItemRef(i) => i.id,
         e::IIForeignRef(i) => i.id,
-        e::IIMethodRef(_, _, m) => m.id,
+        e::IITraitItemRef(_, e::ProvidedInlinedTraitItemRef(m)) => m.id,
+        e::IITraitItemRef(_, e::RequiredInlinedTraitItemRef(m)) => m.id,
     };
     debug!("> Encoding inlined item: {} ({})",
            ecx.tcx.map.path_to_string(id),
@@ -137,7 +138,12 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
         let ident = match ii {
             ast::IIItem(i) => i.ident,
             ast::IIForeign(i) => i.ident,
-            ast::IIMethod(_, _, m) => m.pe_ident(),
+            ast::IITraitItem(_, iti) => {
+                match iti {
+                    ast::ProvidedInlinedTraitItem(m) => m.pe_ident(),
+                    ast::RequiredInlinedTraitItem(m) => m.pe_ident(),
+                }
+            }
         };
         debug!("Fn named: {}", token::get_ident(ident));
         debug!("< Decoded inlined fn: {}::{}",
@@ -344,12 +350,29 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
 
     match ii {
         // HACK we're not dropping items.
-        e::IIItemRef(i) => ast::IIItem(fold::noop_fold_item(i, &mut fld)
-                                       .expect_one("expected one item")),
-        e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)
-                                                 .expect_one(
-                "noop_fold_method must produce exactly one method")),
-        e::IIForeignRef(i) => ast::IIForeign(fold::noop_fold_foreign_item(i, &mut fld))
+        e::IIItemRef(i) => {
+            ast::IIItem(fold::noop_fold_item(i, &mut fld)
+                            .expect_one("expected one item"))
+        }
+        e::IITraitItemRef(d, iti) => {
+            ast::IITraitItem(d, match iti {
+                e::ProvidedInlinedTraitItemRef(m) => {
+                    ast::ProvidedInlinedTraitItem(
+                        fold::noop_fold_method(m, &mut fld)
+                            .expect_one("noop_fold_method must produce \
+                                         exactly one method"))
+                }
+                e::RequiredInlinedTraitItemRef(m) => {
+                    ast::RequiredInlinedTraitItem(
+                        fold::noop_fold_method(m, &mut fld)
+                            .expect_one("noop_fold_method must produce \
+                                         exactly one method"))
+                }
+            })
+        }
+        e::IIForeignRef(i) => {
+            ast::IIForeign(fold::noop_fold_foreign_item(i, &mut fld))
+        }
     }
 }
 
@@ -389,9 +412,23 @@ fn renumber_and_map_ast(xcx: &ExtendedDecodeContext,
             ast::IIItem(i) => {
                 ast::IIItem(fld.fold_item(i).expect_one("expected one item"))
             }
-            ast::IIMethod(d, is_provided, m) => {
-                ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m)
-                              .expect_one("expected one method"))
+            ast::IITraitItem(d, iti) => {
+                match iti {
+                    ast::ProvidedInlinedTraitItem(m) => {
+                        ast::IITraitItem(
+                            xcx.tr_def_id(d),
+                            ast::ProvidedInlinedTraitItem(
+                                fld.fold_method(m)
+                                   .expect_one("expected one method")))
+                    }
+                    ast::RequiredInlinedTraitItem(m) => {
+                        ast::IITraitItem(
+                            xcx.tr_def_id(d),
+                            ast::RequiredInlinedTraitItem(
+                                fld.fold_method(m)
+                                   .expect_one("expected one method")))
+                    }
+                }
             }
             ast::IIForeign(i) => ast::IIForeign(fld.fold_foreign_item(i))
         }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 86fe6dc0ddc..9a7bfb0e6dc 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -40,9 +40,9 @@ fn should_explore(tcx: &ty::ctxt, def_id: ast::DefId) -> bool {
 
     match tcx.map.find(def_id.node) {
         Some(ast_map::NodeItem(..))
-        | Some(ast_map::NodeMethod(..))
+        | Some(ast_map::NodeImplItem(..))
         | Some(ast_map::NodeForeignItem(..))
-        | Some(ast_map::NodeTraitMethod(..)) => true,
+        | Some(ast_map::NodeTraitItem(..)) => true,
         _ => false
     }
 }
@@ -114,9 +114,14 @@ impl<'a> MarkSymbolVisitor<'a> {
                         method_num: index,
                         ..
                     }) => {
-                        let def_id = ty::trait_method(self.tcx,
-                                                      trait_id, index).def_id;
-                        self.check_def_id(def_id);
+                        let trait_item = ty::trait_item(self.tcx,
+                                                        trait_id,
+                                                        index);
+                        match trait_item {
+                            ty::MethodTraitItem(method) => {
+                                self.check_def_id(method.def_id);
+                            }
+                        }
                     }
                 }
             }
@@ -208,11 +213,15 @@ impl<'a> MarkSymbolVisitor<'a> {
                     _ => ()
                 }
             }
-            ast_map::NodeTraitMethod(trait_method) => {
-                visit::walk_trait_method(self, &*trait_method, ctxt);
+            ast_map::NodeTraitItem(trait_method) => {
+                visit::walk_trait_item(self, &*trait_method, ctxt);
             }
-            ast_map::NodeMethod(method) => {
-                visit::walk_block(self, &*method.pe_body(), ctxt);
+            ast_map::NodeImplItem(impl_item) => {
+                match *impl_item {
+                    ast::MethodImplItem(method) => {
+                        visit::walk_block(self, &*method.pe_body(), ctxt);
+                    }
+                }
             }
             ast_map::NodeForeignItem(foreign_item) => {
                 visit::walk_foreign_item(self, &*foreign_item, ctxt);
@@ -316,9 +325,13 @@ impl Visitor<()> for LifeSeeder {
             self.worklist.push(item.id);
         }
         match item.node {
-            ast::ItemImpl(_, Some(ref _trait_ref), _, ref methods) => {
-                for method in methods.iter() {
-                    self.worklist.push(method.id);
+            ast::ItemImpl(_, Some(ref _trait_ref), _, ref impl_items) => {
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(method) => {
+                            self.worklist.push(method.id);
+                        }
+                    }
                 }
             }
             _ => ()
@@ -443,13 +456,14 @@ impl<'a> DeadVisitor<'a> {
         // This is done to handle the case where, for example, the static
         // method of a private type is used, but the type itself is never
         // called directly.
-        let impl_methods = self.tcx.impl_methods.borrow();
+        let impl_items = self.tcx.impl_items.borrow();
         match self.tcx.inherent_impls.borrow().find(&local_def(id)) {
             None => (),
             Some(impl_list) => {
                 for impl_did in impl_list.borrow().iter() {
-                    for method_did in impl_methods.get(impl_did).iter() {
-                        if self.live_symbols.contains(&method_did.node) {
+                    for item_did in impl_items.get(impl_did).iter() {
+                        if self.live_symbols.contains(&item_did.def_id()
+                                                               .node) {
                             return true;
                         }
                     }
@@ -516,12 +530,12 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
     }
 
     // Overwrite so that we don't warn the trait method itself.
-    fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
+    fn visit_trait_item(&mut self, trait_method: &ast::TraitItem, _: ()) {
         match *trait_method {
-            ast::Provided(ref method) => {
+            ast::ProvidedMethod(ref method) => {
                 visit::walk_block(self, &*method.pe_body(), ())
             }
-            ast::Required(_) => ()
+            ast::RequiredMethod(_) => ()
         }
     }
 }
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 7c805b1ac4b..b76b85e024c 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -131,12 +131,14 @@ impl OverloadedCallType {
     fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
                       -> OverloadedCallType {
         let method_descriptor =
-            match tcx.methods.borrow_mut().find(&method_id) {
+            match tcx.impl_or_trait_items.borrow_mut().find(&method_id) {
+                Some(&ty::MethodTraitItem(ref method_descriptor)) => {
+                    (*method_descriptor).clone()
+                }
                 None => {
                     tcx.sess.bug("overloaded call method wasn't in method \
                                   map")
                 }
-                Some(ref method_descriptor) => (*method_descriptor).clone(),
             };
         let impl_id = match method_descriptor.container {
             ty::TraitContainer(_) => {
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 62b5299f8fb..61e6debb086 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -83,8 +83,8 @@ impl Visitor<()> for ParentVisitor {
             ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
                 for m in methods.iter() {
                     match *m {
-                        ast::Provided(ref m) => self.parents.insert(m.id, item.id),
-                        ast::Required(ref m) => self.parents.insert(m.id, item.id),
+                        ast::ProvidedMethod(ref m) => self.parents.insert(m.id, item.id),
+                        ast::RequiredMethod(ref m) => self.parents.insert(m.id, item.id),
                     };
                 }
             }
@@ -240,7 +240,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
             //   undefined symbols at linkage time if this case is not handled.
             //
             // * Private trait impls for private types can be completely ignored
-            ast::ItemImpl(_, _, ref ty, ref methods) => {
+            ast::ItemImpl(_, _, ref ty, ref impl_items) => {
                 let public_ty = match ty.node {
                     ast::TyPath(_, _, id) => {
                         match self.tcx.def_map.borrow().get_copy(&id) {
@@ -261,13 +261,18 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
                 });
 
                 if public_ty || public_trait {
-                    for method in methods.iter() {
-                        let meth_public = match method.pe_explicit_self().node {
-                            ast::SelfStatic => public_ty,
-                            _ => true,
-                        } && method.pe_vis() == ast::Public;
-                        if meth_public || tr.is_some() {
-                            self.exported_items.insert(method.id);
+                    for impl_item in impl_items.iter() {
+                        match *impl_item {
+                            ast::MethodImplItem(method) => {
+                                let meth_public =
+                                    match method.pe_explicit_self().node {
+                                        ast::SelfStatic => public_ty,
+                                        _ => true,
+                                    } && method.pe_vis() == ast::Public;
+                                if meth_public || tr.is_some() {
+                                    self.exported_items.insert(method.id);
+                                }
+                            }
                         }
                     }
                 }
@@ -278,11 +283,11 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
             ast::ItemTrait(_, _, _, ref methods) if public_first => {
                 for method in methods.iter() {
                     match *method {
-                        ast::Provided(ref m) => {
+                        ast::ProvidedMethod(ref m) => {
                             debug!("provided {}", m.id);
                             self.exported_items.insert(m.id);
                         }
-                        ast::Required(ref m) => {
+                        ast::RequiredMethod(ref m) => {
                             debug!("required {}", m.id);
                             self.exported_items.insert(m.id);
                         }
@@ -387,9 +392,10 @@ impl<'a> PrivacyVisitor<'a> {
             }
             debug!("privacy - is {:?} a public method", did);
 
-            return match self.tcx.methods.borrow().find(&did) {
-                Some(meth) => {
-                    debug!("privacy - well at least it's a method: {:?}", meth);
+            return match self.tcx.impl_or_trait_items.borrow().find(&did) {
+                Some(&ty::MethodTraitItem(ref meth)) => {
+                    debug!("privacy - well at least it's a method: {:?}",
+                           *meth);
                     match meth.container {
                         ty::TraitContainer(id) => {
                             debug!("privacy - recursing on trait {:?}", id);
@@ -451,15 +457,23 @@ impl<'a> PrivacyVisitor<'a> {
                 // invocation.
                 // FIXME(#10573) is this the right behavior? Why not consider
                 //               where the method was defined?
-                Some(ast_map::NodeMethod(ref m)) => {
-                    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 => return Allowable,
-                        _ => m.pe_vis()
+                Some(ast_map::NodeImplItem(ref ii)) => {
+                    match **ii {
+                        ast::MethodImplItem(m) => {
+                            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 => {
+                                    return Allowable
+                                }
+                                _ => m.pe_vis()
+                            }
+                        }
                     }
                 }
-                Some(ast_map::NodeTraitMethod(_)) => {
+                Some(ast_map::NodeTraitItem(_)) => {
                     return Allowable;
                 }
 
@@ -648,12 +662,17 @@ impl<'a> PrivacyVisitor<'a> {
     }
 
     // Given the ID of a method, checks to ensure it's in scope.
-    fn check_static_method(&mut self, span: Span, method_id: ast::DefId,
+    fn check_static_method(&mut self,
+                           span: Span,
+                           method_id: ast::DefId,
                            name: ast::Ident) {
         // If the method is a default method, we need to use the def_id of
         // the default implementation.
-        let method_id = ty::method(self.tcx, method_id).provided_source
-                                                       .unwrap_or(method_id);
+        let method_id = match ty::impl_or_trait_item(self.tcx, method_id) {
+            ty::MethodTraitItem(method_type) => {
+                method_type.provided_source.unwrap_or(method_id)
+            }
+        };
 
         let string = token::get_ident(name);
         self.report_error(self.ensure_public(span,
@@ -1075,12 +1094,16 @@ impl<'a> SanePrivacyVisitor<'a> {
         match item.node {
             // implementations of traits don't need visibility qualifiers because
             // that's controlled by having the trait in scope.
-            ast::ItemImpl(_, Some(..), _, ref methods) => {
+            ast::ItemImpl(_, Some(..), _, ref impl_items) => {
                 check_inherited(item.span, item.vis,
                                 "visibility qualifiers have no effect on trait \
                                  impls");
-                for m in methods.iter() {
-                    check_inherited(m.span, m.pe_vis(), "");
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(m) => {
+                            check_inherited(m.span, m.pe_vis(), "");
+                        }
+                    }
                 }
             }
 
@@ -1111,11 +1134,11 @@ impl<'a> SanePrivacyVisitor<'a> {
             ast::ItemTrait(_, _, _, ref methods) => {
                 for m in methods.iter() {
                     match *m {
-                        ast::Provided(ref m) => {
+                        ast::ProvidedMethod(ref m) => {
                             check_inherited(m.span, m.pe_vis(),
                                             "unnecessary visibility");
                         }
-                        ast::Required(ref m) => {
+                        ast::RequiredMethod(ref m) => {
                             check_inherited(m.span, m.vis,
                                             "unnecessary visibility");
                         }
@@ -1148,9 +1171,13 @@ impl<'a> SanePrivacyVisitor<'a> {
         };
         check_inherited(tcx, item.span, item.vis);
         match item.node {
-            ast::ItemImpl(_, _, _, ref methods) => {
-                for m in methods.iter() {
-                    check_inherited(tcx, m.span, m.pe_vis());
+            ast::ItemImpl(_, _, _, ref impl_items) => {
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(m) => {
+                            check_inherited(tcx, m.span, m.pe_vis());
+                        }
+                    }
                 }
             }
             ast::ItemForeignMod(ref fm) => {
@@ -1174,8 +1201,8 @@ impl<'a> SanePrivacyVisitor<'a> {
             ast::ItemTrait(_, _, _, ref methods) => {
                 for m in methods.iter() {
                     match *m {
-                        ast::Required(..) => {}
-                        ast::Provided(ref m) => check_inherited(tcx, m.span,
+                        ast::RequiredMethod(..) => {}
+                        ast::ProvidedMethod(ref m) => check_inherited(tcx, m.span,
                                                                 m.pe_vis()),
                     }
                 }
@@ -1270,7 +1297,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
             // (i.e. we could just return here to not check them at
             // all, or some worse estimation of whether an impl is
             // publicly visible.
-            ast::ItemImpl(ref g, ref trait_ref, self_, ref methods) => {
+            ast::ItemImpl(ref g, ref trait_ref, self_, ref impl_items) => {
                 // `impl [... for] Private` is never visible.
                 let self_contains_private;
                 // impl [... for] Public<...>, but not `impl [... for]
@@ -1311,7 +1338,14 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
                 // are private (because `T` won't be visible externally).
                 let trait_or_some_public_method =
                     trait_ref.is_some() ||
-                    methods.iter().any(|m| self.exported_items.contains(&m.id));
+                    impl_items.iter()
+                              .any(|impl_item| {
+                                  match *impl_item {
+                                      ast::MethodImplItem(m) => {
+                                          self.exported_items.contains(&m.id)
+                                      }
+                                  }
+                              });
 
                 if !self_contains_private &&
                         not_private_trait &&
@@ -1321,8 +1355,14 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
 
                     match *trait_ref {
                         None => {
-                            for method in methods.iter() {
-                                visit::walk_method_helper(self, &**method, ())
+                            for impl_item in impl_items.iter() {
+                                match *impl_item {
+                                    ast::MethodImplItem(method) => {
+                                        visit::walk_method_helper(self,
+                                                                  &*method,
+                                                                  ())
+                                    }
+                                }
                             }
                         }
                         Some(ref tr) => {
@@ -1345,11 +1385,19 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
                     // impl Public<Private> { ... }. Any public static
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
-                    for method in methods.iter() {
-                        if method.pe_explicit_self().node == ast::SelfStatic &&
-                            self.exported_items.contains(&method.id) {
-                            found_pub_static = true;
-                            visit::walk_method_helper(self, &**method, ());
+                    for impl_item in impl_items.iter() {
+                        match *impl_item {
+                            ast::MethodImplItem(method) => {
+                                if method.pe_explicit_self().node ==
+                                        ast::SelfStatic &&
+                                        self.exported_items
+                                            .contains(&method.id) {
+                                    found_pub_static = true;
+                                    visit::walk_method_helper(self,
+                                                              &*method,
+                                                              ());
+                                }
+                            }
                         }
                     }
                     if found_pub_static {
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 7ed1209bdf7..5dfc43daa64 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -193,26 +193,37 @@ impl<'a> ReachableContext<'a> {
                     _ => false,
                 }
             }
-            Some(ast_map::NodeTraitMethod(trait_method)) => {
+            Some(ast_map::NodeTraitItem(trait_method)) => {
                 match *trait_method {
-                    ast::Required(_) => false,
-                    ast::Provided(_) => true,
+                    ast::RequiredMethod(_) => false,
+                    ast::ProvidedMethod(_) => true,
                 }
             }
-            Some(ast_map::NodeMethod(method)) => {
-                if generics_require_inlining(method.pe_generics()) ||
-                        attributes_specify_inlining(method.attrs.as_slice()) {
-                    true
-                } else {
-                    let impl_did = self.tcx.map.get_parent_did(node_id);
-                    // Check the impl. If the generics on the self type of the
-                    // impl require inlining, this method does too.
-                    assert!(impl_did.krate == ast::LOCAL_CRATE);
-                    match self.tcx.map.expect_item(impl_did.node).node {
-                        ast::ItemImpl(ref generics, _, _, _) => {
-                            generics_require_inlining(generics)
+            Some(ast_map::NodeImplItem(impl_item)) => {
+                match *impl_item {
+                    ast::MethodImplItem(method) => {
+                        if generics_require_inlining(method.pe_generics()) ||
+                                attributes_specify_inlining(
+                                    method.attrs.as_slice()) {
+                            true
+                        } else {
+                            let impl_did = self.tcx
+                                               .map
+                                               .get_parent_did(node_id);
+                            // Check the impl. If the generics on the self
+                            // type of the impl require inlining, this method
+                            // does too.
+                            assert!(impl_did.krate == ast::LOCAL_CRATE);
+                            match self.tcx
+                                      .map
+                                      .expect_item(impl_did.node)
+                                      .node {
+                                ast::ItemImpl(ref generics, _, _, _) => {
+                                    generics_require_inlining(generics)
+                                }
+                                _ => false
+                            }
                         }
-                        _ => false
                     }
                 }
             }
@@ -310,20 +321,24 @@ impl<'a> ReachableContext<'a> {
                     }
                 }
             }
-            ast_map::NodeTraitMethod(trait_method) => {
+            ast_map::NodeTraitItem(trait_method) => {
                 match *trait_method {
-                    ast::Required(..) => {
+                    ast::RequiredMethod(..) => {
                         // Keep going, nothing to get exported
                     }
-                    ast::Provided(ref method) => {
+                    ast::ProvidedMethod(ref method) => {
                         visit::walk_block(self, &*method.pe_body(), ())
                     }
                 }
             }
-            ast_map::NodeMethod(method) => {
-                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(), ())
+            ast_map::NodeImplItem(impl_item) => {
+                match *impl_item {
+                    ast::MethodImplItem(method) => {
+                        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(), ())
+                        }
+                    }
                 }
             }
             // Nothing to recurse on for these
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 13a29842fcb..9edf9fcbdba 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -24,7 +24,7 @@ use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
 use syntax::ast::*;
 use syntax::ast;
 use syntax::ast_util::{local_def, PostExpansionMethod};
-use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
+use syntax::ast_util::{walk_pat, trait_item_to_ty_method};
 use syntax::ext::mtwt;
 use syntax::parse::token::special_names;
 use syntax::parse::token::special_idents;
@@ -36,7 +36,7 @@ use syntax::visit::Visitor;
 
 use std::collections::{HashMap, HashSet};
 use std::cell::{Cell, RefCell};
-use std::gc::{Gc, GC};
+use std::gc::GC;
 use std::mem::replace;
 use std::rc::{Rc, Weak};
 use std::uint;
@@ -225,7 +225,7 @@ enum FallbackSuggestion {
     NoSuggestion,
     Field,
     Method,
-    TraitMethod,
+    TraitItem,
     StaticMethod(String),
     StaticTraitMethod(String),
 }
@@ -272,10 +272,10 @@ enum RibKind {
     ConstantItemRibKind
 }
 
-// Methods can be required or provided. Required methods only occur in traits.
+// Methods can be required or provided. RequiredMethod methods only occur in traits.
 enum MethodSort {
-    Required,
-    Provided(NodeId)
+    RequiredMethod,
+    ProvidedMethod(NodeId)
 }
 
 enum UseLexicalScopeFlag {
@@ -289,19 +289,19 @@ enum ModulePrefixResult {
 }
 
 #[deriving(Clone, Eq, PartialEq)]
-enum MethodIsStaticFlag {
-    MethodIsNotStatic,
-    MethodIsStatic,
+pub enum TraitItemKind {
+    NonstaticMethodTraitItemKind,
+    StaticMethodTraitItemKind,
 }
 
-impl MethodIsStaticFlag {
-    fn from_explicit_self_category(explicit_self_category:
-                                   ExplicitSelfCategory)
-                                   -> MethodIsStaticFlag {
+impl TraitItemKind {
+    pub fn from_explicit_self_category(explicit_self_category:
+                                       ExplicitSelfCategory)
+                                       -> TraitItemKind {
         if explicit_self_category == StaticExplicitSelfCategory {
-            MethodIsStatic
+            StaticMethodTraitItemKind
         } else {
-            MethodIsNotStatic
+            NonstaticMethodTraitItemKind
         }
     }
 }
@@ -824,7 +824,7 @@ struct Resolver<'a> {
 
     graph_root: NameBindings,
 
-    method_map: RefCell<FnvHashMap<(Name, DefId), MethodIsStaticFlag>>,
+    trait_item_map: RefCell<FnvHashMap<(Name, DefId), TraitItemKind>>,
 
     structs: FnvHashMap<DefId, Vec<Name>>,
 
@@ -934,7 +934,7 @@ impl<'a> Resolver<'a> {
 
             graph_root: graph_root,
 
-            method_map: RefCell::new(FnvHashMap::new()),
+            trait_item_map: RefCell::new(FnvHashMap::new()),
             structs: FnvHashMap::new(),
 
             unresolved_imports: 0,
@@ -1263,7 +1263,7 @@ impl<'a> Resolver<'a> {
                 parent
             }
 
-            ItemImpl(_, None, ty, ref methods) => {
+            ItemImpl(_, None, ty, ref impl_items) => {
                 // If this implements an anonymous trait, then add all the
                 // methods within to a new module, if the type was defined
                 // within this module.
@@ -1315,35 +1315,43 @@ impl<'a> Resolver<'a> {
                             }
                         };
 
-                        // For each method...
-                        for method in methods.iter() {
-                            // Add the method to the module.
-                            let ident = method.pe_ident();
-                            let method_name_bindings =
-                                self.add_child(ident,
-                                               new_parent.clone(),
-                                               ForbidDuplicateValues,
-                                               method.span);
-                            let def = match method.pe_explicit_self().node {
-                                SelfStatic => {
-                                    // Static methods become
-                                    // `def_static_method`s.
-                                    DefStaticMethod(local_def(method.id),
-                                                      FromImpl(local_def(
-                                                        item.id)),
-                                                      method.pe_fn_style())
-                                }
-                                _ => {
-                                    // Non-static methods become
-                                    // `def_method`s.
-                                    DefMethod(local_def(method.id), None)
-                                }
-                            };
+                        // For each implementation item...
+                        for impl_item in impl_items.iter() {
+                            match *impl_item {
+                                MethodImplItem(method) => {
+                                    // Add the method to the module.
+                                    let ident = method.pe_ident();
+                                    let method_name_bindings =
+                                        self.add_child(ident,
+                                                       new_parent.clone(),
+                                                       ForbidDuplicateValues,
+                                                       method.span);
+                                    let def = match method.pe_explicit_self()
+                                                          .node {
+                                        SelfStatic => {
+                                            // Static methods become
+                                            // `def_static_method`s.
+                                            DefStaticMethod(
+                                                local_def(method.id),
+                                                FromImpl(local_def(item.id)),
+                                                         method.pe_fn_style())
+                                        }
+                                        _ => {
+                                            // Non-static methods become
+                                            // `def_method`s.
+                                            DefMethod(local_def(method.id),
+                                                      None)
+                                        }
+                                    };
 
-                            let is_public = method.pe_vis() == ast::Public;
-                            method_name_bindings.define_value(def,
-                                                              method.span,
-                                                              is_public);
+                                    let is_public =
+                                        method.pe_vis() == ast::Public;
+                                    method_name_bindings.define_value(
+                                        def,
+                                        method.span,
+                                        is_public);
+                                }
+                            }
                         }
                     }
                     _ => {}
@@ -1376,7 +1384,7 @@ impl<'a> Resolver<'a> {
 
                 // Add the names of all the methods to the trait info.
                 for method in methods.iter() {
-                    let ty_m = trait_method_to_ty_method(method);
+                    let ty_m = trait_item_to_ty_method(method);
 
                     let ident = ty_m.ident;
 
@@ -1387,13 +1395,13 @@ impl<'a> Resolver<'a> {
                             (DefStaticMethod(local_def(ty_m.id),
                                               FromTrait(local_def(item.id)),
                                               ty_m.fn_style),
-                             MethodIsStatic)
+                             StaticMethodTraitItemKind)
                         }
                         _ => {
                             // Non-static methods become `def_method`s.
                             (DefMethod(local_def(ty_m.id),
                                        Some(local_def(item.id))),
-                             MethodIsNotStatic)
+                             NonstaticMethodTraitItemKind)
                         }
                     };
 
@@ -1404,7 +1412,7 @@ impl<'a> Resolver<'a> {
                                        ty_m.span);
                     method_name_bindings.define_value(def, ty_m.span, true);
 
-                    self.method_map
+                    self.trait_item_map
                         .borrow_mut()
                         .insert((ident.name, def_id), static_flag);
                 }
@@ -1714,29 +1722,29 @@ impl<'a> Resolver<'a> {
               debug!("(building reduced graph for external \
                       crate) building type {}", final_ident);
 
-              // If this is a trait, add all the method names
-              // to the trait info.
+              // If this is a trait, add all the trait item names to the trait
+              // info.
 
-              let method_def_ids =
-                csearch::get_trait_method_def_ids(&self.session.cstore, def_id);
-              for &method_def_id in method_def_ids.iter() {
-                  let (method_name, explicit_self) =
-                      csearch::get_method_name_and_explicit_self(&self.session.cstore,
-                                                                 method_def_id);
+              let trait_item_def_ids =
+                csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
+              for trait_item_def_id in trait_item_def_ids.iter() {
+                  let (trait_item_name, trait_item_kind) =
+                      csearch::get_trait_item_name_and_kind(
+                          &self.session.cstore,
+                          trait_item_def_id.def_id());
 
-                  debug!("(building reduced graph for \
-                          external crate) ... adding \
-                          trait method '{}'",
-                         token::get_ident(method_name));
+                  debug!("(building reduced graph for external crate) ... \
+                          adding trait item '{}'",
+                         token::get_ident(trait_item_name));
 
-                  self.method_map
+                  self.trait_item_map
                       .borrow_mut()
-                      .insert((method_name.name, def_id),
-                              MethodIsStaticFlag::from_explicit_self_category(
-                                  explicit_self));
+                      .insert((trait_item_name.name, def_id),
+                              trait_item_kind);
 
                   if is_exported {
-                      self.external_exports.insert(method_def_id);
+                      self.external_exports
+                          .insert(trait_item_def_id.def_id());
                   }
               }
 
@@ -3680,12 +3688,12 @@ impl<'a> Resolver<'a> {
             ItemImpl(ref generics,
                      ref implemented_traits,
                      ref self_type,
-                     ref methods) => {
+                     ref impl_items) => {
                 self.resolve_implementation(item.id,
                                             generics,
                                             implemented_traits,
                                             &**self_type,
-                                            methods.as_slice());
+                                            impl_items.as_slice());
             }
 
             ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
@@ -3724,12 +3732,12 @@ impl<'a> Resolver<'a> {
                         // FIXME #4951: Do we need a node ID here?
 
                         match *method {
-                          ast::Required(ref ty_m) => {
+                          ast::RequiredMethod(ref ty_m) => {
                             this.with_type_parameter_rib
                                 (HasTypeParameters(&ty_m.generics,
                                                    FnSpace,
                                                    item.id,
-                                        MethodRibKind(item.id, Required)),
+                                        MethodRibKind(item.id, RequiredMethod)),
                                  |this| {
 
                                 // Resolve the method-specific type
@@ -3751,9 +3759,9 @@ impl<'a> Resolver<'a> {
                                 this.resolve_type(&*ty_m.decl.output);
                             });
                           }
-                          ast::Provided(ref m) => {
+                          ast::ProvidedMethod(ref m) => {
                               this.resolve_method(MethodRibKind(item.id,
-                                                                Provided(m.id)),
+                                                                ProvidedMethod(m.id)),
                                                   &**m)
                           }
                         }
@@ -4129,7 +4137,7 @@ impl<'a> Resolver<'a> {
                               generics: &Generics,
                               opt_trait_reference: &Option<TraitRef>,
                               self_type: &Ty,
-                              methods: &[Gc<Method>]) {
+                              impl_items: &[ImplItem]) {
         // If applicable, create a rib for the type parameters.
         self.with_type_parameter_rib(HasTypeParameters(generics,
                                                        TypeSpace,
@@ -4145,27 +4153,36 @@ impl<'a> Resolver<'a> {
                 this.resolve_type(self_type);
 
                 this.with_current_self_type(self_type, |this| {
-                    for method in methods.iter() {
-                        // If this is a trait impl, ensure the method exists in trait
-                        this.check_trait_method(&**method);
-
-                        // We also need a new scope for the method-specific type parameters.
-                        this.resolve_method(MethodRibKind(id, Provided(method.id)),
-                                            &**method);
+                    for impl_item in impl_items.iter() {
+                        match *impl_item {
+                            MethodImplItem(method) => {
+                                // If this is a trait impl, ensure the method
+                                // exists in trait
+                                this.check_trait_item(method.pe_ident(),
+                                                      method.span);
+
+                                // We also need a new scope for the method-
+                                // specific type parameters.
+                                this.resolve_method(
+                                    MethodRibKind(id,
+                                                  ProvidedMethod(method.id)),
+                                    &*method);
+                            }
+                        }
                     }
                 });
             });
         });
     }
 
-    fn check_trait_method(&self, method: &Method) {
+    fn check_trait_item(&self, ident: Ident, span: Span) {
         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
         for &(did, ref trait_ref) in self.current_trait_ref.iter() {
-            let method_name = method.pe_ident().name;
+            let method_name = ident.name;
 
-            if self.method_map.borrow().find(&(method_name, did)).is_none() {
+            if self.trait_item_map.borrow().find(&(method_name, did)).is_none() {
                 let path_str = self.path_idents_to_string(&trait_ref.path);
-                self.resolve_error(method.span,
+                self.resolve_error(span,
                                     format!("method `{}` is not a member of trait `{}`",
                                             token::get_name(method_name),
                                             path_str).as_slice());
@@ -4845,8 +4862,8 @@ impl<'a> Resolver<'a> {
             TraitModuleKind | ImplModuleKind => {
                 match containing_module.def_id.get() {
                     Some(def_id) => {
-                        match self.method_map.borrow().find(&(ident.name, def_id)) {
-                            Some(&MethodIsStatic) => (),
+                        match self.trait_item_map.borrow().find(&(ident.name, def_id)) {
+                            Some(&StaticMethodTraitItemKind) => (),
                             None => (),
                             _ => {
                                 debug!("containing module was a trait or impl \
@@ -5102,7 +5119,7 @@ impl<'a> Resolver<'a> {
                             }
                         }
                         Some(DefMethod(_, None)) if allowed == Everything => return Method,
-                        Some(DefMethod(_, Some(_))) => return TraitMethod,
+                        Some(DefMethod(_, Some(_))) => return TraitItem,
                         _ => ()
                     }
                 }
@@ -5112,14 +5129,14 @@ impl<'a> Resolver<'a> {
         }
 
         // Look for a method in the current trait.
-        let method_map = self.method_map.borrow();
+        let trait_item_map = self.trait_item_map.borrow();
         match self.current_trait_ref {
             Some((did, ref trait_ref)) => {
                 let path_str = self.path_idents_to_string(&trait_ref.path);
 
-                match method_map.find(&(name, did)) {
-                    Some(&MethodIsStatic) => return StaticTraitMethod(path_str),
-                    Some(_) => return TraitMethod,
+                match trait_item_map.find(&(name, did)) {
+                    Some(&StaticMethodTraitItemKind) => return StaticTraitMethod(path_str),
+                    Some(_) => return TraitItem,
                     None => {}
                 }
             }
@@ -5262,7 +5279,7 @@ impl<'a> Resolver<'a> {
                                         Field =>
                                             format!("`self.{}`", wrong_name),
                                         Method
-                                        | TraitMethod =>
+                                        | TraitItem =>
                                             format!("to call `self.{}`", wrong_name),
                                         StaticTraitMethod(path_str)
                                         | StaticMethod(path_str) =>
@@ -5437,9 +5454,9 @@ impl<'a> Resolver<'a> {
             // Look for the current trait.
             match self.current_trait_ref {
                 Some((trait_def_id, _)) => {
-                    let method_map = self.method_map.borrow();
+                    let trait_item_map = self.trait_item_map.borrow();
 
-                    if method_map.contains_key(&(name, trait_def_id)) {
+                    if trait_item_map.contains_key(&(name, trait_def_id)) {
                         add_trait_info(&mut found_traits, trait_def_id, name);
                     }
                 }
@@ -5450,7 +5467,7 @@ impl<'a> Resolver<'a> {
             self.populate_module_if_necessary(&search_module);
 
             {
-                let method_map = self.method_map.borrow();
+                let trait_item_map = self.trait_item_map.borrow();
                 for (_, child_names) in search_module.children.borrow().iter() {
                     let def = match child_names.def_for_namespace(TypeNS) {
                         Some(def) => def,
@@ -5460,7 +5477,7 @@ impl<'a> Resolver<'a> {
                         DefTrait(trait_def_id) => trait_def_id,
                         _ => continue,
                     };
-                    if method_map.contains_key(&(name, trait_def_id)) {
+                    if trait_item_map.contains_key(&(name, trait_def_id)) {
                         add_trait_info(&mut found_traits, trait_def_id, name);
                     }
                 }
@@ -5476,7 +5493,7 @@ impl<'a> Resolver<'a> {
                     Some(DefTrait(trait_def_id)) => trait_def_id,
                     Some(..) | None => continue,
                 };
-                if self.method_map.borrow().contains_key(&(name, did)) {
+                if self.trait_item_map.borrow().contains_key(&(name, did)) {
                     add_trait_info(&mut found_traits, did, name);
                     self.used_imports.insert((import.type_id, TypeNS));
                 }
diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs
index 4a58a8bba99..11b16f18533 100644
--- a/src/librustc/middle/save/mod.rs
+++ b/src/librustc/middle/save/mod.rs
@@ -283,8 +283,8 @@ impl <'l> DxrVisitor<'l> {
                             let mut result = String::from_str("<");
                             result.push_str(ty_to_string(&*ty).as_slice());
 
-                            match ty::trait_of_method(&self.analysis.ty_cx,
-                                                      ast_util::local_def(method.id)) {
+                            match ty::trait_of_item(&self.analysis.ty_cx,
+                                                    ast_util::local_def(method.id)) {
                                 Some(def_id) => {
                                     result.push_str(" as ");
                                     result.push_str(
@@ -310,8 +310,8 @@ impl <'l> DxrVisitor<'l> {
                                               ).as_slice());
                 },
             },
-            None => match ty::trait_of_method(&self.analysis.ty_cx,
-                                              ast_util::local_def(method.id)) {
+            None => match ty::trait_of_item(&self.analysis.ty_cx,
+                                            ast_util::local_def(method.id)) {
                 Some(def_id) => {
                     scope_id = def_id.node;
                     match self.analysis.ty_cx.map.get(def_id.node) {
@@ -338,9 +338,19 @@ impl <'l> DxrVisitor<'l> {
         let qualname = qualname.as_slice();
 
         // record the decl for this def (if it has one)
-        let decl_id = ty::trait_method_of_method(&self.analysis.ty_cx,
-                                                 ast_util::local_def(method.id))
-            .filtered(|def_id| method.id != 0 && def_id.node == 0);
+        let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
+                                             ast_util::local_def(method.id))
+            .filtered(|def_id| {
+                match *def_id {
+                    ty::MethodTraitItemId(def_id) => {
+                        method.id != 0 && def_id.node == 0
+                    }
+                }
+            });
+        let decl_id = match decl_id {
+            None => None,
+            Some(ty::MethodTraitItemId(def_id)) => Some(def_id),
+        };
 
         let sub_span = self.span.sub_span_after_keyword(method.span, keywords::Fn);
         self.fmt.method_str(method.span,
@@ -601,7 +611,7 @@ impl <'l> DxrVisitor<'l> {
                     type_parameters: &ast::Generics,
                     trait_ref: &Option<ast::TraitRef>,
                     typ: ast::P<ast::Ty>,
-                    methods: &Vec<Gc<ast::Method>>) {
+                    impl_items: &Vec<ast::ImplItem>) {
         match typ.node {
             ast::TyPath(ref path, _, id) => {
                 match self.lookup_type_ref(id) {
@@ -630,8 +640,12 @@ impl <'l> DxrVisitor<'l> {
         }
 
         self.process_generic_params(type_parameters, item.span, "", item.id, e);
-        for method in methods.iter() {
-            visit::walk_method_helper(self, &**method, e)
+        for impl_item in impl_items.iter() {
+            match *impl_item {
+                ast::MethodImplItem(method) => {
+                    visit::walk_method_helper(self, &*method, e)
+                }
+            }
         }
     }
 
@@ -640,7 +654,7 @@ impl <'l> DxrVisitor<'l> {
                      e: DxrVisitorEnv,
                      generics: &ast::Generics,
                      trait_refs: &Vec<ast::TraitRef>,
-                     methods: &Vec<ast::TraitMethod>) {
+                     methods: &Vec<ast::TraitItem>) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
@@ -672,7 +686,7 @@ impl <'l> DxrVisitor<'l> {
         // walk generics and methods
         self.process_generic_params(generics, item.span, qualname.as_slice(), item.id, e);
         for method in methods.iter() {
-            self.visit_trait_method(method, e)
+            self.visit_trait_item(method, e)
         }
     }
 
@@ -735,18 +749,44 @@ impl <'l> DxrVisitor<'l> {
             def::DefStaticMethod(declid, provenence, _) => {
                 let sub_span = self.span.sub_span_for_meth_name(ex.span);
                 let defid = if declid.krate == ast::LOCAL_CRATE {
-                    let m = ty::method(&self.analysis.ty_cx, declid);
+                    let ti = ty::impl_or_trait_item(&self.analysis.ty_cx,
+                                                    declid);
                     match provenence {
-                        def::FromTrait(def_id) =>
-                            Some(ty::trait_methods(&self.analysis.ty_cx, def_id)
-                                .iter().find(|mr| mr.ident.name == m.ident.name).unwrap().def_id),
+                        def::FromTrait(def_id) => {
+                            Some(ty::trait_items(&self.analysis.ty_cx,
+                                                 def_id)
+                                    .iter()
+                                    .find(|mr| {
+                                        match **mr {
+                                            ty::MethodTraitItem(ref mr) => {
+                                                mr.ident.name == ti.ident()
+                                                                   .name
+                                            }
+                                        }
+                                    })
+                                    .unwrap()
+                                    .def_id())
+                        }
                         def::FromImpl(def_id) => {
-                            let impl_methods = self.analysis.ty_cx.impl_methods.borrow();
-                            Some(*impl_methods.get(&def_id)
-                                .iter().find(|mr|
-                                    ty::method(
-                                        &self.analysis.ty_cx, **mr).ident.name == m.ident.name)
-                                .unwrap())
+                            let impl_items = self.analysis
+                                                 .ty_cx
+                                                 .impl_items
+                                                 .borrow();
+                            Some(impl_items.get(&def_id)
+                                           .iter()
+                                           .find(|mr| {
+                                            match **mr {
+                                                ty::MethodTraitItemId(mr) => {
+                                                    ty::impl_or_trait_item(
+                                                            &self.analysis
+                                                                 .ty_cx,
+                                                            mr).ident()
+                                                               .name ==
+                                                        ti.ident().name
+                                                    }
+                                                }
+                                            }).unwrap()
+                                              .def_id())
                         }
                     }
                 } else {
@@ -845,27 +885,45 @@ impl <'l> DxrVisitor<'l> {
             typeck::MethodStatic(def_id) |
             typeck::MethodStaticUnboxedClosure(def_id) => {
                 // method invoked on an object with a concrete type (not a static method)
-                let decl_id = ty::trait_method_of_method(&self.analysis.ty_cx, def_id);
+                let decl_id =
+                    match ty::trait_item_of_item(&self.analysis.ty_cx,
+                                                 def_id) {
+                        None => None,
+                        Some(ty::MethodTraitItemId(decl_id)) => Some(decl_id),
+                    };
 
-                // This incantation is required if the method referenced is a trait's
-                // default implementation.
-                let def_id = ty::method(&self.analysis.ty_cx, def_id).provided_source
-                                    .unwrap_or(def_id);
+                // This incantation is required if the method referenced is a
+                // trait's default implementation.
+                let def_id = match ty::impl_or_trait_item(&self.analysis
+                                                               .ty_cx,
+                                                          def_id) {
+                    ty::MethodTraitItem(method) => {
+                        method.provided_source.unwrap_or(def_id)
+                    }
+                };
                 (Some(def_id), decl_id)
             }
             typeck::MethodParam(mp) => {
                 // method invoked on a type parameter
-                let method = ty::trait_method(&self.analysis.ty_cx,
-                                              mp.trait_id,
-                                              mp.method_num);
-                (None, Some(method.def_id))
+                let trait_item = ty::trait_item(&self.analysis.ty_cx,
+                                                mp.trait_id,
+                                                mp.method_num);
+                match trait_item {
+                    ty::MethodTraitItem(method) => {
+                        (None, Some(method.def_id))
+                    }
+                }
             },
             typeck::MethodObject(mo) => {
                 // method invoked on a trait instance
-                let method = ty::trait_method(&self.analysis.ty_cx,
-                                              mo.trait_id,
-                                              mo.method_num);
-                (None, Some(method.def_id))
+                let trait_item = ty::trait_item(&self.analysis.ty_cx,
+                                                mo.trait_id,
+                                                mo.method_num);
+                match trait_item {
+                    ty::MethodTraitItem(method) => {
+                        (None, Some(method.def_id))
+                    }
+                }
             },
         };
         let sub_span = self.span.sub_span_for_meth_name(ex.span);
@@ -968,8 +1026,17 @@ impl<'l> Visitor<DxrVisitorEnv> for DxrVisitor<'l> {
                 self.process_static(item, e, typ, mt, &*expr),
             ast::ItemStruct(def, ref ty_params) => self.process_struct(item, e, &*def, ty_params),
             ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, e, def, ty_params),
-            ast::ItemImpl(ref ty_params, ref trait_ref, typ, ref methods) =>
-                self.process_impl(item, e, ty_params, trait_ref, typ, methods),
+            ast::ItemImpl(ref ty_params,
+                          ref trait_ref,
+                          typ,
+                          ref impl_items) => {
+                self.process_impl(item,
+                                  e,
+                                  ty_params,
+                                  trait_ref,
+                                  typ,
+                                  impl_items)
+            }
             ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
                 self.process_trait(item, e, generics, trait_refs, methods),
             ast::ItemMod(ref m) => self.process_mod(item, e, m),
@@ -1027,16 +1094,16 @@ impl<'l> Visitor<DxrVisitorEnv> for DxrVisitor<'l> {
         }
     }
 
-    fn visit_trait_method(&mut self, tm: &ast::TraitMethod, e: DxrVisitorEnv) {
+    fn visit_trait_item(&mut self, tm: &ast::TraitItem, e: DxrVisitorEnv) {
         match *tm {
-            ast::Required(ref method_type) => {
+            ast::RequiredMethod(ref method_type) => {
                 if generated_code(method_type.span) {
                     return;
                 }
 
-                let mut scope_id ;
-                let mut qualname = match ty::trait_of_method(&self.analysis.ty_cx,
-                                                             ast_util::local_def(method_type.id)) {
+                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;
                         ty::item_path_str(&self.analysis.ty_cx, def_id).append("::")
@@ -1070,7 +1137,7 @@ impl<'l> Visitor<DxrVisitorEnv> for DxrVisitor<'l> {
                                             method_type.id,
                                             e);
             }
-            ast::Provided(method) => self.process_method(&*method, e),
+            ast::ProvidedMethod(method) => self.process_method(&*method, e),
         }
     }
 
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index a3fa5a5f85b..e73d81d9bf5 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -16,7 +16,7 @@ use syntax::codemap::Span;
 use syntax::{attr, visit};
 use syntax::ast;
 use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
-use syntax::ast::{Item, Required, Provided, TraitMethod, TypeMethod, Method};
+use syntax::ast::{Item, RequiredMethod, ProvidedMethod, TraitItem, TypeMethod, Method};
 use syntax::ast::{Generics, StructDef, StructField, Ident};
 use syntax::ast_util::is_local;
 use syntax::attr::Stability;
@@ -68,18 +68,18 @@ impl Visitor<Option<Stability>> for Annotator {
         visit::walk_fn(self, fk, fd, b, s, stab)
     }
 
-    fn visit_trait_method(&mut self, t: &TraitMethod, parent: Option<Stability>) {
+    fn visit_trait_item(&mut self, t: &TraitItem, parent: Option<Stability>) {
         let stab = match *t {
-            Required(TypeMethod {attrs: ref attrs, id: id, ..}) =>
+            RequiredMethod(TypeMethod {attrs: ref attrs, id: id, ..}) =>
                 self.annotate(id, attrs.as_slice(), parent),
 
             // work around lack of pattern matching for @ types
-            Provided(method) => match *method {
+            ProvidedMethod(method) => match *method {
                 Method {attrs: ref attrs, id: id, ..} =>
                     self.annotate(id, attrs.as_slice(), parent)
             }
         };
-        visit::walk_trait_method(self, t, stab)
+        visit::walk_trait_item(self, t, stab)
     }
 
     fn visit_variant(&mut self, v: &Variant, g: &Generics, parent: Option<Stability>) {
@@ -116,10 +116,11 @@ impl Index {
 
 /// Lookup the stability for a node, loading external crate
 /// metadata as necessary.
-pub fn lookup(tcx: &ty::ctxt,  id: DefId) -> Option<Stability> {
+pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
     // is this definition the implementation of a trait method?
-    match ty::trait_method_of_method(tcx, id) {
-        Some(trait_method_id) if trait_method_id != id => {
+    match ty::trait_item_of_item(tcx, id) {
+        Some(ty::MethodTraitItemId(trait_method_id))
+                if trait_method_id != id => {
             lookup(tcx, trait_method_id)
         }
         _ if is_local(id) => {
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 16ba3ddbd70..9aa4355632c 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1299,9 +1299,9 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
             }
         }
-        Some(ast_map::NodeTraitMethod(trait_method)) => {
+        Some(ast_map::NodeTraitItem(trait_method)) => {
             match *trait_method {
-                ast::Provided(m) => {
+                ast::ProvidedMethod(m) => {
                     match m.node {
                         ast::MethDecl(_, _, _, _, _, _, blk, _) => {
                             let mut explicit = CheckForNestedReturnsVisitor { found: false };
@@ -1313,20 +1313,34 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
                         ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
                     }
                 }
-                ast::Required(_) => tcx.sess.bug("unexpected variant: required trait method in \
-                                                  has_nested_returns")
+                ast::RequiredMethod(_) => {
+                    tcx.sess.bug("unexpected variant: required trait method \
+                                  in has_nested_returns")
+                }
             }
         }
-        Some(ast_map::NodeMethod(m)) => {
-            match m.node {
-                ast::MethDecl(_, _, _, _, _, _, blk, _) => {
-                    let mut explicit = CheckForNestedReturnsVisitor { found: false };
-                    let mut implicit = CheckForNestedReturnsVisitor { found: false };
-                    visit::walk_method_helper(&mut explicit, &*m, false);
-                    visit::walk_expr_opt(&mut implicit, blk.expr, true);
-                    explicit.found || implicit.found
+        Some(ast_map::NodeImplItem(ref ii)) => {
+            match **ii {
+                ast::MethodImplItem(ref m) => {
+                    match m.node {
+                        ast::MethDecl(_, _, _, _, _, _, blk, _) => {
+                            let mut explicit = CheckForNestedReturnsVisitor {
+                                found: false,
+                            };
+                            let mut implicit = CheckForNestedReturnsVisitor {
+                                found: false,
+                            };
+                            visit::walk_method_helper(&mut explicit,
+                                                      &**m,
+                                                      false);
+                            visit::walk_expr_opt(&mut implicit,
+                                                 blk.expr,
+                                                 true);
+                            explicit.found || implicit.found
+                        }
+                        ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
+                    }
                 }
-                ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
             }
         }
         Some(ast_map::NodeExpr(e)) => {
@@ -2107,8 +2121,12 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
         let mut v = TransItemVisitor{ ccx: ccx };
         v.visit_block(&**body, ());
       }
-      ast::ItemImpl(ref generics, _, _, ref ms) => {
-        meth::trans_impl(ccx, item.ident, ms.as_slice(), generics, item.id);
+      ast::ItemImpl(ref generics, _, _, ref impl_items) => {
+        meth::trans_impl(ccx,
+                         item.ident,
+                         impl_items.as_slice(),
+                         generics,
+                         item.id);
       }
       ast::ItemMod(ref m) => {
         trans_mod(ccx, m);
@@ -2615,21 +2633,23 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             v
         }
 
-        ast_map::NodeTraitMethod(trait_method) => {
-            debug!("get_item_val(): processing a NodeTraitMethod");
+        ast_map::NodeTraitItem(trait_method) => {
+            debug!("get_item_val(): processing a NodeTraitItem");
             match *trait_method {
-                ast::Required(_) => {
+                ast::RequiredMethod(_) => {
                     ccx.sess().bug("unexpected variant: required trait method in \
                                    get_item_val()");
                 }
-                ast::Provided(m) => {
+                ast::ProvidedMethod(m) => {
                     register_method(ccx, id, &*m)
                 }
             }
         }
 
-        ast_map::NodeMethod(m) => {
-            register_method(ccx, id, &*m)
+        ast_map::NodeImplItem(ii) => {
+            match *ii {
+                ast::MethodImplItem(m) => register_method(ccx, id, &*m),
+            }
         }
 
         ast_map::NodeForeignItem(ni) => {
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 379b53eebbb..56c1c665331 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -77,7 +77,7 @@ pub enum CalleeData {
 
     Intrinsic(ast::NodeId, subst::Substs),
 
-    TraitMethod(MethodData)
+    TraitItem(MethodData)
 }
 
 pub struct Callee<'a> {
@@ -449,7 +449,7 @@ pub fn trans_fn_ref_with_vtables(
     assert!(substs.types.all(|t| !ty::type_needs_infer(*t)));
 
     // Load the info for the appropriate trait if necessary.
-    match ty::trait_of_method(tcx, def_id) {
+    match ty::trait_of_item(tcx, def_id) {
         None => {}
         Some(trait_id) => {
             ty::populate_implementations_for_trait_if_necessary(tcx, trait_id)
@@ -476,35 +476,43 @@ pub fn trans_fn_ref_with_vtables(
             // So, what we need to do is find this substitution and
             // compose it with the one we already have.
 
-            let impl_id = ty::method(tcx, def_id).container_id();
-            let method = ty::method(tcx, source_id);
-            let trait_ref = ty::impl_trait_ref(tcx, impl_id)
-                .expect("could not find trait_ref for impl with \
-                         default methods");
-
-            // Compute the first substitution
-            let first_subst = make_substs_for_receiver_types(
-                tcx, &*trait_ref, &*method);
-
-            // And compose them
-            let new_substs = first_subst.subst(tcx, &substs);
-
-            debug!("trans_fn_with_vtables - default method: \
-                    substs = {}, trait_subst = {}, \
-                    first_subst = {}, new_subst = {}, \
-                    vtables = {}",
-                   substs.repr(tcx), trait_ref.substs.repr(tcx),
-                   first_subst.repr(tcx), new_substs.repr(tcx),
-                   vtables.repr(tcx));
-
-            let param_vtables =
-                resolve_default_method_vtables(bcx, impl_id, &substs, vtables);
-
-            debug!("trans_fn_with_vtables - default method: \
-                    param_vtables = {}",
-                   param_vtables.repr(tcx));
-
-            (true, source_id, new_substs, param_vtables)
+            let impl_id = ty::impl_or_trait_item(tcx, def_id).container()
+                                                             .id();
+            let impl_or_trait_item = ty::impl_or_trait_item(tcx, source_id);
+            match impl_or_trait_item {
+                ty::MethodTraitItem(method) => {
+                    let trait_ref = ty::impl_trait_ref(tcx, impl_id)
+                        .expect("could not find trait_ref for impl with \
+                                 default methods");
+
+                    // Compute the first substitution
+                    let first_subst = make_substs_for_receiver_types(
+                        tcx, &*trait_ref, &*method);
+
+                    // And compose them
+                    let new_substs = first_subst.subst(tcx, &substs);
+
+                    debug!("trans_fn_with_vtables - default method: \
+                            substs = {}, trait_subst = {}, \
+                            first_subst = {}, new_subst = {}, \
+                            vtables = {}",
+                           substs.repr(tcx), trait_ref.substs.repr(tcx),
+                           first_subst.repr(tcx), new_substs.repr(tcx),
+                           vtables.repr(tcx));
+
+                    let param_vtables =
+                        resolve_default_method_vtables(bcx,
+                                                       impl_id,
+                                                       &substs,
+                                                       vtables);
+
+                    debug!("trans_fn_with_vtables - default method: \
+                            param_vtables = {}",
+                           param_vtables.repr(tcx));
+
+                    (true, source_id, new_substs, param_vtables)
+                }
+            }
         }
     };
 
@@ -742,7 +750,7 @@ pub fn trans_call_inner<'a>(
         Fn(llfn) => {
             (llfn, None, None)
         }
-        TraitMethod(d) => {
+        TraitItem(d) => {
             (d.llfn, None, Some(d.llself))
         }
         Closure(d) => {
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 96b8acbfb40..9b78cedd4ac 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -1140,13 +1140,17 @@ pub fn create_function_debug_context(cx: &CrateContext,
                 }
             }
         }
-        ast_map::NodeMethod(ref method) => {
-            (method.pe_ident(),
-             method.pe_fn_decl(),
-             method.pe_generics(),
-             method.pe_body(),
-             method.span,
-             true)
+        ast_map::NodeImplItem(ref item) => {
+            match **item {
+                ast::MethodImplItem(ref method) => {
+                    (method.pe_ident(),
+                     method.pe_fn_decl(),
+                     method.pe_generics(),
+                     method.pe_body(),
+                     method.span,
+                     true)
+                }
+            }
         }
         ast_map::NodeExpr(ref expr) => {
             match expr.node {
@@ -1168,9 +1172,9 @@ pub fn create_function_debug_context(cx: &CrateContext,
                         "create_function_debug_context: expected an expr_fn_block here")
             }
         }
-        ast_map::NodeTraitMethod(ref trait_method) => {
+        ast_map::NodeTraitItem(ref trait_method) => {
             match **trait_method {
-                ast::Provided(ref method) => {
+                ast::ProvidedMethod(ref method) => {
                     (method.pe_ident(),
                      method.pe_fn_decl(),
                      method.pe_generics(),
diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs
index bf39f3a6aa3..4b1f37fcdc2 100644
--- a/src/librustc/middle/trans/inline.rs
+++ b/src/librustc/middle/trans/inline.rs
@@ -115,27 +115,42 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             ccx.sess().bug("maybe_get_item_ast returned a found_parent \
              with a non-item parent");
         }
-        csearch::found(ast::IIMethod(impl_did, is_provided, mth)) => {
-            ccx.external.borrow_mut().insert(fn_id, Some(mth.id));
-            ccx.external_srcs.borrow_mut().insert(mth.id, fn_id);
+        csearch::found(ast::IITraitItem(impl_did, impl_item)) => {
+            match impl_item {
+                ast::ProvidedInlinedTraitItem(mth) |
+                ast::RequiredInlinedTraitItem(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.
-            if is_provided { return local_def(mth.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();
+            match impl_item {
+                ast::ProvidedInlinedTraitItem(mth) => {
+                    // 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::RequiredInlinedTraitItem(mth) => {
+                    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();
 
-          if unparameterized {
-              let llfn = get_item_val(ccx, mth.id);
-                trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), llfn,
-                       &param_substs::empty(), mth.id, []);
-          }
-          local_def(mth.id)
+                    if unparameterized {
+                        let llfn = get_item_val(ccx, mth.id);
+                        trans_fn(ccx,
+                                 &*mth.pe_fn_decl(),
+                                 &*mth.pe_body(),
+                                 llfn,
+                                 &param_substs::empty(),
+                                 mth.id,
+                                 []);
+                    }
+                    local_def(mth.id)
+                }
+            }
         }
     };
 }
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 3ae4c552b84..31f2a3df662 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -35,7 +35,6 @@ use util::common::indenter;
 use util::ppaux::Repr;
 
 use std::c_str::ToCStr;
-use std::gc::Gc;
 use syntax::abi::{Rust, RustCall};
 use syntax::parse::token;
 use syntax::{ast, ast_map, visit};
@@ -49,7 +48,7 @@ see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
 */
 pub fn trans_impl(ccx: &CrateContext,
                   name: ast::Ident,
-                  methods: &[Gc<ast::Method>],
+                  impl_items: &[ast::ImplItem],
                   generics: &ast::Generics,
                   id: ast::NodeId) {
     let _icx = push_ctxt("meth::trans_impl");
@@ -61,24 +60,34 @@ pub fn trans_impl(ccx: &CrateContext,
     // items that we need to translate.
     if !generics.ty_params.is_empty() {
         let mut v = TransItemVisitor{ ccx: ccx };
-        for method in methods.iter() {
-            visit::walk_method_helper(&mut v, &**method, ());
+        for impl_item in impl_items.iter() {
+            match *impl_item {
+                ast::MethodImplItem(method) => {
+                    visit::walk_method_helper(&mut v, &*method, ());
+                }
+            }
         }
         return;
     }
-    for method in methods.iter() {
-        if method.pe_generics().ty_params.len() == 0u {
-            let llfn = get_item_val(ccx, method.id);
-            trans_fn(ccx,
-                     &*method.pe_fn_decl(),
-                     &*method.pe_body(),
-                     llfn,
-                     &param_substs::empty(),
-                     method.id,
-                     []);
+    for impl_item in impl_items.iter() {
+        match *impl_item {
+            ast::MethodImplItem(method) => {
+                if method.pe_generics().ty_params.len() == 0u {
+                    let llfn = get_item_val(ccx, method.id);
+                    trans_fn(ccx,
+                             &*method.pe_fn_decl(),
+                             &*method.pe_body(),
+                             llfn,
+                             &param_substs::empty(),
+                             method.id,
+                             []);
+                }
+                let mut v = TransItemVisitor {
+                    ccx: ccx,
+                };
+                visit::walk_method_helper(&mut v, &*method, ());
+            }
         }
-        let mut v = TransItemVisitor{ ccx: ccx };
-        visit::walk_method_helper(&mut v, &**method, ());
     }
 }
 
@@ -165,10 +174,10 @@ pub fn trans_static_method_callee(bcx: &Block,
 
     let mname = if method_id.krate == ast::LOCAL_CRATE {
         match bcx.tcx().map.get(method_id.node) {
-            ast_map::NodeTraitMethod(method) => {
+            ast_map::NodeTraitItem(method) => {
                 let ident = match *method {
-                    ast::Required(ref m) => m.ident,
-                    ast::Provided(ref m) => m.pe_ident()
+                    ast::RequiredMethod(ref m) => m.ident,
+                    ast::ProvidedMethod(ref m) => m.pe_ident()
                 };
                 ident.name
             }
@@ -213,22 +222,33 @@ pub fn trans_static_method_callee(bcx: &Block,
     }
 }
 
-fn method_with_name(ccx: &CrateContext,
-                    impl_id: ast::DefId,
-                    name: ast::Name) -> ast::DefId {
+fn method_with_name(ccx: &CrateContext, impl_id: ast::DefId, name: ast::Name)
+                    -> ast::DefId {
     match ccx.impl_method_cache.borrow().find_copy(&(impl_id, name)) {
         Some(m) => return m,
         None => {}
     }
 
-    let methods = ccx.tcx.impl_methods.borrow();
-    let methods = methods.find(&impl_id)
-                         .expect("could not find impl while translating");
-    let meth_did = methods.iter().find(|&did| ty::method(&ccx.tcx, *did).ident.name == name)
-                                 .expect("could not find method while translating");
-
-    ccx.impl_method_cache.borrow_mut().insert((impl_id, name), *meth_did);
-    *meth_did
+    let impl_items = ccx.tcx.impl_items.borrow();
+    let impl_items =
+        impl_items.find(&impl_id)
+                  .expect("could not find impl while translating");
+    let meth_did = impl_items.iter()
+                             .find(|&did| {
+                                match *did {
+                                    ty::MethodTraitItemId(did) => {
+                                        ty::impl_or_trait_item(&ccx.tcx,
+                                                               did).ident()
+                                                                   .name ==
+                                            name
+                                    }
+                                }
+                             }).expect("could not find method while \
+                                        translating");
+
+    ccx.impl_method_cache.borrow_mut().insert((impl_id, name),
+                                              meth_did.def_id());
+    meth_did.def_id()
 }
 
 fn trans_monomorphized_callee<'a>(
@@ -242,7 +262,9 @@ fn trans_monomorphized_callee<'a>(
     match vtbl {
       typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
           let ccx = bcx.ccx();
-          let mname = ty::trait_method(ccx.tcx(), trait_id, n_method).ident;
+          let mname = match ty::trait_item(ccx.tcx(), trait_id, n_method) {
+              ty::MethodTraitItem(method) => method.ident,
+          };
           let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name);
 
           // create a concatenated set of substitutions which includes
@@ -433,7 +455,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
 
     return Callee {
         bcx: bcx,
-        data: TraitMethod(MethodData {
+        data: TraitItem(MethodData {
             llfn: mptr,
             llself: llself,
         })
@@ -552,35 +574,42 @@ fn emit_vtable_methods(bcx: &Block,
 
     ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trt_id);
 
-    let trait_method_def_ids = ty::trait_method_def_ids(tcx, trt_id);
-    trait_method_def_ids.iter().map(|method_def_id| {
-        let ident = ty::method(tcx, *method_def_id).ident;
+    let trait_item_def_ids = ty::trait_item_def_ids(tcx, trt_id);
+    trait_item_def_ids.iter().map(|method_def_id| {
+        let method_def_id = method_def_id.def_id();
+        let ident = ty::impl_or_trait_item(tcx, method_def_id).ident();
         // The substitutions we have are on the impl, so we grab
         // the method type from the impl to substitute into.
         let m_id = method_with_name(ccx, impl_id, ident.name);
-        let m = ty::method(tcx, m_id);
-        debug!("(making impl vtable) emitting method {} at subst {}",
-               m.repr(tcx),
-               substs.repr(tcx));
-        if m.generics.has_type_params(subst::FnSpace) ||
-           ty::type_has_self(ty::mk_bare_fn(tcx, m.fty.clone())) {
-            debug!("(making impl vtable) method has self or type params: {}",
-                   token::get_ident(ident));
-            C_null(Type::nil(ccx).ptr_to())
-        } else {
-            let mut fn_ref = trans_fn_ref_with_vtables(bcx,
-                                                       m_id,
-                                                       ExprId(0),
-                                                       substs.clone(),
-                                                       vtables.clone());
-            if m.explicit_self == ty::ByValueExplicitSelfCategory {
-                fn_ref = trans_unboxing_shim(bcx,
-                                             fn_ref,
-                                             &*m,
-                                             m_id,
-                                             substs.clone());
+        let ti = ty::impl_or_trait_item(tcx, m_id);
+        match ti {
+            ty::MethodTraitItem(m) => {
+                debug!("(making impl vtable) emitting method {} at subst {}",
+                       m.repr(tcx),
+                       substs.repr(tcx));
+                if m.generics.has_type_params(subst::FnSpace) ||
+                   ty::type_has_self(ty::mk_bare_fn(tcx, m.fty.clone())) {
+                    debug!("(making impl vtable) method has self or type \
+                            params: {}",
+                           token::get_ident(ident));
+                    C_null(Type::nil(ccx).ptr_to())
+                } else {
+                    let mut fn_ref = trans_fn_ref_with_vtables(
+                        bcx,
+                        m_id,
+                        ExprId(0),
+                        substs.clone(),
+                        vtables.clone());
+                    if m.explicit_self == ty::ByValueExplicitSelfCategory {
+                        fn_ref = trans_unboxing_shim(bcx,
+                                                     fn_ref,
+                                                     &*m,
+                                                     m_id,
+                                                     substs.clone());
+                    }
+                    fn_ref
+                }
             }
-            fn_ref
         }
     }).collect()
 }
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index 6d705c7d914..e19ee035a78 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -197,15 +197,25 @@ pub fn monomorphic_fn(ccx: &CrateContext,
             }
             d
         }
-        ast_map::NodeMethod(mth) => {
-            let d = mk_lldecl(abi::Rust);
-            set_llvm_fn_attrs(mth.attrs.as_slice(), d);
-            trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, &psubsts, mth.id, []);
-            d
+        ast_map::NodeImplItem(ii) => {
+            match *ii {
+                ast::MethodImplItem(mth) => {
+                    let d = mk_lldecl(abi::Rust);
+                    set_llvm_fn_attrs(mth.attrs.as_slice(), d);
+                    trans_fn(ccx,
+                             &*mth.pe_fn_decl(),
+                             &*mth.pe_body(),
+                             d,
+                             &psubsts,
+                             mth.id,
+                             []);
+                    d
+                }
+            }
         }
-        ast_map::NodeTraitMethod(method) => {
+        ast_map::NodeTraitItem(method) => {
             match *method {
-                ast::Provided(mth) => {
+                ast::ProvidedMethod(mth) => {
                     let d = mk_lldecl(abi::Rust);
                     set_llvm_fn_attrs(mth.attrs.as_slice(), d);
                     trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 9caa9f681aa..2aff12c2b68 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -25,7 +25,6 @@ use middle::trans::type_of::*;
 use middle::ty;
 use util::ppaux::ty_to_string;
 
-use std::rc::Rc;
 use arena::TypedArena;
 use libc::c_uint;
 use syntax::ast::DefId;
@@ -36,7 +35,7 @@ use syntax::parse::token;
 
 pub struct Reflector<'a, 'b> {
     visitor_val: ValueRef,
-    visitor_methods: &'a [Rc<ty::Method>],
+    visitor_items: &'a [ty::ImplOrTraitItem],
     final_bcx: &'b Block<'b>,
     tydesc_ty: Type,
     bcx: &'b Block<'b>
@@ -87,13 +86,14 @@ impl<'a, 'b> Reflector<'a, 'b> {
     pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
         let fcx = self.bcx.fcx;
         let tcx = self.bcx.tcx();
-        let mth_idx = ty::method_idx(token::str_to_ident(format!(
+        let mth_idx = ty::impl_or_trait_item_idx(token::str_to_ident(format!(
                         "visit_{}", ty_name).as_slice()),
-                                     self.visitor_methods.as_slice()).expect(
+                                     self.visitor_items.as_slice()).expect(
                 format!("couldn't find visit method for {}", ty_name).as_slice());
-        let mth_ty =
-            ty::mk_bare_fn(tcx,
-                           self.visitor_methods[mth_idx].fty.clone());
+        let method = match self.visitor_items[mth_idx] {
+            ty::MethodTraitItem(ref method) => (*method).clone(),
+        };
+        let mth_ty = ty::mk_bare_fn(tcx, method.fty.clone());
         let v = self.visitor_val;
         debug!("passing {} args:", args.len());
         let mut bcx = self.bcx;
@@ -397,10 +397,10 @@ pub fn emit_calls_to_trait_visit_ty<'a>(
     let final = fcx.new_temp_block("final");
     let tydesc_ty = ty::get_tydesc_ty(bcx.tcx()).unwrap();
     let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
-    let visitor_methods = ty::trait_methods(bcx.tcx(), visitor_trait_id);
+    let visitor_items = ty::trait_items(bcx.tcx(), visitor_trait_id);
     let mut r = Reflector {
         visitor_val: visitor_val,
-        visitor_methods: visitor_methods.as_slice(),
+        visitor_items: visitor_items.as_slice(),
         final_bcx: final,
         tydesc_ty: tydesc_ty,
         bcx: bcx
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index f03c982bb08..40c4d9682c4 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -76,11 +76,64 @@ pub struct field {
 }
 
 #[deriving(Clone)]
-pub enum MethodContainer {
+pub enum ImplOrTraitItemContainer {
     TraitContainer(ast::DefId),
     ImplContainer(ast::DefId),
 }
 
+impl ImplOrTraitItemContainer {
+    pub fn id(&self) -> ast::DefId {
+        match *self {
+            TraitContainer(id) => id,
+            ImplContainer(id) => id,
+        }
+    }
+}
+
+#[deriving(Clone)]
+pub enum ImplOrTraitItem {
+    MethodTraitItem(Rc<Method>),
+}
+
+impl ImplOrTraitItem {
+    fn id(&self) -> ImplOrTraitItemId {
+        match *self {
+            MethodTraitItem(ref method) => MethodTraitItemId(method.def_id),
+        }
+    }
+
+    pub fn def_id(&self) -> ast::DefId {
+        match *self {
+            MethodTraitItem(ref method) => method.def_id,
+        }
+    }
+
+    pub fn ident(&self) -> ast::Ident {
+        match *self {
+            MethodTraitItem(ref method) => method.ident,
+        }
+    }
+
+    pub fn container(&self) -> ImplOrTraitItemContainer {
+        match *self {
+            MethodTraitItem(ref method) => method.container,
+        }
+    }
+}
+
+#[deriving(Clone)]
+pub enum ImplOrTraitItemId {
+    MethodTraitItemId(ast::DefId),
+}
+
+impl ImplOrTraitItemId {
+    pub fn def_id(&self) -> ast::DefId {
+        match *self {
+            MethodTraitItemId(def_id) => def_id,
+        }
+    }
+}
+
 #[deriving(Clone)]
 pub struct Method {
     pub ident: ast::Ident,
@@ -89,7 +142,7 @@ pub struct Method {
     pub explicit_self: ExplicitSelfCategory,
     pub vis: ast::Visibility,
     pub def_id: ast::DefId,
-    pub container: MethodContainer,
+    pub container: ImplOrTraitItemContainer,
 
     // If this method is provided, we need to know where it came from
     pub provided_source: Option<ast::DefId>
@@ -102,7 +155,7 @@ impl Method {
                explicit_self: ExplicitSelfCategory,
                vis: ast::Visibility,
                def_id: ast::DefId,
-               container: MethodContainer,
+               container: ImplOrTraitItemContainer,
                provided_source: Option<ast::DefId>)
                -> Method {
        Method {
@@ -274,14 +327,14 @@ pub struct ctxt {
     /// other items.
     pub item_substs: RefCell<NodeMap<ItemSubsts>>,
 
-    /// Maps from a method to the method "descriptor"
-    pub methods: RefCell<DefIdMap<Rc<Method>>>,
+    /// Maps from a trait item to the trait item "descriptor"
+    pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem>>,
 
-    /// Maps from a trait def-id to a list of the def-ids of its methods
-    pub trait_method_def_ids: RefCell<DefIdMap<Rc<Vec<DefId>>>>,
+    /// Maps from a trait def-id to a list of the def-ids of its trait items
+    pub trait_item_def_ids: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItemId>>>>,
 
-    /// A cache for the trait_methods() routine
-    pub trait_methods_cache: RefCell<DefIdMap<Rc<Vec<Rc<Method>>>>>,
+    /// A cache for the trait_items() routine
+    pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem>>>>,
 
     pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef>>>>,
 
@@ -332,11 +385,11 @@ pub struct ctxt {
     /// Methods in these implementations don't need to be exported.
     pub inherent_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
 
-    /// Maps a DefId of an impl to a list of its methods.
+    /// Maps a DefId of an impl to a list of its items.
     /// Note that this contains all of the impls that we know about,
     /// including ones in other crates. It's not clear that this is the best
     /// way to do it.
-    pub impl_methods: RefCell<DefIdMap<Vec<ast::DefId>>>,
+    pub impl_items: RefCell<DefIdMap<Vec<ImplOrTraitItemId>>>,
 
     /// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
     /// present in this set can be warned about.
@@ -1104,9 +1157,9 @@ pub fn mk_ctxt(s: Session,
         tc_cache: RefCell::new(HashMap::new()),
         ast_ty_to_ty_cache: RefCell::new(NodeMap::new()),
         enum_var_cache: RefCell::new(DefIdMap::new()),
-        methods: RefCell::new(DefIdMap::new()),
-        trait_method_def_ids: RefCell::new(DefIdMap::new()),
-        trait_methods_cache: RefCell::new(DefIdMap::new()),
+        impl_or_trait_items: RefCell::new(DefIdMap::new()),
+        trait_item_def_ids: RefCell::new(DefIdMap::new()),
+        trait_items_cache: RefCell::new(DefIdMap::new()),
         impl_trait_cache: RefCell::new(DefIdMap::new()),
         ty_param_defs: RefCell::new(NodeMap::new()),
         adjustments: RefCell::new(NodeMap::new()),
@@ -1120,7 +1173,7 @@ pub fn mk_ctxt(s: Session,
         destructors: RefCell::new(DefIdSet::new()),
         trait_impls: RefCell::new(DefIdMap::new()),
         inherent_impls: RefCell::new(DefIdMap::new()),
-        impl_methods: RefCell::new(DefIdMap::new()),
+        impl_items: RefCell::new(DefIdMap::new()),
         used_unsafe: RefCell::new(NodeSet::new()),
         used_mut_nodes: RefCell::new(NodeSet::new()),
         impl_vtables: RefCell::new(DefIdMap::new()),
@@ -3075,11 +3128,19 @@ pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin)
                 Err(s) => tcx.sess.fatal(s.as_slice()),
             }
         }
-        typeck::MethodParam(typeck::MethodParam{trait_id: trt_id,
-                                                method_num: n_mth, ..}) |
-        typeck::MethodObject(typeck::MethodObject{trait_id: trt_id,
-                                                  method_num: n_mth, ..}) => {
-            ty::trait_method(tcx, trt_id, n_mth).generics.types.clone()
+        typeck::MethodParam(typeck::MethodParam{
+            trait_id: trt_id,
+            method_num: n_mth,
+            ..
+        }) |
+        typeck::MethodObject(typeck::MethodObject{
+                trait_id: trt_id,
+                method_num: n_mth,
+                ..
+        }) => {
+            match ty::trait_item(tcx, trt_id, n_mth) {
+                ty::MethodTraitItem(method) => method.generics.types.clone(),
+            }
         }
     }
 }
@@ -3297,8 +3358,9 @@ pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
               .collect::<Vec<String>>()).as_slice());
 }
 
-pub fn method_idx(id: ast::Ident, meths: &[Rc<Method>]) -> Option<uint> {
-    meths.iter().position(|m| m.ident == id)
+pub fn impl_or_trait_item_idx(id: ast::Ident, trait_items: &[ImplOrTraitItem])
+                              -> Option<uint> {
+    trait_items.iter().position(|m| m.ident() == id)
 }
 
 /// Returns a vector containing the indices of all type parameters that appear
@@ -3540,7 +3602,15 @@ pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec<Rc<Method>> {
                 match item.node {
                     ItemTrait(_, _, _, ref ms) => {
                         let (_, p) = ast_util::split_trait_methods(ms.as_slice());
-                        p.iter().map(|m| method(cx, ast_util::local_def(m.id))).collect()
+                        p.iter()
+                         .map(|m| {
+                            match impl_or_trait_item(
+                                    cx,
+                                    ast_util::local_def(m.id)) {
+                                MethodTraitItem(m) => m,
+                            }
+                         })
+                         .collect()
                     }
                     _ => {
                         cx.sess.bug(format!("provided_trait_methods: `{}` is \
@@ -3592,7 +3662,7 @@ fn lookup_locally_or_in_crate_store<V:Clone>(
     /*!
      * Helper for looking things up in the various maps
      * that are populated during typeck::collect (e.g.,
-     * `cx.methods`, `cx.tcache`, etc).  All of these share
+     * `cx.impl_or_trait_items`, `cx.tcache`, etc).  All of these share
      * the pattern that if the id is local, it should have
      * been loaded into the map by the `typeck::collect` phase.
      * If the def-id is external, then we have to go consult
@@ -3612,40 +3682,47 @@ fn lookup_locally_or_in_crate_store<V:Clone>(
     v
 }
 
-pub fn trait_method(cx: &ctxt, trait_did: ast::DefId, idx: uint) -> Rc<Method> {
-    let method_def_id = *ty::trait_method_def_ids(cx, trait_did).get(idx);
-    ty::method(cx, method_def_id)
+pub fn trait_item(cx: &ctxt, trait_did: ast::DefId, idx: uint)
+                  -> ImplOrTraitItem {
+    let method_def_id = ty::trait_item_def_ids(cx, trait_did).get(idx)
+                                                             .def_id();
+    impl_or_trait_item(cx, method_def_id)
 }
 
-
-pub fn trait_methods(cx: &ctxt, trait_did: ast::DefId) -> Rc<Vec<Rc<Method>>> {
-    let mut trait_methods = cx.trait_methods_cache.borrow_mut();
-    match trait_methods.find_copy(&trait_did) {
-        Some(methods) => methods,
+pub fn trait_items(cx: &ctxt, trait_did: ast::DefId)
+                   -> Rc<Vec<ImplOrTraitItem>> {
+    let mut trait_items = cx.trait_items_cache.borrow_mut();
+    match trait_items.find_copy(&trait_did) {
+        Some(trait_items) => trait_items,
         None => {
-            let def_ids = ty::trait_method_def_ids(cx, trait_did);
-            let methods: Rc<Vec<Rc<Method>>> = Rc::new(def_ids.iter().map(|d| {
-                ty::method(cx, *d)
-            }).collect());
-            trait_methods.insert(trait_did, methods.clone());
-            methods
+            let def_ids = ty::trait_item_def_ids(cx, trait_did);
+            let items: Rc<Vec<ImplOrTraitItem>> =
+                Rc::new(def_ids.iter()
+                               .map(|d| impl_or_trait_item(cx, d.def_id()))
+                               .collect());
+            trait_items.insert(trait_did, items.clone());
+            items
         }
     }
 }
 
-pub fn method(cx: &ctxt, id: ast::DefId) -> Rc<Method> {
-    lookup_locally_or_in_crate_store("methods", id,
-                                     &mut *cx.methods.borrow_mut(), || {
-        Rc::new(csearch::get_method(cx, id))
+pub fn impl_or_trait_item(cx: &ctxt, id: ast::DefId) -> ImplOrTraitItem {
+    lookup_locally_or_in_crate_store("impl_or_trait_items",
+                                     id,
+                                     &mut *cx.impl_or_trait_items
+                                             .borrow_mut(),
+                                     || {
+        csearch::get_impl_or_trait_item(cx, id)
     })
 }
 
-pub fn trait_method_def_ids(cx: &ctxt, id: ast::DefId) -> Rc<Vec<DefId>> {
-    lookup_locally_or_in_crate_store("trait_method_def_ids",
+pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
+                          -> Rc<Vec<ImplOrTraitItemId>> {
+    lookup_locally_or_in_crate_store("trait_item_def_ids",
                                      id,
-                                     &mut *cx.trait_method_def_ids.borrow_mut(),
+                                     &mut *cx.trait_item_def_ids.borrow_mut(),
                                      || {
-        Rc::new(csearch::get_trait_method_def_ids(&cx.sess.cstore, id))
+        Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id))
     })
 }
 
@@ -4459,7 +4536,8 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
 
     csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
             |impl_def_id| {
-        let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id);
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
+                                                 impl_def_id);
 
         // Record the trait->implementation mappings, if applicable.
         let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
@@ -4469,14 +4547,21 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for &method_def_id in methods.iter() {
-            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
+        for impl_item_def_id in impl_items.iter() {
+            let method_def_id = impl_item_def_id.def_id();
+            match impl_or_trait_item(tcx, method_def_id) {
+                MethodTraitItem(method) => {
+                    for &source in method.provided_source.iter() {
+                        tcx.provided_method_sources
+                           .borrow_mut()
+                           .insert(method_def_id, source);
+                    }
+                }
             }
         }
 
         // Store the implementation info.
-        tcx.impl_methods.borrow_mut().insert(impl_def_id, methods);
+        tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
 
         // If this is an inherent implementation, record it.
         if associated_traits.is_none() {
@@ -4509,21 +4594,28 @@ pub fn populate_implementations_for_trait_if_necessary(
 
     csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id,
             |implementation_def_id| {
-        let methods = csearch::get_impl_methods(&tcx.sess.cstore, implementation_def_id);
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
 
         // Record the trait->implementation mapping.
         record_trait_implementation(tcx, trait_id, implementation_def_id);
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for &method_def_id in methods.iter() {
-            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
+        for impl_item_def_id in impl_items.iter() {
+            let method_def_id = impl_item_def_id.def_id();
+            match impl_or_trait_item(tcx, method_def_id) {
+                MethodTraitItem(method) => {
+                    for &source in method.provided_source.iter() {
+                        tcx.provided_method_sources
+                           .borrow_mut()
+                           .insert(method_def_id, source);
+                    }
+                }
             }
         }
 
         // Store the implementation info.
-        tcx.impl_methods.borrow_mut().insert(implementation_def_id, methods);
+        tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items);
     });
 
     tcx.populated_external_traits.borrow_mut().insert(trait_id);
@@ -4555,14 +4647,15 @@ pub fn trait_id_of_impl(tcx: &ctxt,
 pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
                        -> Option<ast::DefId> {
     if def_id.krate != LOCAL_CRATE {
-        return match csearch::get_method(tcx, def_id).container {
+        return match csearch::get_impl_or_trait_item(tcx,
+                                                     def_id).container() {
             TraitContainer(_) => None,
             ImplContainer(def_id) => Some(def_id),
         };
     }
-    match tcx.methods.borrow().find_copy(&def_id) {
-        Some(method) => {
-            match method.container {
+    match tcx.impl_or_trait_items.borrow().find_copy(&def_id) {
+        Some(trait_item) => {
+            match trait_item.container() {
                 TraitContainer(_) => None,
                 ImplContainer(def_id) => Some(def_id),
             }
@@ -4571,17 +4664,16 @@ pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
     }
 }
 
-/// If the given def ID describes a method belonging to a trait (either a
+/// If the given def ID describes an item belonging to a trait (either a
 /// default method or an implementation of a trait method), return the ID of
 /// the trait that the method belongs to. Otherwise, return `None`.
-pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId)
-                       -> Option<ast::DefId> {
+pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option<ast::DefId> {
     if def_id.krate != LOCAL_CRATE {
-        return csearch::get_trait_of_method(&tcx.sess.cstore, def_id, tcx);
+        return csearch::get_trait_of_item(&tcx.sess.cstore, def_id, tcx);
     }
-    match tcx.methods.borrow().find_copy(&def_id) {
-        Some(method) => {
-            match method.container {
+    match tcx.impl_or_trait_items.borrow().find_copy(&def_id) {
+        Some(impl_or_trait_item) => {
+            match impl_or_trait_item.container() {
                 TraitContainer(def_id) => Some(def_id),
                 ImplContainer(def_id) => trait_id_of_impl(tcx, def_id),
             }
@@ -4590,25 +4682,27 @@ pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId)
     }
 }
 
-/// If the given def ID describes a method belonging to a trait, (either a
+/// If the given def ID describes an item belonging to a trait, (either a
 /// default method or an implementation of a trait method), return the ID of
 /// the method inside trait definition (this means that if the given def ID
 /// is already that of the original trait method, then the return value is
 /// the same).
 /// Otherwise, return `None`.
-pub fn trait_method_of_method(tcx: &ctxt,
-                              def_id: ast::DefId) -> Option<ast::DefId> {
-    let method = match tcx.methods.borrow().find(&def_id) {
+pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
+                          -> Option<ImplOrTraitItemId> {
+    let impl_item = match tcx.impl_or_trait_items.borrow().find(&def_id) {
         Some(m) => m.clone(),
         None => return None,
     };
-    let name = method.ident.name;
-    match trait_of_method(tcx, def_id) {
+    let name = match impl_item {
+        MethodTraitItem(method) => method.ident.name,
+    };
+    match trait_of_item(tcx, def_id) {
         Some(trait_did) => {
-            let trait_methods = ty::trait_methods(tcx, trait_did);
-            trait_methods.iter()
-                .position(|m| m.ident.name == name)
-                .map(|idx| ty::trait_method(tcx, trait_did, idx).def_id)
+            let trait_items = ty::trait_items(tcx, trait_did);
+            trait_items.iter()
+                .position(|m| m.ident().name == name)
+                .map(|idx| ty::trait_item(tcx, trait_did, idx).id())
         }
         None => None
     }
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index dfcde8ca9b9..1e3ea095704 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -220,9 +220,15 @@ fn get_method_index(tcx: &ty::ctxt,
     // methods from them.
     let mut method_count = 0;
     ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
-        if bound_ref.def_id == trait_ref.def_id { false }
-            else {
-            method_count += ty::trait_methods(tcx, bound_ref.def_id).len();
+        if bound_ref.def_id == trait_ref.def_id {
+            false
+        } else {
+            let trait_items = ty::trait_items(tcx, bound_ref.def_id);
+            for trait_item in trait_items.iter() {
+                match *trait_item {
+                    ty::MethodTraitItem(_) => method_count += 1,
+                }
+            }
             true
         }
     });
@@ -488,11 +494,13 @@ impl<'a> LookupContext<'a> {
         ty::populate_implementations_for_trait_if_necessary(self.tcx(), trait_did);
 
         // Look for explicit implementations.
-        let impl_methods = self.tcx().impl_methods.borrow();
+        let impl_items = self.tcx().impl_items.borrow();
         for impl_infos in self.tcx().trait_impls.borrow().find(&trait_did).iter() {
             for impl_did in impl_infos.borrow().iter() {
-                let methods = impl_methods.get(impl_did);
-                self.push_candidates_from_impl(*impl_did, methods.as_slice(), true);
+                let items = impl_items.get(impl_did);
+                self.push_candidates_from_impl(*impl_did,
+                                               items.as_slice(),
+                                               true);
             }
         }
     }
@@ -520,8 +528,11 @@ impl<'a> LookupContext<'a> {
             trait_did: DefId,
             closure_did: DefId,
             closure_function_type: &ClosureTy) {
-        let method =
-            ty::trait_methods(self.tcx(), trait_did).get(0).clone();
+        let trait_item = ty::trait_items(self.tcx(), trait_did).get(0)
+                                                               .clone();
+        let method = match trait_item {
+            ty::MethodTraitItem(method) => method,
+        };
 
         let vcx = self.fcx.vtable_context();
         let region_params =
@@ -701,14 +712,24 @@ impl<'a> LookupContext<'a> {
             let this_bound_idx = next_bound_idx;
             next_bound_idx += 1;
 
-            let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
-            match trait_methods.iter().position(|m| {
-                m.explicit_self != ty::StaticExplicitSelfCategory &&
-                m.ident.name == self.m_name }) {
+            let trait_items = ty::trait_items(tcx, bound_trait_ref.def_id);
+            match trait_items.iter().position(|ti| {
+                match *ti {
+                    ty::MethodTraitItem(ref m) => {
+                        m.explicit_self != ty::StaticExplicitSelfCategory &&
+                        m.ident.name == self.m_name
+                    }
+                }
+            }) {
                 Some(pos) => {
-                    let method = trait_methods.get(pos).clone();
-
-                    match mk_cand(bound_trait_ref, method, pos, this_bound_idx) {
+                    let method = match *trait_items.get(pos) {
+                        ty::MethodTraitItem(ref method) => (*method).clone(),
+                    };
+
+                    match mk_cand(bound_trait_ref,
+                                  method,
+                                  pos,
+                                  this_bound_idx) {
                         Some(cand) => {
                             debug!("pushing inherent candidate for param: {}",
                                    cand.repr(self.tcx()));
@@ -733,18 +754,20 @@ impl<'a> LookupContext<'a> {
         // metadata if necessary.
         ty::populate_implementations_for_type_if_necessary(self.tcx(), did);
 
-        let impl_methods = self.tcx().impl_methods.borrow();
+        let impl_items = self.tcx().impl_items.borrow();
         for impl_infos in self.tcx().inherent_impls.borrow().find(&did).iter() {
             for impl_did in impl_infos.borrow().iter() {
-                let methods = impl_methods.get(impl_did);
-                self.push_candidates_from_impl(*impl_did, methods.as_slice(), false);
+                let items = impl_items.get(impl_did);
+                self.push_candidates_from_impl(*impl_did,
+                                               items.as_slice(),
+                                               false);
             }
         }
     }
 
     fn push_candidates_from_impl(&mut self,
                                  impl_did: DefId,
-                                 impl_methods: &[DefId],
+                                 impl_items: &[ImplOrTraitItemId],
                                  is_extension: bool) {
         let did = if self.report_statics == ReportStaticMethods {
             // we only want to report each base trait once
@@ -762,13 +785,23 @@ impl<'a> LookupContext<'a> {
 
         debug!("push_candidates_from_impl: {} {}",
                token::get_name(self.m_name),
-               impl_methods.iter().map(|&did| ty::method(self.tcx(), did).ident)
-                                 .collect::<Vec<ast::Ident>>()
-                                 .repr(self.tcx()));
-
-        let method = match impl_methods.iter().map(|&did| ty::method(self.tcx(), did))
-                                              .find(|m| m.ident.name == self.m_name) {
-            Some(method) => method,
+               impl_items.iter()
+                         .map(|&did| {
+                             ty::impl_or_trait_item(self.tcx(),
+                                                    did.def_id()).ident()
+                         })
+                         .collect::<Vec<ast::Ident>>()
+                         .repr(self.tcx()));
+
+        let method = match impl_items.iter()
+                                     .map(|&did| {
+                                         ty::impl_or_trait_item(self.tcx(),
+                                                                did.def_id())
+                                     })
+                                     .find(|m| {
+                                         m.ident().name == self.m_name
+                                     }) {
+            Some(ty::MethodTraitItem(method)) => method,
             None => { return; } // No method with the right name.
         };
 
@@ -1486,9 +1519,16 @@ impl<'a> LookupContext<'a> {
                 let did = if self.report_statics == ReportStaticMethods {
                     // If we're reporting statics, we want to report the trait
                     // definition if possible, rather than an impl
-                    match ty::trait_method_of_method(self.tcx(), impl_did) {
-                        None => {debug!("(report candidate) No trait method found"); impl_did},
-                        Some(trait_did) => {debug!("(report candidate) Found trait ref"); trait_did}
+                    match ty::trait_item_of_item(self.tcx(), impl_did) {
+                        None => {
+                            debug!("(report candidate) No trait method \
+                                    found");
+                            impl_did
+                        }
+                        Some(MethodTraitItemId(trait_did)) => {
+                            debug!("(report candidate) Found trait ref");
+                            trait_did
+                        }
                     }
                 } else {
                     // If it is an instantiated default method, use the original
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index aa5a3585158..3403a51610c 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -123,7 +123,7 @@ use std::mem::replace;
 use std::rc::Rc;
 use std::gc::Gc;
 use syntax::abi;
-use syntax::ast::{Provided, Required};
+use syntax::ast::{ProvidedMethod, RequiredMethod};
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{local_def, PostExpansionMethod};
@@ -680,23 +680,27 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
 
         check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
       }
-      ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => {
+      ast::ItemImpl(_, ref opt_trait_ref, _, ref impl_items) => {
         debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
 
         let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
-        for m in ms.iter() {
-            check_method_body(ccx, &impl_pty.generics, &**m);
+        for impl_item in impl_items.iter() {
+            match *impl_item {
+                ast::MethodImplItem(m) => {
+                    check_method_body(ccx, &impl_pty.generics, &*m);
+                }
+            }
         }
 
         match *opt_trait_ref {
             Some(ref ast_trait_ref) => {
                 let impl_trait_ref =
                     ty::node_id_to_trait_ref(ccx.tcx, ast_trait_ref.ref_id);
-                check_impl_methods_against_trait(ccx,
-                                             it.span,
-                                             ast_trait_ref,
-                                             &*impl_trait_ref,
-                                             ms.as_slice());
+                check_impl_items_against_trait(ccx,
+                                               it.span,
+                                               ast_trait_ref,
+                                               &*impl_trait_ref,
+                                               impl_items.as_slice());
                 vtable::resolve_impl(ccx.tcx, it, &impl_pty.generics, &*impl_trait_ref);
             }
             None => { }
@@ -707,11 +711,11 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
         let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
         for trait_method in (*trait_methods).iter() {
             match *trait_method {
-                Required(..) => {
+                RequiredMethod(..) => {
                     // Nothing to do, since required methods don't have
                     // bodies to check.
                 }
-                Provided(m) => {
+                ProvidedMethod(m) => {
                     check_method_body(ccx, &trait_def.generics, &*m);
                 }
             }
@@ -770,7 +774,9 @@ fn check_method_body(ccx: &CrateCtxt,
             item_generics.repr(ccx.tcx),
             method.id);
     let method_def_id = local_def(method.id);
-    let method_ty = ty::method(ccx.tcx, method_def_id);
+    let method_ty = match ty::impl_or_trait_item(ccx.tcx, method_def_id) {
+        ty::MethodTraitItem(ref method_ty) => (*method_ty).clone(),
+    };
     let method_generics = &method_ty.generics;
 
     let param_env = ty::construct_parameter_environment(ccx.tcx,
@@ -787,43 +793,58 @@ fn check_method_body(ccx: &CrateCtxt,
                   param_env);
 }
 
-fn check_impl_methods_against_trait(ccx: &CrateCtxt,
-                                    impl_span: Span,
-                                    ast_trait_ref: &ast::TraitRef,
-                                    impl_trait_ref: &ty::TraitRef,
-                                    impl_methods: &[Gc<ast::Method>]) {
+fn check_impl_items_against_trait(ccx: &CrateCtxt,
+                                  impl_span: Span,
+                                  ast_trait_ref: &ast::TraitRef,
+                                  impl_trait_ref: &ty::TraitRef,
+                                  impl_items: &[ast::ImplItem]) {
     // Locate trait methods
     let tcx = ccx.tcx;
-    let trait_methods = ty::trait_methods(tcx, impl_trait_ref.def_id);
+    let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id);
 
     // Check existing impl methods to see if they are both present in trait
     // and compatible with trait signature
-    for impl_method in impl_methods.iter() {
-        let impl_method_def_id = local_def(impl_method.id);
-        let impl_method_ty = ty::method(ccx.tcx, impl_method_def_id);
-
-        // If this is an impl of a trait method, find the corresponding
-        // method definition in the trait.
-        let opt_trait_method_ty =
-            trait_methods.iter().
-            find(|tm| tm.ident.name == impl_method_ty.ident.name);
-        match opt_trait_method_ty {
-            Some(trait_method_ty) => {
-                compare_impl_method(ccx.tcx,
-                                    &*impl_method_ty,
-                                    impl_method.span,
-                                    impl_method.pe_body().id,
-                                    &**trait_method_ty,
-                                    &impl_trait_ref.substs);
-            }
-            None => {
-                // This is span_bug as it should have already been caught in resolve.
-                tcx.sess.span_bug(
-                    impl_method.span,
-                    format!(
-                        "method `{}` is not a member of trait `{}`",
-                        token::get_ident(impl_method_ty.ident),
-                        pprust::path_to_string(&ast_trait_ref.path)).as_slice());
+    for impl_item in impl_items.iter() {
+        match *impl_item {
+            ast::MethodImplItem(impl_method) => {
+                let impl_method_def_id = local_def(impl_method.id);
+                let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
+                                                          impl_method_def_id);
+
+                // If this is an impl of a trait method, find the
+                // corresponding method definition in the trait.
+                let opt_trait_method_ty =
+                    trait_items.iter()
+                               .find(|ti| {
+                                   ti.ident().name == impl_item_ty.ident()
+                                                                  .name
+                               });
+                match opt_trait_method_ty {
+                    Some(trait_method_ty) => {
+                        match (trait_method_ty, &impl_item_ty) {
+                            (&ty::MethodTraitItem(ref trait_method_ty),
+                             &ty::MethodTraitItem(ref impl_method_ty)) => {
+                                compare_impl_method(ccx.tcx,
+                                                    &**impl_method_ty,
+                                                    impl_method.span,
+                                                    impl_method.pe_body().id,
+                                                    &**trait_method_ty,
+                                                    &impl_trait_ref.substs);
+                            }
+                        }
+                    }
+                    None => {
+                        // This is span_bug as it should have already been
+                        // caught in resolve.
+                        tcx.sess.span_bug(
+                            impl_method.span,
+                            format!(
+                                "method `{}` is not a member of trait `{}`",
+                                token::get_ident(impl_item_ty.ident()),
+                                pprust::path_to_string(
+                                    &ast_trait_ref.path)).as_slice());
+                    }
+                }
             }
         }
     }
@@ -832,16 +853,26 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
     let provided_methods = ty::provided_trait_methods(tcx,
                                                       impl_trait_ref.def_id);
     let mut missing_methods = Vec::new();
-    for trait_method in trait_methods.iter() {
-        let is_implemented =
-            impl_methods.iter().any(
-                |m| m.pe_ident().name == trait_method.ident.name);
-        let is_provided =
-            provided_methods.iter().any(
-                |m| m.ident.name == trait_method.ident.name);
-        if !is_implemented && !is_provided {
-            missing_methods.push(
-                format!("`{}`", token::get_ident(trait_method.ident)));
+    for trait_item in trait_items.iter() {
+        match *trait_item {
+            ty::MethodTraitItem(ref trait_method) => {
+                let is_implemented =
+                    impl_items.iter().any(|ii| {
+                        match *ii {
+                            ast::MethodImplItem(m) => {
+                                m.pe_ident().name == trait_method.ident.name
+                            }
+                        }
+                    });
+                let is_provided =
+                    provided_methods.iter().any(
+                        |m| m.ident.name == trait_method.ident.name);
+                if !is_implemented && !is_provided {
+                    missing_methods.push(
+                        format!("`{}`",
+                                token::get_ident(trait_method.ident)));
+                }
+            }
         }
     }
 
@@ -853,7 +884,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
 }
 
 /**
- * Checks that a method from an impl/class conforms to the signature of
+ * Checks that a method from an impl conforms to the signature of
  * the same method as declared in the trait.
  *
  * # Parameters
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index 76af54ba4d1..3dee787b6c9 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -20,7 +20,8 @@ use metadata::csearch;
 use middle::subst;
 use middle::subst::{Substs};
 use middle::ty::get;
-use middle::ty::{ImplContainer, lookup_item_type};
+use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
+use middle::ty::{lookup_item_type};
 use middle::ty::{t, ty_bool, ty_char, ty_bot, ty_box, ty_enum, ty_err};
 use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_nil};
 use middle::ty::{ty_param, Polytype, ty_ptr};
@@ -308,7 +309,7 @@ impl<'a> CoherenceChecker<'a> {
             }
         }
 
-        let impl_methods = self.create_impl_from_item(item);
+        let impl_items = self.create_impl_from_item(item);
 
         for associated_trait in associated_traits.iter() {
             let trait_ref = ty::node_id_to_trait_ref(
@@ -337,16 +338,17 @@ impl<'a> CoherenceChecker<'a> {
             }
         }
 
-        tcx.impl_methods.borrow_mut().insert(impl_did, impl_methods);
+        tcx.impl_items.borrow_mut().insert(impl_did, impl_items);
     }
 
     // Creates default method IDs and performs type substitutions for an impl
     // and trait pair. Then, for each provided method in the trait, inserts a
     // `ProvidedMethodInfo` instance into the `provided_method_sources` map.
-    fn instantiate_default_methods(&self,
-                                   impl_id: DefId,
-                                   trait_ref: &ty::TraitRef,
-                                   all_methods: &mut Vec<DefId>) {
+    fn instantiate_default_methods(
+            &self,
+            impl_id: DefId,
+            trait_ref: &ty::TraitRef,
+            all_impl_items: &mut Vec<ImplOrTraitItemId>) {
         let tcx = self.crate_context.tcx;
         debug!("instantiate_default_methods(impl_id={:?}, trait_ref={})",
                impl_id, trait_ref.repr(tcx));
@@ -373,7 +375,7 @@ impl<'a> CoherenceChecker<'a> {
                     Some(trait_method.def_id)));
 
             debug!("new_method_ty={}", new_method_ty.repr(tcx));
-            all_methods.push(new_did);
+            all_impl_items.push(MethodTraitItemId(new_did));
 
             // construct the polytype for the method based on the
             // method_ty.  it will have all the generics from the
@@ -385,7 +387,9 @@ impl<'a> CoherenceChecker<'a> {
             debug!("new_polytype={}", new_polytype.repr(tcx));
 
             tcx.tcache.borrow_mut().insert(new_did, new_polytype);
-            tcx.methods.borrow_mut().insert(new_did, new_method_ty);
+            tcx.impl_or_trait_items
+               .borrow_mut()
+               .insert(new_did, ty::MethodTraitItem(new_method_ty));
 
             // Pair the new synthesized ID up with the
             // ID of the method.
@@ -576,13 +580,20 @@ impl<'a> CoherenceChecker<'a> {
         }
     }
 
-    // Converts an implementation in the AST to a vector of methods.
-    fn create_impl_from_item(&self, item: &Item) -> Vec<DefId> {
+    // 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 trait_refs, _, ref ast_methods) => {
-                let mut methods: Vec<DefId> = ast_methods.iter().map(|ast_method| {
-                    local_def(ast_method.id)
-                }).collect();
+            ItemImpl(_, ref trait_refs, _, ref ast_items) => {
+                let mut items: Vec<ImplOrTraitItemId> =
+                        ast_items.iter()
+                                 .map(|ast_item| {
+                            match *ast_item {
+                                ast::MethodImplItem(ast_method) => {
+                                    MethodTraitItemId(
+                                        local_def(ast_method.id))
+                                }
+                            }
+                        }).collect();
 
                 for trait_ref in trait_refs.iter() {
                     let ty_trait_ref = ty::node_id_to_trait_ref(
@@ -591,10 +602,10 @@ impl<'a> CoherenceChecker<'a> {
 
                     self.instantiate_default_methods(local_def(item.id),
                                                      &*ty_trait_ref,
-                                                     &mut methods);
+                                                     &mut items);
                 }
 
-                methods
+                items
             }
             _ => {
                 self.crate_context.tcx.sess.span_bug(item.span,
@@ -614,7 +625,8 @@ impl<'a> CoherenceChecker<'a> {
                          impls_seen: &mut HashSet<DefId>,
                          impl_def_id: DefId) {
         let tcx = self.crate_context.tcx;
-        let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id);
+        let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
+                                                 impl_def_id);
 
         // Make sure we don't visit the same implementation multiple times.
         if !impls_seen.insert(impl_def_id) {
@@ -629,20 +641,27 @@ impl<'a> CoherenceChecker<'a> {
         // Do a sanity check.
         assert!(associated_traits.is_some());
 
-        // Record all the trait methods.
+        // Record all the trait items.
         for trait_ref in associated_traits.iter() {
             self.add_trait_impl(trait_ref.def_id, impl_def_id);
         }
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for &method_def_id in methods.iter() {
-            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
+        for item_def_id in impl_items.iter() {
+            let impl_item = ty::impl_or_trait_item(tcx, item_def_id.def_id());
+            match impl_item {
+                ty::MethodTraitItem(ref method) => {
+                    for &source in method.provided_source.iter() {
+                        tcx.provided_method_sources
+                           .borrow_mut()
+                           .insert(item_def_id.def_id(), source);
+                    }
+                }
             }
         }
 
-        tcx.impl_methods.borrow_mut().insert(impl_def_id, methods);
+        tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
     }
 
     // Adds implementations and traits from external crates to the coherence
@@ -669,28 +688,31 @@ impl<'a> CoherenceChecker<'a> {
             Some(id) => id, None => { return }
         };
 
-        let impl_methods = tcx.impl_methods.borrow();
+        let impl_items = tcx.impl_items.borrow();
         let trait_impls = match tcx.trait_impls.borrow().find_copy(&drop_trait) {
             None => return, // No types with (new-style) dtors present.
             Some(found_impls) => found_impls
         };
 
         for &impl_did in trait_impls.borrow().iter() {
-            let methods = impl_methods.get(&impl_did);
-            if methods.len() < 1 {
+            let items = impl_items.get(&impl_did);
+            if items.len() < 1 {
                 // We'll error out later. For now, just don't ICE.
                 continue;
             }
-            let method_def_id = *methods.get(0);
+            let method_def_id = *items.get(0);
 
             let self_type = self.get_self_type_for_implementation(impl_did);
             match ty::get(self_type.ty).sty {
                 ty::ty_enum(type_def_id, _) |
                 ty::ty_struct(type_def_id, _) |
                 ty::ty_unboxed_closure(type_def_id, _) => {
-                    tcx.destructor_for_type.borrow_mut().insert(type_def_id,
-                                                                method_def_id);
-                    tcx.destructors.borrow_mut().insert(method_def_id);
+                    tcx.destructor_for_type
+                       .borrow_mut()
+                       .insert(type_def_id, method_def_id.def_id());
+                    tcx.destructors
+                       .borrow_mut()
+                       .insert(method_def_id.def_id());
                 }
                 _ => {
                     // Destructors only work on nominal types.
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index a81c6344cc9..284330c51c8 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -37,7 +37,7 @@ use middle::lang_items::SizedTraitLangItem;
 use middle::resolve_lifetime;
 use middle::subst;
 use middle::subst::{Substs};
-use middle::ty::{ImplContainer, MethodContainer, TraitContainer};
+use middle::ty::{ImplContainer, ImplOrTraitItemContainer, TraitContainer};
 use middle::ty::{Polytype};
 use middle::ty;
 use middle::ty_fold::TypeFolder;
@@ -200,64 +200,74 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
     match tcx.map.get(trait_id) {
         ast_map::NodeItem(item) => {
             match item.node {
-                ast::ItemTrait(_, _, _, ref ms) => {
+                ast::ItemTrait(_, _, _, ref trait_items) => {
                     // For each method, construct a suitable ty::Method and
-                    // store it into the `tcx.methods` table:
-                    for m in ms.iter() {
-                        let ty_method = Rc::new(match m {
-                            &ast::Required(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &m.id,
-                                    &m.ident,
-                                    &m.explicit_self,
-                                    m.abi,
-                                    &m.generics,
-                                    &m.fn_style,
-                                    &*m.decl)
-                            }
+                    // store it into the `tcx.impl_or_trait_items` table:
+                    for trait_item in trait_items.iter() {
+                        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,
+                                            &m.id,
+                                            &m.ident,
+                                            &m.explicit_self,
+                                            m.abi,
+                                            &m.generics,
+                                            &m.fn_style,
+                                            &*m.decl)
+                                    }
+                                    ast::ProvidedMethod(ref m) => {
+                                        ty_method_of_trait_method(
+                                            ccx,
+                                            trait_id,
+                                            &trait_def.generics,
+                                            &m.id,
+                                            &m.pe_ident(),
+                                            m.pe_explicit_self(),
+                                            m.pe_abi(),
+                                            m.pe_generics(),
+                                            &m.pe_fn_style(),
+                                            &*m.pe_fn_decl())
+                                    }
+                                });
 
-                            &ast::Provided(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &m.id,
-                                    &m.pe_ident(),
-                                    m.pe_explicit_self(),
-                                    m.pe_abi(),
-                                    m.pe_generics(),
-                                    &m.pe_fn_style(),
-                                    &*m.pe_fn_decl())
-                            }
-                        });
+                                if ty_method.explicit_self ==
+                                        ty::StaticExplicitSelfCategory {
+                                    make_static_method_ty(ccx, &*ty_method);
+                                }
 
-                        if ty_method.explicit_self ==
-                                ty::StaticExplicitSelfCategory {
-                            make_static_method_ty(ccx, &*ty_method);
+                                tcx.impl_or_trait_items
+                                   .borrow_mut()
+                                   .insert(ty_method.def_id,
+                                           ty::MethodTraitItem(ty_method));
+                            }
                         }
-
-                        tcx.methods.borrow_mut().insert(ty_method.def_id,
-                                                        ty_method);
                     }
 
                     // Add an entry mapping
-                    let method_def_ids = Rc::new(ms.iter().map(|m| {
-                        match m {
-                            &ast::Required(ref ty_method) => {
-                                local_def(ty_method.id)
-                            }
-                            &ast::Provided(ref method) => {
-                                local_def(method.id)
+                    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))
+                                }
                             }
-                        }
-                    }).collect());
+                        }).collect());
 
                     let trait_def_id = local_def(trait_id);
-                    tcx.trait_method_def_ids.borrow_mut()
-                        .insert(trait_def_id, method_def_ids);
+                    tcx.trait_item_def_ids.borrow_mut()
+                        .insert(trait_def_id, trait_item_def_ids);
                 }
                 _ => {} // Ignore things that aren't traits.
             }
@@ -346,12 +356,11 @@ pub fn convert_field(ccx: &CrateCtxt,
 }
 
 fn convert_methods(ccx: &CrateCtxt,
-                   container: MethodContainer,
+                   container: ImplOrTraitItemContainer,
                    ms: &[Gc<ast::Method>],
                    untransformed_rcvr_ty: ty::t,
                    rcvr_ty_generics: &ty::Generics,
-                   rcvr_visibility: ast::Visibility)
-{
+                   rcvr_visibility: ast::Visibility) {
     let tcx = ccx.tcx;
     let mut seen_methods = HashSet::new();
     for m in ms.iter() {
@@ -379,11 +388,13 @@ fn convert_methods(ccx: &CrateCtxt,
 
         write_ty_to_tcx(tcx, m.id, fty);
 
-        tcx.methods.borrow_mut().insert(mty.def_id, mty);
+        tcx.impl_or_trait_items
+           .borrow_mut()
+           .insert(mty.def_id, ty::MethodTraitItem(mty));
     }
 
     fn ty_of_method(ccx: &CrateCtxt,
-                    container: MethodContainer,
+                    container: ImplOrTraitItemContainer,
                     m: &ast::Method,
                     untransformed_rcvr_ty: ty::t,
                     rcvr_ty_generics: &ty::Generics,
@@ -459,7 +470,10 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                                    enum_definition.variants.as_slice(),
                                    generics);
         },
-        ast::ItemImpl(ref generics, ref opt_trait_ref, selfty, ref ms) => {
+        ast::ItemImpl(ref generics,
+                      ref opt_trait_ref,
+                      selfty,
+                      ref impl_items) => {
             let ty_generics = ty_generics_for_type(ccx, generics);
             let selfty = ccx.to_ty(&ExplicitRscope, &*selfty);
             write_ty_to_tcx(tcx, it.id, selfty);
@@ -480,16 +494,22 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                 it.vis
             };
 
-            for method in ms.iter() {
-                check_method_self_type(ccx,
-                                       &BindingRscope::new(method.id),
-                                       selfty,
-                                       method.pe_explicit_self())
+            let mut methods = Vec::new();
+            for impl_item in impl_items.iter() {
+                match *impl_item {
+                    ast::MethodImplItem(ref method) => {
+                        check_method_self_type(ccx,
+                                               &BindingRscope::new(method.id),
+                                               selfty,
+                                               method.pe_explicit_self());
+                        methods.push(*method);
+                    }
+                }
             }
 
             convert_methods(ccx,
                             ImplContainer(local_def(it.id)),
-                            ms.as_slice(),
+                            methods.as_slice(),
                             selfty,
                             &ty_generics,
                             parent_visibility);
@@ -507,14 +527,14 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
                                              0,
                                              local_def(it.id));
                 match *trait_method {
-                    ast::Required(ref type_method) => {
+                    ast::RequiredMethod(ref type_method) => {
                         let rscope = BindingRscope::new(type_method.id);
                         check_method_self_type(ccx,
                                                &rscope,
                                                self_type,
                                                &type_method.explicit_self)
                     }
-                    ast::Provided(ref method) => {
+                    ast::ProvidedMethod(ref method) => {
                         check_method_self_type(ccx,
                                                &BindingRscope::new(method.id),
                                                self_type,
diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs
index e191fb343b5..a4e7f28b450 100644
--- a/src/librustc/middle/typeck/infer/error_reporting.rs
+++ b/src/librustc/middle/typeck/infer/error_reporting.rs
@@ -305,7 +305,8 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
                         },
                         _ => None
                     },
-                    ast_map::NodeMethod(..) => {
+                    ast_map::NodeImplItem(..) |
+                    ast_map::NodeTraitItem(..) => {
                         Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id))
                     },
                     _ => None
@@ -699,9 +700,17 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
                         _ => None
                     }
                 }
-                ast_map::NodeMethod(ref m) => {
-                    Some((m.pe_fn_decl(), m.pe_generics(), m.pe_fn_style(),
-                          m.pe_ident(), Some(m.pe_explicit_self().node), m.span))
+                ast_map::NodeImplItem(ref item) => {
+                    match **item {
+                        ast::MethodImplItem(ref m) => {
+                            Some((m.pe_fn_decl(),
+                                  m.pe_generics(),
+                                  m.pe_fn_style(),
+                                  m.pe_ident(),
+                                  Some(m.pe_explicit_self().node),
+                                  m.span))
+                        }
+                    }
                 },
                 _ => None
             },
@@ -1454,10 +1463,14 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
                 },
                 _ => None
             },
-            ast_map::NodeMethod(m) => {
-                taken.push_all(m.pe_generics().lifetimes.as_slice());
-                Some(m.id)
-            },
+            ast_map::NodeImplItem(ii) => {
+                match *ii {
+                    ast::MethodImplItem(m) => {
+                        taken.push_all(m.pe_generics().lifetimes.as_slice());
+                        Some(m.id)
+                    }
+                }
+            }
             _ => None
         },
         None => None
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index 54b9ce03534..e0fab95a045 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -515,10 +515,14 @@ impl<'a> Visitor<()> for ConstraintContext<'a> {
             }
 
             ast::ItemTrait(..) => {
-                let methods = ty::trait_methods(tcx, did);
-                for method in methods.iter() {
-                    self.add_constraints_from_sig(
-                        &method.fty.sig, self.covariant);
+                let trait_items = ty::trait_items(tcx, did);
+                for trait_item in trait_items.iter() {
+                    match *trait_item {
+                        ty::MethodTraitItem(ref method) => {
+                            self.add_constraints_from_sig(&method.fty.sig,
+                                                          self.covariant);
+                        }
+                    }
                 }
             }
 
@@ -609,8 +613,8 @@ impl<'a> ConstraintContext<'a> {
                         _                    => cannot_happen!(),
                     }
                 }
-                ast_map::NodeTraitMethod(..) => is_inferred = false,
-                ast_map::NodeMethod(_)       => is_inferred = false,
+                ast_map::NodeTraitItem(..)   => is_inferred = false,
+                ast_map::NodeImplItem(..)    => is_inferred = false,
                 _                            => cannot_happen!(),
             }
 
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 4e193f0f1d9..301143e5045 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -762,8 +762,8 @@ impl Repr for ast::DefId {
                 match tcx.map.find(self.node) {
                     Some(ast_map::NodeItem(..)) |
                     Some(ast_map::NodeForeignItem(..)) |
-                    Some(ast_map::NodeMethod(..)) |
-                    Some(ast_map::NodeTraitMethod(..)) |
+                    Some(ast_map::NodeImplItem(..)) |
+                    Some(ast_map::NodeTraitItem(..)) |
                     Some(ast_map::NodeVariant(..)) |
                     Some(ast_map::NodeStructCtor(..)) => {
                         return format!(
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index d45ebb3858e..29668795ed7 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -480,8 +480,8 @@ mod svh_visitor {
             SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
         }
 
-        fn visit_trait_method(&mut self, t: &TraitMethod, e: E) {
-            SawTraitMethod.hash(self.st); visit::walk_trait_method(self, t, e)
+        fn visit_trait_item(&mut self, t: &TraitItem, e: E) {
+            SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t, e)
         }
 
         fn visit_struct_field(&mut self, s: &StructField, e: E) {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 3c942d0791e..0e87be1c241 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -157,13 +157,13 @@ pub fn record_extern_fqn(cx: &core::DocContext,
 
 pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
     let def = ty::lookup_trait_def(tcx, did);
-    let methods = ty::trait_methods(tcx, did).clean();
+    let trait_items = ty::trait_items(tcx, did).clean();
     let provided = ty::provided_trait_methods(tcx, did);
-    let mut methods = methods.move_iter().map(|meth| {
-        if provided.iter().any(|a| a.def_id == meth.def_id) {
-            clean::Provided(meth)
+    let mut items = trait_items.move_iter().map(|trait_item| {
+        if provided.iter().any(|a| a.def_id == trait_item.def_id) {
+            clean::ProvidedMethod(trait_item)
         } else {
-            clean::Required(meth)
+            clean::RequiredMethod(trait_item)
         }
     });
     let supertraits = ty::trait_supertraits(tcx, did);
@@ -176,7 +176,7 @@ pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
 
     clean::Trait {
         generics: (&def.generics, subst::TypeSpace).clean(),
-        methods: methods.collect(),
+        items: items.collect(),
         parents: parents.collect()
     }
 }
@@ -303,27 +303,33 @@ fn build_impl(cx: &core::DocContext,
 
     let attrs = load_attrs(tcx, did);
     let ty = ty::lookup_item_type(tcx, did);
-    let methods = csearch::get_impl_methods(&tcx.sess.cstore,
-                                            did).iter().filter_map(|did| {
-        let method = ty::method(tcx, *did);
-        if method.vis != ast::Public && associated_trait.is_none() {
-            return None
-        }
-        let mut item = ty::method(tcx, *did).clean();
-        item.inner = match item.inner.clone() {
-            clean::TyMethodItem(clean::TyMethod {
-                fn_style, decl, self_, generics
-            }) => {
-                clean::MethodItem(clean::Method {
-                    fn_style: fn_style,
-                    decl: decl,
-                    self_: self_,
-                    generics: generics,
-                })
+    let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
+            .iter()
+            .filter_map(|did| {
+        let did = did.def_id();
+        let impl_item = ty::impl_or_trait_item(tcx, did);
+        match impl_item {
+            ty::MethodTraitItem(method) => {
+                if method.vis != ast::Public && associated_trait.is_none() {
+                    return None
+                }
+                let mut item = method.clean();
+                item.inner = match item.inner.clone() {
+                    clean::TyMethodItem(clean::TyMethod {
+                        fn_style, decl, self_, generics
+                    }) => {
+                        clean::MethodItem(clean::Method {
+                            fn_style: fn_style,
+                            decl: decl,
+                            self_: self_,
+                            generics: generics,
+                        })
+                    }
+                    _ => fail!("not a tymethod"),
+                };
+                Some(item)
             }
-            _ => fail!("not a tymethod"),
-        };
-        Some(item)
+        }
     }).collect();
     return Some(clean::Item {
         inner: clean::ImplItem(clean::Impl {
@@ -336,7 +342,7 @@ fn build_impl(cx: &core::DocContext,
             }),
             for_: ty.ty.clean(),
             generics: (&ty.generics, subst::TypeSpace).clean(),
-            methods: methods,
+            items: trait_items,
         }),
         source: clean::Span::empty(),
         name: None,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index a1f486b3b31..c5d3c73c9bc 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -907,7 +907,7 @@ impl Clean<RetStyle> for ast::RetStyle {
 
 #[deriving(Clone, Encodable, Decodable)]
 pub struct Trait {
-    pub methods: Vec<TraitMethod>,
+    pub items: Vec<TraitItem>,
     pub generics: Generics,
     pub parents: Vec<Type>,
 }
@@ -922,7 +922,7 @@ impl Clean<Item> for doctree::Trait {
             visibility: self.vis.clean(),
             stability: self.stab.clean(),
             inner: TraitItem(Trait {
-                methods: self.methods.clean(),
+                items: self.items.clean(),
                 generics: self.generics.clean(),
                 parents: self.parents.clean(),
             }),
@@ -937,37 +937,50 @@ impl Clean<Type> for ast::TraitRef {
 }
 
 #[deriving(Clone, Encodable, Decodable)]
-pub enum TraitMethod {
-    Required(Item),
-    Provided(Item),
+pub enum TraitItem {
+    RequiredMethod(Item),
+    ProvidedMethod(Item),
 }
 
-impl TraitMethod {
+impl TraitItem {
     pub fn is_req(&self) -> bool {
         match self {
-            &Required(..) => true,
+            &RequiredMethod(..) => true,
             _ => false,
         }
     }
     pub fn is_def(&self) -> bool {
         match self {
-            &Provided(..) => true,
+            &ProvidedMethod(..) => true,
             _ => false,
         }
     }
     pub fn item<'a>(&'a self) -> &'a Item {
         match *self {
-            Required(ref item) => item,
-            Provided(ref item) => item,
+            RequiredMethod(ref item) => item,
+            ProvidedMethod(ref item) => item,
         }
     }
 }
 
-impl Clean<TraitMethod> for ast::TraitMethod {
-    fn clean(&self) -> TraitMethod {
+impl Clean<TraitItem> for ast::TraitItem {
+    fn clean(&self) -> TraitItem {
         match self {
-            &ast::Required(ref t) => Required(t.clean()),
-            &ast::Provided(ref t) => Provided(t.clean()),
+            &ast::RequiredMethod(ref t) => RequiredMethod(t.clean()),
+            &ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean()),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum ImplItem {
+    MethodImplItem(Item),
+}
+
+impl Clean<ImplItem> for ast::ImplItem {
+    fn clean(&self) -> ImplItem {
+        match self {
+            &ast::MethodImplItem(ref t) => MethodImplItem(t.clean()),
         }
     }
 }
@@ -1019,6 +1032,14 @@ impl Clean<Item> for ty::Method {
     }
 }
 
+impl Clean<Item> for ty::ImplOrTraitItem {
+    fn clean(&self) -> Item {
+        match *self {
+            ty::MethodTraitItem(ref mti) => mti.clean(),
+        }
+    }
+}
+
 /// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
 /// type out of the AST/ty::ctxt given one of these, if more information is needed. Most importantly
 /// it does not preserve mutability or boxes.
@@ -1714,7 +1735,7 @@ pub struct Impl {
     pub generics: Generics,
     pub trait_: Option<Type>,
     pub for_: Type,
-    pub methods: Vec<Item>,
+    pub items: Vec<Item>,
     pub derived: bool,
 }
 
@@ -1735,7 +1756,11 @@ impl Clean<Item> for doctree::Impl {
                 generics: self.generics.clean(),
                 trait_: self.trait_.clean(),
                 for_: self.for_.clean(),
-                methods: self.methods.clean(),
+                items: self.items.clean().move_iter().map(|ti| {
+                        match ti {
+                            MethodImplItem(i) => i,
+                        }
+                    }).collect(),
                 derived: detect_derived(self.attrs.as_slice()),
             }),
         }
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 313f1c81c79..a5ead46384a 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -154,7 +154,7 @@ pub struct Static {
 
 pub struct Trait {
     pub name: Ident,
-    pub methods: Vec<ast::TraitMethod>, //should be TraitMethod
+    pub items: Vec<ast::TraitItem>, //should be TraitItem
     pub generics: ast::Generics,
     pub parents: Vec<ast::TraitRef>,
     pub attrs: Vec<ast::Attribute>,
@@ -168,7 +168,7 @@ pub struct Impl {
     pub generics: ast::Generics,
     pub trait_: Option<ast::TraitRef>,
     pub for_: ast::P<ast::Ty>,
-    pub methods: Vec<Gc<ast::Method>>,
+    pub items: Vec<ast::ImplItem>,
     pub attrs: Vec<ast::Attribute>,
     pub where: Span,
     pub vis: ast::Visibility,
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 60853f450ab..f0082f8900e 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -40,29 +40,31 @@ pub trait DocFolder {
                 EnumItem(i)
             },
             TraitItem(mut i) => {
-                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod) -> Option<TraitMethod> {
+                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitItem)
+                        -> Option<TraitItem> {
                     match trm {
-                        Required(it) => {
+                        RequiredMethod(it) => {
                             match this.fold_item(it) {
-                                Some(x) => return Some(Required(x)),
+                                Some(x) => return Some(RequiredMethod(x)),
                                 None => return None,
                             }
                         },
-                        Provided(it) => {
+                        ProvidedMethod(it) => {
                             match this.fold_item(it) {
-                                Some(x) => return Some(Provided(x)),
+                                Some(x) => return Some(ProvidedMethod(x)),
                                 None => return None,
                             }
                         },
                     }
                 }
-                let mut foo = Vec::new(); swap(&mut foo, &mut i.methods);
-                i.methods.extend(foo.move_iter().filter_map(|x| vtrm(self, x)));
+                let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
+                i.items.extend(foo.move_iter().filter_map(|x| vtrm(self, x)));
                 TraitItem(i)
             },
             ImplItem(mut i) => {
-                let mut foo = Vec::new(); swap(&mut foo, &mut i.methods);
-                i.methods.extend(foo.move_iter().filter_map(|x| self.fold_item(x)));
+                let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
+                i.items.extend(foo.move_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 4f511e390ff..bb68c6536a0 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1624,10 +1624,24 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                   it.name.get_ref().as_slice(),
                   t.generics,
                   parents));
-    let required = t.methods.iter().filter(|m| m.is_req()).collect::<Vec<&clean::TraitMethod>>();
-    let provided = t.methods.iter().filter(|m| !m.is_req()).collect::<Vec<&clean::TraitMethod>>();
-
-    if t.methods.len() == 0 {
+    let required = t.items.iter()
+                          .filter(|m| {
+                              match **m {
+                                  clean::RequiredMethod(_) => true,
+                                  _ => false,
+                              }
+                          })
+                          .collect::<Vec<&clean::TraitItem>>();
+    let provided = t.items.iter()
+                          .filter(|m| {
+                              match **m {
+                                  clean::ProvidedMethod(_) => true,
+                                  _ => false,
+                              }
+                          })
+                          .collect::<Vec<&clean::TraitItem>>();
+
+    if t.items.len() == 0 {
         try!(write!(w, "{{ }}"));
     } else {
         try!(write!(w, "{{\n"));
@@ -1651,7 +1665,8 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     // Trait documentation
     try!(document(w, it));
 
-    fn meth(w: &mut fmt::Formatter, m: &clean::TraitMethod) -> fmt::Result {
+    fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitItem)
+                  -> fmt::Result {
         try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>",
                     shortty(m.item()),
                     *m.item().name.get_ref(),
@@ -1669,7 +1684,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
             <div class='methods'>
         "));
         for m in required.iter() {
-            try!(meth(w, *m));
+            try!(trait_item(w, *m));
         }
         try!(write!(w, "</div>"));
     }
@@ -1679,7 +1694,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
             <div class='methods'>
         "));
         for m in provided.iter() {
-            try!(meth(w, *m));
+            try!(trait_item(w, *m));
         }
         try!(write!(w, "</div>"));
     }
@@ -1991,8 +2006,8 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
         None => {}
     }
 
-    fn docmeth(w: &mut fmt::Formatter, item: &clean::Item,
-               dox: bool) -> fmt::Result {
+    fn doctraititem(w: &mut fmt::Formatter, item: &clean::Item, dox: bool)
+                    -> fmt::Result {
         try!(write!(w, "<h4 id='method.{}' class='method'>{}<code>",
                     *item.name.get_ref(),
                     ConciseStability(&item.stability)));
@@ -2008,21 +2023,21 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
     }
 
     try!(write!(w, "<div class='impl-methods'>"));
-    for meth in i.impl_.methods.iter() {
-        try!(docmeth(w, meth, true));
+    for trait_item in i.impl_.items.iter() {
+        try!(doctraititem(w, trait_item, true));
     }
 
     fn render_default_methods(w: &mut fmt::Formatter,
                               t: &clean::Trait,
                               i: &clean::Impl) -> fmt::Result {
-        for method in t.methods.iter() {
-            let n = method.item().name.clone();
-            match i.methods.iter().find(|m| { m.name == n }) {
+        for trait_item in t.items.iter() {
+            let n = trait_item.item().name.clone();
+            match i.items.iter().find(|m| { m.name == n }) {
                 Some(..) => continue,
                 None => {}
             }
 
-            try!(docmeth(w, method.item(), false));
+            try!(doctraititem(w, trait_item.item(), false));
         }
         Ok(())
     }
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index cc5bc5cb7c1..eeccc3303eb 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -202,7 +202,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                     clean::ModuleItem(ref m)
                         if m.items.len() == 0 &&
                            i.doc_value().is_none() => None,
-                    clean::ImplItem(ref i) if i.methods.len() == 0 => None,
+                    clean::ImplItem(ref i) if i.items.len() == 0 => None,
                     _ => {
                         self.retained.insert(i.def_id.node);
                         Some(i)
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 60db4fda051..bbcf38f4955 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -21,7 +21,7 @@ use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
 use syntax::ast::Public;
 
 use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum};
-use clean::{ImplItem, Impl, TraitItem, Trait, TraitMethod, Provided, Required};
+use clean::{ImplItem, Impl, Trait, TraitItem, ProvidedMethod, RequiredMethod};
 use clean::{ViewItemItem, PrimitiveItem};
 
 #[deriving(Zero, Encodable, Decodable, PartialEq, Eq)]
@@ -110,7 +110,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
     match item.inner {
         // Require explicit `pub` to be visible
         StructItem(Struct { fields: ref subitems, .. }) |
-        ImplItem(Impl { methods: ref subitems, trait_: None, .. }) => {
+        ImplItem(Impl { items: ref subitems, trait_: None, .. }) => {
             let subcounts = subitems.iter().filter(|i| visible(*i))
                                            .map(summarize_item)
                                            .map(|s| s.val0())
@@ -124,16 +124,21 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
                                            .sum();
             (item_counts + subcounts, None)
         }
-        TraitItem(Trait { methods: ref methods, .. }) => {
-            fn extract_item<'a>(meth: &'a TraitMethod) -> &'a Item {
-                match *meth {
-                    Provided(ref item) | Required(ref item) => item
+        TraitItem(Trait {
+            items: ref trait_items,
+            ..
+        }) => {
+            fn extract_item<'a>(trait_item: &'a TraitItem) -> &'a Item {
+                match *trait_item {
+                    ProvidedMethod(ref item) |
+                    RequiredMethod(ref item) => item
                 }
             }
-            let subcounts = methods.iter().map(extract_item)
-                                          .map(summarize_item)
-                                          .map(|s| s.val0())
-                                          .sum();
+            let subcounts = trait_items.iter()
+                                       .map(extract_item)
+                                       .map(summarize_item)
+                                       .map(|s| s.val0())
+                                       .sum();
             (item_counts + subcounts, None)
         }
         ModuleItem(Module { items: ref items, .. }) => {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5b2a542ca96..f7ccad79fda 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -317,10 +317,10 @@ impl<'a> RustdocVisitor<'a> {
                 };
                 om.statics.push(s);
             },
-            ast::ItemTrait(ref gen, _, ref tr, ref met) => {
+            ast::ItemTrait(ref gen, _, ref tr, ref items) => {
                 let t = Trait {
                     name: item.ident,
-                    methods: met.iter().map(|x| (*x).clone()).collect(),
+                    items: items.iter().map(|x| (*x).clone()).collect(),
                     generics: gen.clone(),
                     parents: tr.iter().map(|x| (*x).clone()).collect(),
                     id: item.id,
@@ -331,12 +331,12 @@ impl<'a> RustdocVisitor<'a> {
                 };
                 om.traits.push(t);
             },
-            ast::ItemImpl(ref gen, ref tr, ty, ref meths) => {
+            ast::ItemImpl(ref gen, ref tr, ty, ref items) => {
                 let i = Impl {
                     generics: gen.clone(),
                     trait_: tr.clone(),
                     for_: ty,
-                    methods: meths.iter().map(|x| *x).collect(),
+                    items: items.iter().map(|x| *x).collect(),
                     attrs: item.attrs.iter().map(|x| *x).collect(),
                     id: item.id,
                     where: item.span,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 7d9a23e91ba..1ff8ca10fff 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -767,9 +767,14 @@ pub struct TypeMethod {
 /// doesn't have an implementation, just a signature) or provided (meaning it
 /// has a default implementation).
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
-pub enum TraitMethod {
-    Required(TypeMethod),
-    Provided(Gc<Method>),
+pub enum TraitItem {
+    RequiredMethod(TypeMethod),
+    ProvidedMethod(Gc<Method>),
+}
+
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum ImplItem {
+    MethodImplItem(Gc<Method>),
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
@@ -1273,11 +1278,11 @@ pub enum Item_ {
               Option<TyParamBound>, // (optional) default bound not required for Self.
                                     // Currently, only Sized makes sense here.
               Vec<TraitRef> ,
-              Vec<TraitMethod>),
+              Vec<TraitItem>),
     ItemImpl(Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
-             Vec<Gc<Method>>),
+             Vec<ImplItem>),
     /// A macro invocation (which includes macro definition)
     ItemMac(Mac),
 }
@@ -1311,10 +1316,16 @@ pub enum UnboxedClosureKind {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum InlinedItem {
     IIItem(Gc<Item>),
-    IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>),
+    IITraitItem(DefId /* impl id */, InlinedTraitItem),
     IIForeign(Gc<ForeignItem>),
 }
 
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub enum InlinedTraitItem {
+    ProvidedInlinedTraitItem(Gc<Method>),
+    RequiredInlinedTraitItem(Gc<Method>),
+}
+
 #[cfg(test)]
 mod test {
     use serialize::json;
diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
index 83af390c4ed..b00c6ce14b5 100644
--- a/src/libsyntax/ast_map/blocks.rs
+++ b/src/libsyntax/ast_map/blocks.rs
@@ -60,9 +60,9 @@ impl MaybeFnLike for ast::Item {
     }
 }
 
-impl MaybeFnLike for ast::TraitMethod {
+impl MaybeFnLike for ast::TraitItem {
     fn is_fn_like(&self) -> bool {
-        match *self { ast::Provided(_) => true, _ => false, }
+        match *self { ast::ProvidedMethod(_) => true, _ => false, }
     }
 }
 
@@ -97,9 +97,9 @@ impl Code {
         match node {
             ast_map::NodeItem(item) if item.is_fn_like() =>
                 Some(FnLikeCode(new(node))),
-            ast_map::NodeTraitMethod(tm) if tm.is_fn_like() =>
+            ast_map::NodeTraitItem(tm) if tm.is_fn_like() =>
                 Some(FnLikeCode(new(node))),
-            ast_map::NodeMethod(_) =>
+            ast_map::NodeImplItem(_) =>
                 Some(FnLikeCode(new(node))),
             ast_map::NodeExpr(e) if e.is_fn_like() =>
                 Some(FnLikeCode(new(node))),
@@ -200,11 +200,15 @@ impl FnLikeNode {
                     }),
                 _ => fail!("item FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeTraitMethod(ref t) => match **t {
-                ast::Provided(ref m) => method(&**m),
+            ast_map::NodeTraitItem(ref t) => match **t {
+                ast::ProvidedMethod(ref m) => method(&**m),
                 _ => fail!("trait method FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeMethod(ref m) => method(&**m),
+            ast_map::NodeImplItem(ref ii) => {
+                match **ii {
+                    ast::MethodImplItem(ref m) => method(&**m),
+                }
+            }
             ast_map::NodeExpr(ref e) => match e.node {
                 ast::ExprFnBlock(_, ref decl, ref block) =>
                     closure(ClosureParts::new(*decl, *block, e.id, e.span)),
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 881ee4fd8d1..78afa8441c5 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -99,8 +99,8 @@ pub fn path_to_string<PI: Iterator<PathElem>>(mut path: PI) -> String {
 pub enum Node {
     NodeItem(Gc<Item>),
     NodeForeignItem(Gc<ForeignItem>),
-    NodeTraitMethod(Gc<TraitMethod>),
-    NodeMethod(Gc<Method>),
+    NodeTraitItem(Gc<TraitItem>),
+    NodeImplItem(Gc<ImplItem>),
     NodeVariant(P<Variant>),
     NodeExpr(Gc<Expr>),
     NodeStmt(Gc<Stmt>),
@@ -125,8 +125,8 @@ enum MapEntry {
     /// All the node types, with a parent ID.
     EntryItem(NodeId, Gc<Item>),
     EntryForeignItem(NodeId, Gc<ForeignItem>),
-    EntryTraitMethod(NodeId, Gc<TraitMethod>),
-    EntryMethod(NodeId, Gc<Method>),
+    EntryTraitItem(NodeId, Gc<TraitItem>),
+    EntryImplItem(NodeId, Gc<ImplItem>),
     EntryVariant(NodeId, P<Variant>),
     EntryExpr(NodeId, Gc<Expr>),
     EntryStmt(NodeId, Gc<Stmt>),
@@ -144,7 +144,7 @@ enum MapEntry {
 
 struct InlinedParent {
     path: Vec<PathElem> ,
-    /// Required by NodeTraitMethod and NodeMethod.
+    /// RequiredMethod by NodeTraitItem and NodeImplItem.
     def_id: DefId
 }
 
@@ -153,8 +153,8 @@ impl MapEntry {
         Some(match *self {
             EntryItem(id, _) => id,
             EntryForeignItem(id, _) => id,
-            EntryTraitMethod(id, _) => id,
-            EntryMethod(id, _) => id,
+            EntryTraitItem(id, _) => id,
+            EntryImplItem(id, _) => id,
             EntryVariant(id, _) => id,
             EntryExpr(id, _) => id,
             EntryStmt(id, _) => id,
@@ -172,8 +172,8 @@ impl MapEntry {
         Some(match *self {
             EntryItem(_, p) => NodeItem(p),
             EntryForeignItem(_, p) => NodeForeignItem(p),
-            EntryTraitMethod(_, p) => NodeTraitMethod(p),
-            EntryMethod(_, p) => NodeMethod(p),
+            EntryTraitItem(_, p) => NodeTraitItem(p),
+            EntryImplItem(_, p) => NodeImplItem(p),
             EntryVariant(_, p) => NodeVariant(p),
             EntryExpr(_, p) => NodeExpr(p),
             EntryStmt(_, p) => NodeStmt(p),
@@ -324,13 +324,23 @@ impl Map {
                 }
             }
             NodeForeignItem(i) => PathName(i.ident.name),
-            NodeMethod(m) => match m.node {
-                MethDecl(ident, _, _, _, _, _, _, _) => PathName(ident.name),
-                MethMac(_) => fail!("no path elem for {:?}", node)
+            NodeImplItem(ii) => {
+                match *ii {
+                    MethodImplItem(ref m) => {
+                        match m.node {
+                            MethDecl(ident, _, _, _, _, _, _, _) => {
+                                PathName(ident.name)
+                            }
+                            MethMac(_) => {
+                                fail!("no path elem for {:?}", node)
+                            }
+                        }
+                    }
+                }
             },
-            NodeTraitMethod(tm) => match *tm {
-                Required(ref m) => PathName(m.ident.name),
-                Provided(m) => match m.node {
+            NodeTraitItem(tm) => match *tm {
+                RequiredMethod(ref m) => PathName(m.ident.name),
+                ProvidedMethod(m) => match m.node {
                     MethDecl(ident, _, _, _, _, _, _, _) => {
                         PathName(ident.name)
                     }
@@ -393,11 +403,15 @@ impl Map {
         let attrs = match node {
             NodeItem(ref i) => Some(i.attrs.as_slice()),
             NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()),
-            NodeTraitMethod(ref tm) => match **tm {
-                Required(ref type_m) => Some(type_m.attrs.as_slice()),
-                Provided(ref m) => Some(m.attrs.as_slice())
+            NodeTraitItem(ref tm) => match **tm {
+                RequiredMethod(ref type_m) => Some(type_m.attrs.as_slice()),
+                ProvidedMethod(ref m) => Some(m.attrs.as_slice())
             },
-            NodeMethod(ref m) => Some(m.attrs.as_slice()),
+            NodeImplItem(ref ii) => {
+                match **ii {
+                    MethodImplItem(ref m) => Some(m.attrs.as_slice()),
+                }
+            }
             NodeVariant(ref v) => Some(v.node.attrs.as_slice()),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
@@ -428,13 +442,17 @@ impl Map {
         let sp = match self.find(id) {
             Some(NodeItem(item)) => item.span,
             Some(NodeForeignItem(foreign_item)) => foreign_item.span,
-            Some(NodeTraitMethod(trait_method)) => {
+            Some(NodeTraitItem(trait_method)) => {
                 match *trait_method {
-                    Required(ref type_method) => type_method.span,
-                    Provided(ref method) => method.span,
+                    RequiredMethod(ref type_method) => type_method.span,
+                    ProvidedMethod(ref method) => method.span,
+                }
+            }
+            Some(NodeImplItem(ref impl_item)) => {
+                match **impl_item {
+                    MethodImplItem(ref method) => method.span,
                 }
             }
-            Some(NodeMethod(method)) => method.span,
             Some(NodeVariant(variant)) => variant.span,
             Some(NodeExpr(expr)) => expr.span,
             Some(NodeStmt(stmt)) => stmt.span,
@@ -532,8 +550,8 @@ impl<'a,S:Str> Iterator<NodeId> for NodesMatchingSuffix<'a,S> {
             let (p, name) = match self.map.find_entry(idx) {
                 Some(EntryItem(p, n))        => (p, n.name()),
                 Some(EntryForeignItem(p, n)) => (p, n.name()),
-                Some(EntryTraitMethod(p, n)) => (p, n.name()),
-                Some(EntryMethod(p, n))      => (p, n.name()),
+                Some(EntryTraitItem(p, n))   => (p, n.name()),
+                Some(EntryImplItem(p, n))    => (p, n.name()),
                 Some(EntryVariant(p, n))     => (p, n.name()),
                 _ => continue,
             };
@@ -553,11 +571,18 @@ 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 TraitMethod {
+impl Named for TraitItem {
+    fn name(&self) -> Name {
+        match *self {
+            RequiredMethod(ref tm) => tm.ident.name,
+            ProvidedMethod(m) => m.name(),
+        }
+    }
+}
+impl Named for ImplItem {
     fn name(&self) -> Name {
         match *self {
-            Required(ref tm) => tm.ident.name,
-            Provided(m) => m.name(),
+            MethodImplItem(ref m) => m.name(),
         }
     }
 }
@@ -616,9 +641,15 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
         assert_eq!(self.parent, i.id);
 
         match i.node {
-            ItemImpl(_, _, _, ref ms) => {
-                for &m in ms.iter() {
-                    self.insert(m.id, EntryMethod(self.parent, m));
+            ItemImpl(_, _, _, ref impl_items) => {
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        MethodImplItem(m) => {
+                            self.insert(m.id,
+                                        EntryImplItem(self.parent,
+                                                      box(GC) *impl_item));
+                        }
+                    }
                 }
             }
             ItemEnum(ref enum_definition, _) => {
@@ -649,13 +680,13 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
 
                 for tm in methods.iter() {
                     match *tm {
-                        Required(ref m) => {
-                            self.insert(m.id, EntryTraitMethod(self.parent,
+                        RequiredMethod(ref m) => {
+                            self.insert(m.id, EntryTraitItem(self.parent,
                                                                box(GC) (*tm).clone()));
                         }
-                        Provided(m) => {
-                            self.insert(m.id, EntryTraitMethod(self.parent,
-                                                               box(GC) Provided(m)));
+                        ProvidedMethod(m) => {
+                            self.insert(m.id, EntryTraitItem(self.parent,
+                                                               box(GC) ProvidedMethod(m)));
                         }
                     }
                 }
@@ -798,13 +829,18 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map,
     let ii = fold(&mut cx);
     match ii {
         IIItem(_) => {}
-        IIMethod(impl_did, is_provided, m) => {
-            let entry = if is_provided {
-                EntryTraitMethod(cx.parent, box(GC) Provided(m))
-            } else {
-                EntryMethod(cx.parent, m)
+        IITraitItem(impl_did, inlined_trait_item) => {
+            let (trait_item_id, entry) = match inlined_trait_item {
+                ProvidedInlinedTraitItem(m) => {
+                    (m.id,
+                     EntryTraitItem(cx.parent, box(GC) ProvidedMethod(m)))
+                }
+                RequiredInlinedTraitItem(m) => {
+                    (m.id,
+                     EntryImplItem(cx.parent, box(GC) MethodImplItem(m)))
+                }
             };
-            cx.insert(m.id, entry);
+            cx.insert(trait_item_id, entry);
             def_id = impl_did;
         }
         IIForeign(i) => {
@@ -829,8 +865,8 @@ impl<'a> NodePrinter for pprust::State<'a> {
         match *node {
             NodeItem(a)        => self.print_item(&*a),
             NodeForeignItem(a) => self.print_foreign_item(&*a),
-            NodeTraitMethod(a) => self.print_trait_method(&*a),
-            NodeMethod(a)      => self.print_method(&*a),
+            NodeTraitItem(a)   => self.print_trait_method(&*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),
@@ -870,17 +906,23 @@ fn node_id_to_string(map: &Map, id: NodeId) -> String {
             let path_str = map.path_to_str_with_ident(id, item.ident);
             format!("foreign item {} (id={})", path_str, id)
         }
-        Some(NodeMethod(m)) => match m.node {
-            MethDecl(ident, _, _, _, _, _, _, _) =>
-                format!("method {} in {} (id={})",
-                        token::get_ident(ident),
-                        map.path_to_string(id), id),
-            MethMac(ref mac) =>
-                format!("method macro {} (id={})",
-                        pprust::mac_to_string(mac), id)
-        },
-        Some(NodeTraitMethod(ref tm)) => {
-            let m = ast_util::trait_method_to_ty_method(&**tm);
+        Some(NodeImplItem(ref ii)) => {
+            match **ii {
+                MethodImplItem(ref m) => {
+                    match m.node {
+                        MethDecl(ident, _, _, _, _, _, _, _) =>
+                            format!("method {} in {} (id={})",
+                                    token::get_ident(ident),
+                                    map.path_to_string(id), id),
+                        MethMac(ref mac) =>
+                            format!("method macro {} (id={})",
+                                    pprust::mac_to_string(mac), id)
+                    }
+                }
+            }
+        }
+        Some(NodeTraitItem(ref tm)) => {
+            let m = ast_util::trait_item_to_ty_method(&**tm);
             format!("method {} in {} (id={})",
                     token::get_ident(m.ident),
                     map.path_to_string(id), id)
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index cf2b5bc4063..7689646d373 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -241,51 +241,52 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
     token::gensym_ident(pretty.as_slice())
 }
 
-/// extract a TypeMethod from a TraitMethod. if the TraitMethod is
+pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
+    match method.node {
+        MethDecl(ident,
+                 ref generics,
+                 abi,
+                 explicit_self,
+                 fn_style,
+                 decl,
+                 _,
+                 vis) => {
+            TypeMethod {
+                ident: ident,
+                attrs: method.attrs.clone(),
+                fn_style: fn_style,
+                decl: decl,
+                generics: generics.clone(),
+                explicit_self: explicit_self,
+                id: method.id,
+                span: method.span,
+                vis: vis,
+                abi: abi,
+            }
+        },
+        MethMac(_) => fail!("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_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
+pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod {
     match *method {
-        Required(ref m) => (*m).clone(),
-        Provided(m) => {
-            match m.node {
-                MethDecl(ident,
-                         ref generics,
-                         abi,
-                         explicit_self,
-                         fn_style,
-                         decl,
-                         _,
-                         vis) => {
-                    TypeMethod {
-                        ident: ident,
-                        attrs: m.attrs.clone(),
-                        fn_style: fn_style,
-                        decl: decl,
-                        generics: generics.clone(),
-                        explicit_self: explicit_self,
-                        id: m.id,
-                        span: m.span,
-                        vis: vis,
-                        abi: abi,
-                    }
-                },
-                MethMac(_) => fail!("expected non-macro method declaration")
-            }
-
-        }
+        RequiredMethod(ref m) => (*m).clone(),
+        ProvidedMethod(ref m) => trait_method_to_ty_method(&**m),
     }
 }
 
-pub fn split_trait_methods(trait_methods: &[TraitMethod])
+pub fn split_trait_methods(trait_methods: &[TraitItem])
     -> (Vec<TypeMethod> , Vec<Gc<Method>> ) {
     let mut reqd = Vec::new();
     let mut provd = Vec::new();
     for trt_method in trait_methods.iter() {
         match *trt_method {
-            Required(ref tm) => reqd.push((*tm).clone()),
-            Provided(m) => provd.push(m)
+            RequiredMethod(ref tm) => reqd.push((*tm).clone()),
+            ProvidedMethod(m) => provd.push(m)
         }
     };
     (reqd, provd)
@@ -543,12 +544,12 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
         visit::walk_struct_def(self, struct_def, ());
     }
 
-    fn visit_trait_method(&mut self, tm: &ast::TraitMethod, _: ()) {
+    fn visit_trait_item(&mut self, tm: &ast::TraitItem, _: ()) {
         match *tm {
-            ast::Required(ref m) => self.operation.visit_id(m.id),
-            ast::Provided(ref m) => self.operation.visit_id(m.id),
+            ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
+            ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
         }
-        visit::walk_trait_method(self, tm, ());
+        visit::walk_trait_item(self, tm, ());
     }
 }
 
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index 5842ca4a0d5..7a8ee6d1416 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -452,8 +452,13 @@ impl<'a> TraitDef<'a> {
             self.span,
             ident,
             (vec!(attr)).append(self.attributes.as_slice()),
-            ast::ItemImpl(trait_generics, opt_trait_ref,
-                          self_type, methods))
+            ast::ItemImpl(trait_generics,
+                          opt_trait_ref,
+                          self_type,
+                          methods.move_iter()
+                                 .map(|method| {
+                                     ast::MethodImplItem(method)
+                                 }).collect()))
     }
 
     fn expand_struct_def(&self,
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index cebe1862528..4ed2a3ed4c2 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -834,26 +834,37 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
             let struct_def = folder.fold_struct_def(*struct_def);
             ItemStruct(struct_def, folder.fold_generics(generics))
         }
-        ItemImpl(ref generics, ref ifce, ty, ref methods) => {
+        ItemImpl(ref generics, ref ifce, ty, ref impl_items) => {
             ItemImpl(folder.fold_generics(generics),
                      ifce.as_ref().map(|p| folder.fold_trait_ref(p)),
                      folder.fold_ty(ty),
-                     methods.iter().flat_map(|x| folder.fold_method(*x).move_iter()).collect()
+                     impl_items.iter()
+                               .flat_map(|impl_item| {
+                                    match *impl_item {
+                                        MethodImplItem(x) => {
+                                            folder.fold_method(x)
+                                                  .move_iter()
+                                                  .map(|x| MethodImplItem(x))
+                                        }
+                                    }
+                               }).collect()
             )
         }
         ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
             let methods = methods.iter().flat_map(|method| {
                 let r = match *method {
-                    Required(ref m) =>
-                            SmallVector::one(Required(folder.fold_type_method(m))).move_iter(),
-                    Provided(method) => {
+                    RequiredMethod(ref m) => {
+                            SmallVector::one(RequiredMethod(
+                                    folder.fold_type_method(m))).move_iter()
+                    }
+                    ProvidedMethod(method) => {
                             // the awkward collect/iter idiom here is because
                             // even though an iter and a map satisfy the same trait bound,
                             // they're not actually the same type, so the method arms
                             // don't unify.
-                            let methods : SmallVector<ast::TraitMethod> =
+                            let methods : SmallVector<ast::TraitItem> =
                                 folder.fold_method(method).move_iter()
-                                .map(|m| Provided(m)).collect();
+                                .map(|m| ProvidedMethod(m)).collect();
                             methods.move_iter()
                         }
                 };
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f6db577a004..f272f7e1887 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -13,7 +13,7 @@
 use abi;
 use ast::{BareFnTy, ClosureTy};
 use ast::{StaticRegionTyParamBound, OtherRegionTyParamBound, TraitTyParamBound};
-use ast::{Provided, Public, FnStyle};
+use ast::{ProvidedMethod, Public, FnStyle};
 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, Block};
 use ast::{BlockCheckMode, UnBox};
@@ -33,23 +33,24 @@ use ast::{ExprVstoreUniq, Once, Many};
 use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
 use ast::{FnOnceUnboxedClosureKind};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
-use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
+use ast::{Ident, NormalFn, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
 use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
+use ast::{MethodImplItem};
 use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
 use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
-use ast::{BiRem, Required};
+use ast::{BiRem, RequiredMethod};
 use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub};
 use ast::StrStyle;
 use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
-use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
+use ast::{TokenTree, TraitItem, TraitRef, TTDelim, TTSeq, TTTok};
 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
@@ -1238,7 +1239,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse the methods in a trait declaration
-    pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
+    pub fn parse_trait_methods(&mut self) -> Vec<TraitItem> {
         self.parse_unspanned_seq(
             &token::LBRACE,
             &token::RBRACE,
@@ -1276,7 +1277,7 @@ impl<'a> Parser<'a> {
               token::SEMI => {
                 p.bump();
                 debug!("parse_trait_methods(): parsing required method");
-                Required(TypeMethod {
+                RequiredMethod(TypeMethod {
                     ident: ident,
                     attrs: attrs,
                     fn_style: style,
@@ -1294,7 +1295,7 @@ impl<'a> Parser<'a> {
                 let (inner_attrs, body) =
                     p.parse_inner_attrs_and_block();
                 let attrs = attrs.append(inner_attrs.as_slice());
-                Provided(box(GC) ast::Method {
+                ProvidedMethod(box(GC) ast::Method {
                     attrs: attrs,
                     id: ast::DUMMY_NODE_ID,
                     span: mk_sp(lo, hi),
@@ -4243,6 +4244,18 @@ impl<'a> Parser<'a> {
         (ident, ItemTrait(tps, sized, traits, meths), None)
     }
 
+    fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
+        let mut impl_items = Vec::new();
+        self.expect(&token::LBRACE);
+        let (inner_attrs, next) = self.parse_inner_attrs_and_next();
+        let mut method_attrs = Some(next);
+        while !self.eat(&token::RBRACE) {
+            impl_items.push(MethodImplItem(self.parse_method(method_attrs)));
+            method_attrs = None;
+        }
+        (impl_items, inner_attrs)
+    }
+
     /// Parses two variants (with the region/type params always optional):
     ///    impl<T> Foo { ... }
     ///    impl<T> ToString for ~[T] { ... }
@@ -4284,18 +4297,13 @@ impl<'a> Parser<'a> {
             None
         };
 
-        let mut meths = Vec::new();
-        self.expect(&token::LBRACE);
-        let (inner_attrs, next) = self.parse_inner_attrs_and_next();
-        let mut method_attrs = Some(next);
-        while !self.eat(&token::RBRACE) {
-            meths.push(self.parse_method(method_attrs));
-            method_attrs = None;
-        }
+        let (impl_items, attrs) = self.parse_impl_items();
 
         let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
 
-        (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
+        (ident,
+         ItemImpl(generics, opt_trait, ty, impl_items),
+         Some(attrs))
     }
 
     /// Parse a::B<String,int>
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 4ee73406f03..c573cc0c0ad 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -10,9 +10,9 @@
 
 use abi;
 use ast::{FnMutUnboxedClosureKind, FnOnceUnboxedClosureKind};
-use ast::{FnUnboxedClosureKind, P, OtherRegionTyParamBound};
+use ast::{FnUnboxedClosureKind, MethodImplItem, P, OtherRegionTyParamBound};
 use ast::{StaticRegionTyParamBound, TraitTyParamBound, UnboxedClosureKind};
-use ast::{UnboxedFnTyParamBound, Required, Provided};
+use ast::{UnboxedFnTyParamBound, RequiredMethod, ProvidedMethod};
 use ast;
 use ast_util;
 use owned_slice::OwnedSlice;
@@ -787,7 +787,10 @@ impl<'a> State<'a> {
                                        item.span));
             }
 
-            ast::ItemImpl(ref generics, ref opt_trait, ref ty, ref methods) => {
+            ast::ItemImpl(ref generics,
+                          ref opt_trait,
+                          ref ty,
+                          ref impl_items) => {
                 try!(self.head(visibility_qualified(item.vis,
                                                     "impl").as_slice()));
                 if generics.is_parameterized() {
@@ -809,8 +812,12 @@ impl<'a> State<'a> {
                 try!(space(&mut self.s));
                 try!(self.bopen());
                 try!(self.print_inner_attributes(item.attrs.as_slice()));
-                for meth in methods.iter() {
-                    try!(self.print_method(&**meth));
+                for impl_item in impl_items.iter() {
+                    match *impl_item {
+                        ast::MethodImplItem(meth) => {
+                            try!(self.print_method(&*meth));
+                        }
+                    }
                 }
                 try!(self.bclose(item.span));
             }
@@ -1061,10 +1068,16 @@ impl<'a> State<'a> {
     }
 
     pub fn print_trait_method(&mut self,
-                              m: &ast::TraitMethod) -> IoResult<()> {
+                              m: &ast::TraitItem) -> IoResult<()> {
         match *m {
-            Required(ref ty_m) => self.print_ty_method(ty_m),
-            Provided(ref m) => self.print_method(&**m)
+            RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
+            ProvidedMethod(ref m) => self.print_method(&**m)
+        }
+    }
+
+    pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> {
+        match *ii {
+            MethodImplItem(ref m) => self.print_method(&**m),
         }
     }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 79a870422a6..18cbf797d03 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -99,7 +99,7 @@ pub trait Visitor<E: Clone> {
         walk_fn(self, fk, fd, b, s, e)
     }
     fn visit_ty_method(&mut self, t: &TypeMethod, e: E) { walk_ty_method(self, t, e) }
-    fn visit_trait_method(&mut self, t: &TraitMethod, e: E) { walk_trait_method(self, t, e) }
+    fn visit_trait_item(&mut self, t: &TraitItem, e: E) { walk_trait_item(self, t, e) }
     fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId, e: E) {
         walk_struct_def(self, s, e)
     }
@@ -148,7 +148,16 @@ pub fn walk_inlined_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
     match *item {
         IIItem(i) => visitor.visit_item(&*i, env),
         IIForeign(i) => visitor.visit_foreign_item(&*i, env),
-        IIMethod(_, _, m) => walk_method_helper(visitor, &*m, env),
+        IITraitItem(_, iti) => {
+            match iti {
+                ProvidedInlinedTraitItem(m) => {
+                    walk_method_helper(visitor, &*m, env)
+                }
+                RequiredInlinedTraitItem(m) => {
+                    walk_method_helper(visitor, &*m, env)
+                }
+            }
+        }
     }
 }
 
@@ -269,7 +278,7 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
         ItemImpl(ref type_parameters,
                  ref trait_reference,
                  typ,
-                 ref methods) => {
+                 ref impl_items) => {
             visitor.visit_generics(type_parameters, env.clone());
             match *trait_reference {
                 Some(ref trait_reference) => walk_trait_ref_helper(visitor,
@@ -277,8 +286,12 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
                 None => ()
             }
             visitor.visit_ty(&*typ, env.clone());
-            for method in methods.iter() {
-                walk_method_helper(visitor, &**method, env.clone())
+            for impl_item in impl_items.iter() {
+                match *impl_item {
+                    MethodImplItem(method) => {
+                        walk_method_helper(visitor, &*method, env.clone())
+                    }
+                }
             }
         }
         ItemStruct(ref struct_definition, ref generics) => {
@@ -297,7 +310,7 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E)
                                    env.clone())
             }
             for method in methods.iter() {
-                visitor.visit_trait_method(method, env.clone())
+                visitor.visit_trait_item(method, env.clone())
             }
         }
         ItemMac(ref macro) => visitor.visit_mac(macro, env.clone()),
@@ -626,14 +639,14 @@ pub fn walk_ty_method<E: Clone, V: Visitor<E>>(visitor: &mut V,
     }
 }
 
-pub fn walk_trait_method<E: Clone, V: Visitor<E>>(visitor: &mut V,
-                                                  trait_method: &TraitMethod,
+pub fn walk_trait_item<E: Clone, V: Visitor<E>>(visitor: &mut V,
+                                                  trait_method: &TraitItem,
                                                   env: E) {
     match *trait_method {
-        Required(ref method_type) => {
+        RequiredMethod(ref method_type) => {
             visitor.visit_ty_method(method_type, env)
         }
-        Provided(ref method) => walk_method_helper(visitor, &**method, env),
+        ProvidedMethod(ref method) => walk_method_helper(visitor, &**method, env),
     }
 }