From 4e7d86c079d9b4862bcf72a2a3b1093264fc5731 Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Thu, 16 Oct 2014 17:40:01 +1300
Subject: [PATCH 1/6] Resolve methods called as functions and...

...defined in another crate.

Fixes #18061
---
 src/librustc/metadata/decoder.rs |  6 ++++
 src/librustc/metadata/encoder.rs | 47 ++++++++++++++++++--------------
 src/librustc/middle/resolve.rs   |  7 +----
 3 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 22ebaa40eb2..d72b370864a 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -115,6 +115,8 @@ enum Family {
     CtorFn,                // o
     StaticMethod,          // F
     UnsafeStaticMethod,    // U
+    Method,                // h
+    UnsafeMethod,          // H
     Type,                  // y
     ForeignType,           // T
     Mod,                   // m
@@ -141,6 +143,8 @@ fn item_family(item: rbml::Doc) -> Family {
       'o' => CtorFn,
       'F' => StaticMethod,
       'U' => UnsafeStaticMethod,
+      'h' => Method,
+      'H' => UnsafeMethod,
       'y' => Type,
       'T' => ForeignType,
       'm' => Mod,
@@ -312,6 +316,8 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         UnsafeFn  => DlDef(def::DefFn(did, ast::UnsafeFn, false)),
         Fn        => DlDef(def::DefFn(did, ast::NormalFn, false)),
         CtorFn    => DlDef(def::DefFn(did, ast::NormalFn, true)),
+        UnsafeMethod  => DlDef(def::DefMethod(did, ast::UnsafeFn, false)),
+        Method    => DlDef(def::DefMethod(did, ast::NormalFn, false)),
         StaticMethod | UnsafeStaticMethod => {
             let fn_style = if fam == UnsafeStaticMethod {
                 ast::UnsafeFn
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index fd983075218..2769d713273 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -840,7 +840,7 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
         ty::StaticExplicitSelfCategory => {
             encode_family(rbml_w, fn_style_static_method_family(fn_style));
         }
-        _ => encode_family(rbml_w, style_fn_family(fn_style))
+        _ => encode_family(rbml_w, fn_style_method_family(fn_style))
     }
     encode_provided_source(rbml_w, method_ty.provided_source);
 }
@@ -978,6 +978,13 @@ fn fn_style_static_method_family(s: FnStyle) -> char {
     }
 }
 
+fn fn_style_method_family(s: FnStyle) -> char {
+    match s {
+        UnsafeFn => 'h',
+        NormalFn => 'H',
+    }
+}
+
 
 fn should_inline(attrs: &[Attribute]) -> bool {
     use syntax::attr::*;
@@ -1407,7 +1414,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                         }
                         _ => {
                             encode_family(rbml_w,
-                                          style_fn_family(
+                                          fn_style_method_family(
                                               method_ty.fty.fn_style));
                         }
                     }
@@ -1432,30 +1439,30 @@ fn encode_info_for_item(ecx: &EncodeContext,
             encode_parent_sort(rbml_w, 't');
 
             let trait_item = &ms[i];
-            match &ms[i] {
-                &RequiredMethod(ref tm) => {
-                    encode_attributes(rbml_w, tm.attrs.as_slice());
+            let foo = |rbml_w: &mut Encoder| {
+                // If this is a static method, we've already
+                // encoded this.
+                if is_nonstatic_method {
+                    // FIXME: I feel like there is something funny
+                    // going on.
+                    let pty = ty::lookup_item_type(tcx, item_def_id.def_id());
+                    encode_bounds_and_type(rbml_w, ecx, &pty);
+                }
+            };
+            match trait_item {
+                &RequiredMethod(ref m) => {
+                    encode_attributes(rbml_w, m.attrs.as_slice());
+                    foo(rbml_w);
                     encode_item_sort(rbml_w, 'r');
-                    encode_method_argument_names(rbml_w, &*tm.decl);
+                    encode_method_argument_names(rbml_w, &*m.decl);
                 }
 
                 &ProvidedMethod(ref m) => {
                     encode_attributes(rbml_w, m.attrs.as_slice());
-                    // If this is a static method, we've already
-                    // encoded this.
-                    if is_nonstatic_method {
-                        // FIXME: I feel like there is something funny
-                        // going on.
-                        let pty = ty::lookup_item_type(tcx,
-                                                       item_def_id.def_id());
-                        encode_bounds_and_type(rbml_w, ecx, &pty);
-                    }
+                    foo(rbml_w);
                     encode_item_sort(rbml_w, 'p');
-                    encode_inlined_item(ecx,
-                                        rbml_w,
-                                        IITraitItemRef(def_id, trait_item));
-                    encode_method_argument_names(rbml_w,
-                                                 &*m.pe_fn_decl());
+                    encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
+                    encode_method_argument_names(rbml_w, &*m.pe_fn_decl());
                 }
 
                 &TypeTraitItem(ref associated_type) => {
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 383a60e51da..7b21b8666e2 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1837,7 +1837,7 @@ impl<'a> Resolver<'a> {
                 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
                     .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, is_public);
           }
-          DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) => {
+          DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
             debug!("(building reduced graph for external \
                     crate) building value (fn/static) {}", final_ident);
             child_name_bindings.define_value(def, DUMMY_SP, is_public);
@@ -1902,11 +1902,6 @@ impl<'a> Resolver<'a> {
             // Record the def ID and fields of this struct.
             self.structs.insert(def_id, fields);
           }
-          DefMethod(..) => {
-              debug!("(building reduced graph for external crate) \
-                      ignoring {}", def);
-              // Ignored; handled elsewhere.
-          }
           DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
           DefUse(..) | DefUpvar(..) | DefRegion(..) |
           DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {

From d416d16cce61033b65474967fd7a4d780011dfb8 Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Thu, 16 Oct 2014 17:44:24 +1300
Subject: [PATCH 2/6] Remove FnStyle from DefFn and DefStaticMethod

---
 src/librustc/metadata/csearch.rs        |  1 -
 src/librustc/metadata/decoder.rs        | 39 +++++++----------------
 src/librustc/metadata/encoder.rs        | 41 ++++++-------------------
 src/librustc/middle/astencode.rs        |  7 ++---
 src/librustc/middle/def.rs              |  6 ++--
 src/librustc/middle/intrinsicck.rs      |  2 +-
 src/librustc/middle/resolve.rs          | 19 +++++-------
 src/librustc/middle/save/mod.rs         |  8 ++---
 src/librustc/middle/trans/callee.rs     | 10 +++---
 src/librustc/middle/trans/closure.rs    |  2 +-
 src/librustc/middle/trans/consts.rs     |  2 +-
 src/librustc/middle/trans/expr.rs       |  6 ++--
 src/librustc/middle/ty.rs               |  2 +-
 src/librustc/middle/typeck/check/mod.rs |  2 +-
 14 files changed, 52 insertions(+), 95 deletions(-)

diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 507aaf137cd..13b734a84a4 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -35,7 +35,6 @@ use std::collections::hashmap::HashMap;
 pub struct StaticMethodInfo {
     pub name: ast::Name,
     pub def_id: ast::DefId,
-    pub fn_style: ast::FnStyle,
     pub vis: ast::Visibility,
 }
 
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index d72b370864a..7fc417ddc18 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -111,12 +111,9 @@ enum Family {
     ImmStatic,             // c
     MutStatic,             // b
     Fn,                    // f
-    UnsafeFn,              // u
     CtorFn,                // o
     StaticMethod,          // F
-    UnsafeStaticMethod,    // U
     Method,                // h
-    UnsafeMethod,          // H
     Type,                  // y
     ForeignType,           // T
     Mod,                   // m
@@ -139,12 +136,9 @@ fn item_family(item: rbml::Doc) -> Family {
       'c' => ImmStatic,
       'b' => MutStatic,
       'f' => Fn,
-      'u' => UnsafeFn,
       'o' => CtorFn,
       'F' => StaticMethod,
-      'U' => UnsafeStaticMethod,
       'h' => Method,
-      'H' => UnsafeMethod,
       'y' => Type,
       'T' => ForeignType,
       'm' => Mod,
@@ -313,17 +307,9 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         ImmStatic => DlDef(def::DefStatic(did, false)),
         MutStatic => DlDef(def::DefStatic(did, true)),
         Struct    => DlDef(def::DefStruct(did)),
-        UnsafeFn  => DlDef(def::DefFn(did, ast::UnsafeFn, false)),
-        Fn        => DlDef(def::DefFn(did, ast::NormalFn, false)),
-        CtorFn    => DlDef(def::DefFn(did, ast::NormalFn, true)),
-        UnsafeMethod  => DlDef(def::DefMethod(did, ast::UnsafeFn, false)),
-        Method    => DlDef(def::DefMethod(did, ast::NormalFn, false)),
-        StaticMethod | UnsafeStaticMethod => {
-            let fn_style = if fam == UnsafeStaticMethod {
-                ast::UnsafeFn
-            } else {
-                ast::NormalFn
-            };
+        Fn        => DlDef(def::DefFn(did, false)),
+        CtorFn    => DlDef(def::DefFn(did, true)),
+        Method | StaticMethod => {
             // 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
@@ -337,7 +323,12 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
                 def::FromImpl(item_reqd_and_translated_parent_item(cnum,
                                                                    item))
             };
-            DlDef(def::DefStaticMethod(did, provenance, fn_style))
+            match fam {
+                // We don't bother to get encode/decode the trait id, we don't need it.
+                Method => DlDef(def::DefMethod(did, None, provenance)),
+                StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
+                _ => fail!()
+            }
         }
         Type | ForeignType => DlDef(def::DefTy(did, false)),
         Mod => DlDef(def::DefMod(did)),
@@ -524,7 +515,7 @@ fn each_child_of_item_or_crate(intr: Rc<IdentInterner>,
                         None => {}
                         Some(impl_method_doc) => {
                             match item_family(impl_method_doc) {
-                                StaticMethod | UnsafeStaticMethod => {
+                                StaticMethod => {
                                     // Hand off the static method
                                     // to the callback.
                                     let static_method_name =
@@ -938,18 +929,10 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
         let impl_method_doc = lookup_item(impl_method_id.node, cdata.data());
         let family = item_family(impl_method_doc);
         match family {
-            StaticMethod | UnsafeStaticMethod => {
-                let fn_style;
-                match item_family(impl_method_doc) {
-                    StaticMethod => fn_style = ast::NormalFn,
-                    UnsafeStaticMethod => fn_style = ast::UnsafeFn,
-                    _ => panic!()
-                }
-
+            StaticMethod => {
                 static_impl_methods.push(StaticMethodInfo {
                     name: item_name(&*intr, impl_method_doc),
                     def_id: item_def_id(impl_method_doc, cdata),
-                    fn_style: fn_style,
                     vis: item_visibility(impl_method_doc),
                 });
             }
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 2769d713273..f3f802f35ba 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -835,12 +835,11 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
     encode_method_fty(ecx, rbml_w, &method_ty.fty);
     encode_visibility(rbml_w, method_ty.vis);
     encode_explicit_self(rbml_w, &method_ty.explicit_self);
-    let fn_style = method_ty.fty.fn_style;
     match method_ty.explicit_self {
         ty::StaticExplicitSelfCategory => {
-            encode_family(rbml_w, fn_style_static_method_family(fn_style));
+            encode_family(rbml_w, STATIC_METHOD_FAMILY);
         }
-        _ => encode_family(rbml_w, fn_style_method_family(fn_style))
+        _ => encode_family(rbml_w, METHOD_FAMILY)
     }
     encode_provided_source(rbml_w, method_ty.provided_source);
 }
@@ -964,27 +963,9 @@ fn encode_inlined_item(ecx: &EncodeContext,
     (*eii)(ecx, rbml_w, ii)
 }
 
-fn style_fn_family(s: FnStyle) -> char {
-    match s {
-        UnsafeFn => 'u',
-        NormalFn => 'f',
-    }
-}
-
-fn fn_style_static_method_family(s: FnStyle) -> char {
-    match s {
-        UnsafeFn => 'U',
-        NormalFn => 'F',
-    }
-}
-
-fn fn_style_method_family(s: FnStyle) -> char {
-    match s {
-        UnsafeFn => 'h',
-        NormalFn => 'H',
-    }
-}
-
+const FN_FAMILY: char = 'f';
+const STATIC_METHOD_FAMILY: char = 'F';
+const METHOD_FAMILY: char = 'h';
 
 fn should_inline(attrs: &[Attribute]) -> bool {
     use syntax::attr::*;
@@ -1088,11 +1069,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_stability(rbml_w, stab);
         rbml_w.end_tag();
       }
-      ItemFn(ref decl, fn_style, _, ref generics, _) => {
+      ItemFn(ref decl, _, _, ref generics, _) => {
         add_to_index(item, rbml_w, index);
         rbml_w.start_tag(tag_items_data_item);
         encode_def_id(rbml_w, def_id);
-        encode_family(rbml_w, style_fn_family(fn_style));
+        encode_family(rbml_w, FN_FAMILY);
         let tps_len = generics.ty_params.len();
         encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
         encode_name(rbml_w, item.ident.name);
@@ -1409,13 +1390,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
                     match method_ty.explicit_self {
                         ty::StaticExplicitSelfCategory => {
                             encode_family(rbml_w,
-                                          fn_style_static_method_family(
-                                              method_ty.fty.fn_style));
+                                          STATIC_METHOD_FAMILY);
                         }
                         _ => {
                             encode_family(rbml_w,
-                                          fn_style_method_family(
-                                              method_ty.fty.fn_style));
+                                          METHOD_FAMILY);
                         }
                     }
                     let pty = ty::lookup_item_type(tcx,
@@ -1500,7 +1479,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
     encode_visibility(rbml_w, nitem.vis);
     match nitem.node {
       ForeignItemFn(..) => {
-        encode_family(rbml_w, style_fn_family(NormalFn));
+        encode_family(rbml_w, FN_FAMILY);
         encode_bounds_and_type(rbml_w, ecx,
                                &lookup_item_type(ecx.tcx,local_def(nitem.id)));
         encode_name(rbml_w, nitem.ident.name);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index f6d85a8eb01..3d2bd763a14 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -440,8 +440,8 @@ fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
 impl tr for def::Def {
     fn tr(&self, dcx: &DecodeContext) -> def::Def {
         match *self {
-          def::DefFn(did, p, is_ctor) => def::DefFn(did.tr(dcx), p, is_ctor),
-          def::DefStaticMethod(did, wrapped_did2, p) => {
+          def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
+          def::DefStaticMethod(did, wrapped_did2) => {
             def::DefStaticMethod(did.tr(dcx),
                                    match wrapped_did2 {
                                     def::FromTrait(did2) => {
@@ -450,8 +450,7 @@ impl tr for def::Def {
                                     def::FromImpl(did2) => {
                                         def::FromImpl(did2.tr(dcx))
                                     }
-                                   },
-                                   p)
+                                   })
           }
           def::DefMethod(did0, did1, p) => {
             def::DefMethod(did0.tr(dcx), did1.map(|did1| did1.tr(dcx)), p)
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index f88269ccac9..a71f714a2ef 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -14,8 +14,8 @@ use syntax::ast_util::local_def;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum Def {
-    DefFn(ast::DefId, ast::FnStyle, bool /* is_ctor */),
-    DefStaticMethod(/* method */ ast::DefId, MethodProvenance, ast::FnStyle),
+    DefFn(ast::DefId, bool /* is_ctor */),
+    DefStaticMethod(/* method */ ast::DefId, MethodProvenance),
     DefSelfTy(/* trait id */ ast::NodeId),
     DefMod(ast::DefId),
     DefForeignMod(ast::DefId),
@@ -58,7 +58,7 @@ pub enum MethodProvenance {
 impl Def {
     pub fn def_id(&self) -> ast::DefId {
         match *self {
-            DefFn(id, _, _) | DefStaticMethod(id, _, _) | DefMod(id) |
+            DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |
             DefForeignMod(id) | DefStatic(id, _) |
             DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
             DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 1dd823539b4..2c7c360bb1d 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -121,7 +121,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
         match expr.node {
             ast::ExprPath(..) => {
                 match ty::resolve_expr(self.tcx, expr) {
-                    DefFn(did, _, _) if self.def_id_is_transmute(did) => {
+                    DefFn(did, _) if self.def_id_is_transmute(did) => {
                         let typ = ty::node_id_to_type(self.tcx, expr.id);
                         match ty::get(typ).sty {
                             ty_bare_fn(ref bare_fn_ty)
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 7b21b8666e2..cbda829804b 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -41,7 +41,7 @@ use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt};
 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyProc, TyQPath};
 use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
 use syntax::ast::{TypeImplItem, UnboxedFnTyParamBound, UnnamedField};
-use syntax::ast::{UnsafeFn, Variant, ViewItem, ViewItemExternCrate};
+use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
 use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
 use syntax::ast::{Visibility};
 use syntax::ast;
@@ -1250,11 +1250,11 @@ impl<'a> Resolver<'a> {
                                   sp, is_public);
                 parent
             }
-            ItemFn(_, fn_style, _, _, _) => {
+            ItemFn(_, _, _, _, _) => {
                 let name_bindings =
                     self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
 
-                let def = DefFn(local_def(item.id), fn_style, false);
+                let def = DefFn(local_def(item.id), false);
                 name_bindings.define_value(def, sp, is_public);
                 parent
             }
@@ -1392,8 +1392,7 @@ impl<'a> Resolver<'a> {
                                             // Static methods become
                                             // `DefStaticMethod`s.
                                             DefStaticMethod(local_def(method.id),
-                                                            FromImpl(local_def(item.id)),
-                                                                     method.pe_fn_style())
+                                                            FromImpl(local_def(item.id)))
                                         }
                                         _ => {
                                             // Non-static methods become
@@ -1483,8 +1482,7 @@ impl<'a> Resolver<'a> {
                                     // Static methods become `DefStaticMethod`s.
                                     (DefStaticMethod(
                                             local_def(ty_m.id),
-                                            FromTrait(local_def(item.id)),
-                                            ty_m.fn_style),
+                                            FromTrait(local_def(item.id))),
                                      StaticMethodTraitItemKind)
                                 }
                                 _ => {
@@ -1711,7 +1709,7 @@ impl<'a> Resolver<'a> {
 
         match foreign_item.node {
             ForeignItemFn(_, ref generics) => {
-                let def = DefFn(local_def(foreign_item.id), UnsafeFn, false);
+                let def = DefFn(local_def(foreign_item.id), false);
                 name_bindings.define_value(def, foreign_item.span, is_public);
 
                 self.with_type_parameter_rib(
@@ -1832,7 +1830,7 @@ impl<'a> Resolver<'a> {
                 child_name_bindings.define_value(def, DUMMY_SP, is_exported);
             }
           }
-          DefFn(ctor_id, _, true) => {
+          DefFn(ctor_id, true) => {
             child_name_bindings.define_value(
                 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
                     .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, is_public);
@@ -2025,7 +2023,6 @@ impl<'a> Resolver<'a> {
                                                        DUMMY_SP);
                                     let def = DefFn(
                                         static_method_info.def_id,
-                                        static_method_info.fn_style,
                                         false);
 
                                     method_name_bindings.define_value(
@@ -5641,7 +5638,7 @@ impl<'a> Resolver<'a> {
                 Some(binding) => {
                     let p_str = self.path_names_to_string(&path);
                     match binding.def_for_namespace(ValueNS) {
-                        Some(DefStaticMethod(_, provenance, _)) => {
+                        Some(DefStaticMethod(_, provenance)) => {
                             match provenance {
                                 FromImpl(_) => return StaticMethod(p_str),
                                 FromTrait(_) => unreachable!()
diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs
index 4748de01240..90a21d47903 100644
--- a/src/librustc/middle/save/mod.rs
+++ b/src/librustc/middle/save/mod.rs
@@ -241,7 +241,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             def::DefRegion(_) |
             def::DefTyParamBinder(_) |
             def::DefLabel(_) |
-            def::DefStaticMethod(_, _, _) |
+            def::DefStaticMethod(..) |
             def::DefTyParam(..) |
             def::DefUse(_) |
             def::DefMethod(..) |
@@ -783,7 +783,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                        sub_span,
                                                        def_id,
                                                         self.cur_scope),
-            def::DefStaticMethod(declid, provenence, _) => {
+            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 ti = ty::impl_or_trait_item(&self.analysis.ty_cx,
@@ -825,7 +825,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                        Some(declid),
                                        self.cur_scope);
             },
-            def::DefFn(def_id, _, _) => self.fmt.fn_call_str(ex.span,
+            def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
                                                              sub_span,
                                                              def_id,
                                                              self.cur_scope),
@@ -835,7 +835,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         }
         // modules or types in the path prefix
         match *def {
-            def::DefStaticMethod(_, _, _) => {
+            def::DefStaticMethod(..) => {
                 self.write_sub_path_trait_truncated(path);
             },
             def::DefLocal(_) |
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 1f4a0dadc02..6addd914440 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -144,7 +144,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
         debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
         let expr_ty = node_id_type(bcx, ref_expr.id);
         match def {
-            def::DefFn(did, _, _) if {
+            def::DefFn(did, _) if {
                 let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
                 let maybe_ast_node = maybe_def_id.and_then(|def_id| bcx.tcx().map
                                                                              .find(def_id.node));
@@ -159,7 +159,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                     data: NamedTupleConstructor(substs, 0)
                 }
             }
-            def::DefFn(did, _, _) if match ty::get(expr_ty).sty {
+            def::DefFn(did, _) if match ty::get(expr_ty).sty {
                 ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
                 _ => false
             } => {
@@ -167,11 +167,11 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                 let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
                 Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
             }
-            def::DefFn(did, _, _) | def::DefMethod(did, _, def::FromImpl(_)) |
-            def::DefStaticMethod(did, def::FromImpl(_), _) => {
+            def::DefFn(did, _) | def::DefMethod(did, _, def::FromImpl(_)) |
+            def::DefStaticMethod(did, def::FromImpl(_)) => {
                 fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
             }
-            def::DefStaticMethod(meth_did, def::FromTrait(trait_did), _) |
+            def::DefStaticMethod(meth_did, def::FromTrait(trait_did)) |
             def::DefMethod(meth_did, _, def::FromTrait(trait_did)) => {
                 fn_callee(bcx, meth::trans_static_method_callee(bcx, meth_did,
                                                                 trait_did,
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 717f52d739d..44613e85a82 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -554,7 +554,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
                                is_local: bool) -> ValueRef {
 
     let def_id = match def {
-        def::DefFn(did, _, _) | def::DefStaticMethod(did, _, _) |
+        def::DefFn(did, _) | def::DefStaticMethod(did, _) |
         def::DefVariant(_, did, _) | def::DefStruct(did) => did,
         _ => {
             ccx.sess().bug(format!("get_wrapper_for_bare_fn: \
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 2f193754c1a..6ba6ff6fb21 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -629,7 +629,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef {
 
             let opt_def = cx.tcx().def_map.borrow().find_copy(&e.id);
             match opt_def {
-                Some(def::DefFn(def_id, _fn_style, _)) => {
+                Some(def::DefFn(def_id, _)) => {
                     if !ast_util::is_local(def_id) {
                         let ty = csearch::get_type(cx.tcx(), def_id).ty;
                         base::trans_external_path(cx, def_id, ty)
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 3bfa6af4a9b..f516c6106a9 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1189,13 +1189,13 @@ fn trans_def_fn_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_def_datum_unadjusted");
 
     let llfn = match def {
-        def::DefFn(did, _, _) |
+        def::DefFn(did, _) |
         def::DefStruct(did) | def::DefVariant(_, did, _) |
-        def::DefStaticMethod(did, def::FromImpl(_), _) |
+        def::DefStaticMethod(did, def::FromImpl(_)) |
         def::DefMethod(did, _, def::FromImpl(_)) => {
             callee::trans_fn_ref(bcx, did, ExprId(ref_expr.id))
         }
-        def::DefStaticMethod(impl_did, def::FromTrait(trait_did), _) |
+        def::DefStaticMethod(impl_did, def::FromTrait(trait_did)) |
         def::DefMethod(impl_did, _, def::FromTrait(trait_did)) => {
             meth::trans_static_method_callee(bcx, impl_did,
                                              trait_did, ref_expr.id)
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 763b55a6fa0..b9af31665a1 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3626,7 +3626,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
                 // end (like `UnitStruct`) which means this is an ExprPath to a DefFn. But in case
                 // of unit structs this is should not be interpreted as function pointer but as
                 // call to the constructor.
-                def::DefFn(_, _, true) => RvalueDpsExpr,
+                def::DefFn(_, true) => RvalueDpsExpr,
 
                 // Fn pointers are just scalar values.
                 def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) => RvalueDatumExpr,
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 13ffc1f4fcb..f334d801692 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -4990,7 +4990,7 @@ pub fn polytype_for_def(fcx: &FnCtxt,
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
       }
-      def::DefFn(id, _, _) | def::DefStaticMethod(id, _, _) | def::DefMethod(id, _, _) |
+      def::DefFn(id, _) | def::DefStaticMethod(id, _) | def::DefMethod(id, _, _) |
       def::DefStatic(id, _) | def::DefVariant(_, id, _) |
       def::DefStruct(id) | def::DefConst(id) => {
         return ty::lookup_item_type(fcx.ccx.tcx, id);

From 1397f990fe190d88dff8963eac1cebb25210a09f Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Mon, 20 Oct 2014 14:30:31 +1300
Subject: [PATCH 3/6] Cross crait inherant impls

---
 src/librustc/metadata/csearch.rs |  8 ++++----
 src/librustc/metadata/decoder.rs | 16 ++++++++--------
 src/librustc/middle/resolve.rs   | 20 ++++++++------------
 3 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 13b734a84a4..d92623636f4 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -32,7 +32,7 @@ use syntax::parse::token;
 
 use std::collections::hashmap::HashMap;
 
-pub struct StaticMethodInfo {
+pub struct MethodInfo {
     pub name: ast::Name,
     pub def_id: ast::DefId,
     pub vis: ast::Visibility,
@@ -177,11 +177,11 @@ pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId)
     decoder::get_type_name_if_impl(&*cdata, def.node)
 }
 
-pub fn get_static_methods_if_impl(cstore: &cstore::CStore,
+pub fn get_methods_if_impl(cstore: &cstore::CStore,
                                   def: ast::DefId)
-                               -> Option<Vec<StaticMethodInfo> > {
+                               -> Option<Vec<MethodInfo> > {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_static_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
+    decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
 }
 
 pub fn get_item_attrs(cstore: &cstore::CStore,
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 7fc417ddc18..5403f91645a 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -15,7 +15,7 @@
 use back::svh::Svh;
 use metadata::cstore::crate_metadata;
 use metadata::common::*;
-use metadata::csearch::StaticMethodInfo;
+use metadata::csearch::MethodInfo;
 use metadata::csearch;
 use metadata::cstore;
 use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
@@ -902,10 +902,10 @@ pub fn get_type_name_if_impl(cdata: Cmd,
     ret
 }
 
-pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
+pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
                                   cdata: Cmd,
                                   node_id: ast::NodeId)
-                               -> Option<Vec<StaticMethodInfo> > {
+                               -> Option<Vec<MethodInfo> > {
     let item = lookup_item(node_id, cdata.data());
     if item_family(item) != Impl {
         return None;
@@ -924,14 +924,14 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
         true
     });
 
-    let mut static_impl_methods = Vec::new();
+    let mut impl_methods = Vec::new();
     for impl_method_id in impl_method_ids.iter() {
         let impl_method_doc = lookup_item(impl_method_id.node, cdata.data());
         let family = item_family(impl_method_doc);
         match family {
-            StaticMethod => {
-                static_impl_methods.push(StaticMethodInfo {
-                    name: item_name(&*intr, impl_method_doc),
+            StaticMethod | Method => {
+                impl_methods.push(MethodInfo {
+                    ident: item_name(&*intr, impl_method_doc),
                     def_id: item_def_id(impl_method_doc, cdata),
                     vis: item_visibility(impl_method_doc),
                 });
@@ -940,7 +940,7 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
         }
     }
 
-    return Some(static_impl_methods);
+    return Some(impl_methods);
 }
 
 /// If node_id is the constructor of a tuple struct, retrieve the NodeId of
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index cbda829804b..3d102892277 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1950,15 +1950,14 @@ impl<'a> Resolver<'a> {
                 }
             }
             DlImpl(def) => {
-                // We only process static methods of impls here.
                 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
                     None => {}
                     Some(final_name) => {
-                        let static_methods_opt =
-                            csearch::get_static_methods_if_impl(&self.session.cstore, def);
-                        match static_methods_opt {
-                            Some(ref static_methods) if
-                                static_methods.len() >= 1 => {
+                        let methods_opt =
+                            csearch::get_methods_if_impl(&self.session.cstore, def);
+                        match methods_opt {
+                            Some(ref methods) if
+                                methods.len() >= 1 => {
                                 debug!("(building reduced graph for \
                                         external crate) processing \
                                         static methods for type name {}",
@@ -2008,9 +2007,8 @@ impl<'a> Resolver<'a> {
                                 // Add each static method to the module.
                                 let new_parent =
                                     ModuleReducedGraphParent(type_module);
-                                for static_method_info in
-                                        static_methods.iter() {
-                                    let name = static_method_info.name;
+                                for method_info in methods.iter() {
+                                    let name = method_info.name;
                                     debug!("(building reduced graph for \
                                              external crate) creating \
                                              static method '{}'",
@@ -2021,9 +2019,7 @@ impl<'a> Resolver<'a> {
                                                        new_parent.clone(),
                                                        OverwriteDuplicates,
                                                        DUMMY_SP);
-                                    let def = DefFn(
-                                        static_method_info.def_id,
-                                        false);
+                                    let def = DefFn(method_info.def_id, false);
 
                                     method_name_bindings.define_value(
                                         def, DUMMY_SP,

From 318472bea9c30415a092db9d417589909b98a083 Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Mon, 20 Oct 2014 11:27:56 +1300
Subject: [PATCH 4/6] test

---
 src/test/auxiliary/method_self_arg.rs    | 87 ++++++++++++++++++++++++
 src/test/run-pass/method-self-arg-aux.rs | 42 ++++++++++++
 2 files changed, 129 insertions(+)
 create mode 100644 src/test/auxiliary/method_self_arg.rs
 create mode 100644 src/test/run-pass/method-self-arg-aux.rs

diff --git a/src/test/auxiliary/method_self_arg.rs b/src/test/auxiliary/method_self_arg.rs
new file mode 100644
index 00000000000..8e48ded5653
--- /dev/null
+++ b/src/test/auxiliary/method_self_arg.rs
@@ -0,0 +1,87 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+static mut COUNT: u64 = 1;
+
+pub fn get_count() -> u64 { unsafe { COUNT } }
+pub fn reset_count() { unsafe { COUNT = 1; } }
+
+pub struct Foo;
+
+impl Foo {
+    pub fn foo(self, x: &Foo) {
+        unsafe { COUNT *= 2; }
+        // Test internal call.
+        Foo::bar(&self);
+        Foo::bar(x);
+
+        Foo::baz(self);
+        Foo::baz(*x);
+
+        Foo::qux(box self);
+        Foo::qux(box *x);
+    }
+
+    pub fn bar(&self) {
+        unsafe { COUNT *= 3; }
+    }
+
+    pub fn baz(self) {
+        unsafe { COUNT *= 5; }
+    }
+
+    pub fn qux(self: Box<Foo>) {
+        unsafe { COUNT *= 7; }
+    }
+
+    pub fn run_trait(self) {
+        unsafe { COUNT *= 17; }
+        // Test internal call.
+        Bar::foo1(&self);
+        Bar::foo2(self);
+        Bar::foo3(box self);
+
+        Bar::bar1(&self);
+        Bar::bar2(self);
+        Bar::bar3(box self);
+    }
+}
+
+pub trait Bar {
+    fn foo1(&self);
+    fn foo2(self);
+    fn foo3(self: Box<Self>);
+
+    fn bar1(&self) {
+        unsafe { COUNT *= 7; }
+    }
+    fn bar2(self) {
+        unsafe { COUNT *= 11; }
+    }
+    fn bar3(self: Box<Self>) {
+        unsafe { COUNT *= 13; }
+    }
+}
+
+impl Bar for Foo {
+    fn foo1(&self) {
+        unsafe { COUNT *= 2; }
+    }
+
+    fn foo2(self) {
+        unsafe { COUNT *= 3; }
+    }
+
+    fn foo3(self: Box<Foo>) {
+        unsafe { COUNT *= 5; }
+    }
+}
diff --git a/src/test/run-pass/method-self-arg-aux.rs b/src/test/run-pass/method-self-arg-aux.rs
new file mode 100644
index 00000000000..9c081855a7b
--- /dev/null
+++ b/src/test/run-pass/method-self-arg-aux.rs
@@ -0,0 +1,42 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test method calls with self as an argument (cross-crate)
+
+// aux-build:method_self_arg.rs
+extern crate method_self_arg;
+use method_self_arg::{Foo, Bar};
+
+fn main() {
+    let x = Foo;
+    // Test external call.
+    Foo::bar(&x);
+    Foo::baz(x);
+    Foo::qux(box x);
+
+    x.foo(&x);
+
+    assert!(method_self_arg::get_count() == 2u64*3*3*3*5*5*5*7*7*7);
+
+    method_self_arg::reset_count();
+    // Test external call.
+    Bar::foo1(&x);
+    Bar::foo2(x);
+    Bar::foo3(box x);
+
+    Bar::bar1(&x);
+    Bar::bar2(x);
+    Bar::bar3(box x);
+
+    x.run_trait();
+
+    println!("{}, {}", method_self_arg::get_count(), 2u64*2*3*3*5*5*7*7*11*11*13*13*17);
+    assert!(method_self_arg::get_count() == 2u64*2*3*3*5*5*7*7*11*11*13*13*17);
+}

From 2474d7d2c44a8684925838abc8ef7729d2997a05 Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Thu, 30 Oct 2014 16:33:37 +1300
Subject: [PATCH 5/6] Rebasing and review changes

---
 src/librustc/metadata/decoder.rs              |  4 +-
 src/librustc/metadata/encoder.rs              |  6 +--
 src/test/auxiliary/method_self_arg1.rs        | 44 +++++++++++++++++++
 ...method_self_arg.rs => method_self_arg2.rs} | 26 -----------
 src/test/run-pass/method-self-arg-aux1.rs     | 27 ++++++++++++
 ...elf-arg-aux.rs => method-self-arg-aux2.rs} | 19 ++------
 6 files changed, 80 insertions(+), 46 deletions(-)
 create mode 100644 src/test/auxiliary/method_self_arg1.rs
 rename src/test/auxiliary/{method_self_arg.rs => method_self_arg2.rs} (73%)
 create mode 100644 src/test/run-pass/method-self-arg-aux1.rs
 rename src/test/run-pass/{method-self-arg-aux.rs => method-self-arg-aux2.rs} (60%)

diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 5403f91645a..213f32a1d18 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -327,7 +327,7 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
                 // We don't bother to get encode/decode the trait id, we don't need it.
                 Method => DlDef(def::DefMethod(did, None, provenance)),
                 StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
-                _ => fail!()
+                _ => panic!()
             }
         }
         Type | ForeignType => DlDef(def::DefTy(did, false)),
@@ -931,7 +931,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
         match family {
             StaticMethod | Method => {
                 impl_methods.push(MethodInfo {
-                    ident: item_name(&*intr, impl_method_doc),
+                    name: item_name(&*intr, impl_method_doc),
                     def_id: item_def_id(impl_method_doc, cdata),
                     vis: item_visibility(impl_method_doc),
                 });
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index f3f802f35ba..a5d3cc1f12c 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1418,7 +1418,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
             encode_parent_sort(rbml_w, 't');
 
             let trait_item = &ms[i];
-            let foo = |rbml_w: &mut Encoder| {
+            let encode_trait_item = |rbml_w: &mut Encoder| {
                 // If this is a static method, we've already
                 // encoded this.
                 if is_nonstatic_method {
@@ -1431,14 +1431,14 @@ fn encode_info_for_item(ecx: &EncodeContext,
             match trait_item {
                 &RequiredMethod(ref m) => {
                     encode_attributes(rbml_w, m.attrs.as_slice());
-                    foo(rbml_w);
+                    encode_trait_item(rbml_w);
                     encode_item_sort(rbml_w, 'r');
                     encode_method_argument_names(rbml_w, &*m.decl);
                 }
 
                 &ProvidedMethod(ref m) => {
                     encode_attributes(rbml_w, m.attrs.as_slice());
-                    foo(rbml_w);
+                    encode_trait_item(rbml_w);
                     encode_item_sort(rbml_w, 'p');
                     encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
                     encode_method_argument_names(rbml_w, &*m.pe_fn_decl());
diff --git a/src/test/auxiliary/method_self_arg1.rs b/src/test/auxiliary/method_self_arg1.rs
new file mode 100644
index 00000000000..d02222931e5
--- /dev/null
+++ b/src/test/auxiliary/method_self_arg1.rs
@@ -0,0 +1,44 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+static mut COUNT: u64 = 1;
+
+pub fn get_count() -> u64 { unsafe { COUNT } }
+
+pub struct Foo;
+
+impl Foo {
+    pub fn foo(self, x: &Foo) {
+        unsafe { COUNT *= 2; }
+        // Test internal call.
+        Foo::bar(&self);
+        Foo::bar(x);
+
+        Foo::baz(self);
+        Foo::baz(*x);
+
+        Foo::qux(box self);
+        Foo::qux(box *x);
+    }
+
+    pub fn bar(&self) {
+        unsafe { COUNT *= 3; }
+    }
+
+    pub fn baz(self) {
+        unsafe { COUNT *= 5; }
+    }
+
+    pub fn qux(self: Box<Foo>) {
+        unsafe { COUNT *= 7; }
+    }
+}
diff --git a/src/test/auxiliary/method_self_arg.rs b/src/test/auxiliary/method_self_arg2.rs
similarity index 73%
rename from src/test/auxiliary/method_self_arg.rs
rename to src/test/auxiliary/method_self_arg2.rs
index 8e48ded5653..99eb665388b 100644
--- a/src/test/auxiliary/method_self_arg.rs
+++ b/src/test/auxiliary/method_self_arg2.rs
@@ -13,36 +13,10 @@
 static mut COUNT: u64 = 1;
 
 pub fn get_count() -> u64 { unsafe { COUNT } }
-pub fn reset_count() { unsafe { COUNT = 1; } }
 
 pub struct Foo;
 
 impl Foo {
-    pub fn foo(self, x: &Foo) {
-        unsafe { COUNT *= 2; }
-        // Test internal call.
-        Foo::bar(&self);
-        Foo::bar(x);
-
-        Foo::baz(self);
-        Foo::baz(*x);
-
-        Foo::qux(box self);
-        Foo::qux(box *x);
-    }
-
-    pub fn bar(&self) {
-        unsafe { COUNT *= 3; }
-    }
-
-    pub fn baz(self) {
-        unsafe { COUNT *= 5; }
-    }
-
-    pub fn qux(self: Box<Foo>) {
-        unsafe { COUNT *= 7; }
-    }
-
     pub fn run_trait(self) {
         unsafe { COUNT *= 17; }
         // Test internal call.
diff --git a/src/test/run-pass/method-self-arg-aux1.rs b/src/test/run-pass/method-self-arg-aux1.rs
new file mode 100644
index 00000000000..d4a0d514a7d
--- /dev/null
+++ b/src/test/run-pass/method-self-arg-aux1.rs
@@ -0,0 +1,27 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test method calls with self as an argument (cross-crate)
+
+// aux-build:method_self_arg1.rs
+extern crate method_self_arg1;
+use method_self_arg1::Foo;
+
+fn main() {
+    let x = Foo;
+    // Test external call.
+    Foo::bar(&x);
+    Foo::baz(x);
+    Foo::qux(box x);
+
+    x.foo(&x);
+
+    assert!(method_self_arg1::get_count() == 2u64*3*3*3*5*5*5*7*7*7);
+}
diff --git a/src/test/run-pass/method-self-arg-aux.rs b/src/test/run-pass/method-self-arg-aux2.rs
similarity index 60%
rename from src/test/run-pass/method-self-arg-aux.rs
rename to src/test/run-pass/method-self-arg-aux2.rs
index 9c081855a7b..b94f1ae6ba6 100644
--- a/src/test/run-pass/method-self-arg-aux.rs
+++ b/src/test/run-pass/method-self-arg-aux2.rs
@@ -10,23 +10,13 @@
 
 // Test method calls with self as an argument (cross-crate)
 
-// aux-build:method_self_arg.rs
-extern crate method_self_arg;
-use method_self_arg::{Foo, Bar};
+// aux-build:method_self_arg2.rs
+extern crate method_self_arg2;
+use method_self_arg2::{Foo, Bar};
 
 fn main() {
     let x = Foo;
     // Test external call.
-    Foo::bar(&x);
-    Foo::baz(x);
-    Foo::qux(box x);
-
-    x.foo(&x);
-
-    assert!(method_self_arg::get_count() == 2u64*3*3*3*5*5*5*7*7*7);
-
-    method_self_arg::reset_count();
-    // Test external call.
     Bar::foo1(&x);
     Bar::foo2(x);
     Bar::foo3(box x);
@@ -37,6 +27,5 @@ fn main() {
 
     x.run_trait();
 
-    println!("{}, {}", method_self_arg::get_count(), 2u64*2*3*3*5*5*7*7*11*11*13*13*17);
-    assert!(method_self_arg::get_count() == 2u64*2*3*3*5*5*7*7*11*11*13*13*17);
+    assert!(method_self_arg2::get_count() == 2u64*2*3*3*5*5*7*7*11*11*13*13*17);
 }

From 060566f08a5c6b2343880516799971755183744f Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Fri, 31 Oct 2014 15:00:35 +1300
Subject: [PATCH 6/6] Fix RustDoc bug

---
 src/librustdoc/clean/inline.rs | 17 ++++++++---------
 src/librustdoc/clean/mod.rs    |  2 +-
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 967e1fbb700..d87d8776d4a 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -73,10 +73,10 @@ fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt,
             record_extern_fqn(cx, did, clean::TypeTrait);
             clean::TraitItem(build_external_trait(cx, tcx, did))
         }
-        def::DefFn(did, style, false) => {
+        def::DefFn(did, false) => {
             // If this function is a tuple struct constructor, we just skip it
             record_extern_fqn(cx, did, clean::TypeFunction);
-            clean::FunctionItem(build_external_function(cx, tcx, did, style))
+            clean::FunctionItem(build_external_function(cx, tcx, did))
         }
         def::DefStruct(did) => {
             record_extern_fqn(cx, did, clean::TypeStruct);
@@ -167,15 +167,14 @@ pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
     }
 }
 
-fn build_external_function(cx: &DocContext, tcx: &ty::ctxt,
-                           did: ast::DefId,
-                           style: ast::FnStyle) -> clean::Function {
+fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Function {
     let t = ty::lookup_item_type(tcx, did);
+    let (decl, style) = match ty::get(t.ty).sty {
+        ty::ty_bare_fn(ref f) => ((did, &f.sig).clean(cx), f.fn_style),
+        _ => panic!("bad function"),
+    };
     clean::Function {
-        decl: match ty::get(t.ty).sty {
-            ty::ty_bare_fn(ref f) => (did, &f.sig).clean(cx),
-            _ => panic!("bad function"),
-        },
+        decl: decl,
         generics: (&t.generics, subst::FnSpace).clean(cx),
         fn_style: style,
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 7c8f4ba8f65..c128588918e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2124,7 +2124,7 @@ fn resolve_type(cx: &DocContext, path: Path,
 
 fn register_def(cx: &DocContext, def: def::Def) -> ast::DefId {
     let (did, kind) = match def {
-        def::DefFn(i, _, _) => (i, TypeFunction),
+        def::DefFn(i, _) => (i, TypeFunction),
         def::DefTy(i, false) => (i, TypeTypedef),
         def::DefTy(i, true) => (i, TypeEnum),
         def::DefTrait(i) => (i, TypeTrait),