about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/fold.rs32
-rw-r--r--src/librustc/hir/intravisit.rs22
-rw-r--r--src/librustc/hir/lowering.rs23
-rw-r--r--src/librustc/hir/mod.rs79
-rw-r--r--src/librustc/hir/print.rs112
-rw-r--r--src/librustc/infer/error_reporting.rs58
-rw-r--r--src/librustc/lint/context.rs5
-rw-r--r--src/librustc/middle/resolve_lifetime.rs1
-rw-r--r--src/librustc_incremental/calculate_svh.rs5
-rw-r--r--src/librustc_privacy/lib.rs4
-rw-r--r--src/librustc_resolve/lib.rs1
-rw-r--r--src/librustc_typeck/astconv.rs77
-rw-r--r--src/librustdoc/clean/inline.rs3
-rw-r--r--src/librustdoc/clean/mod.rs113
-rw-r--r--src/librustdoc/html/format.rs42
-rw-r--r--src/librustdoc/html/render.rs50
16 files changed, 196 insertions, 431 deletions
diff --git a/src/librustc/hir/fold.rs b/src/librustc/hir/fold.rs
index fa391538b9c..740d72f4c3e 100644
--- a/src/librustc/hir/fold.rs
+++ b/src/librustc/hir/fold.rs
@@ -158,14 +158,6 @@ pub trait Folder : Sized {
         noop_fold_local(l, self)
     }
 
-    fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf {
-        noop_fold_explicit_self(es, self)
-    }
-
-    fn fold_explicit_self_underscore(&mut self, es: ExplicitSelf_) -> ExplicitSelf_ {
-        noop_fold_explicit_self_underscore(es, self)
-    }
-
     fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime {
         noop_fold_lifetime(l, self)
     }
@@ -495,29 +487,6 @@ pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attr
     })
 }
 
-pub fn noop_fold_explicit_self_underscore<T: Folder>(es: ExplicitSelf_,
-                                                     fld: &mut T)
-                                                     -> ExplicitSelf_ {
-    match es {
-        SelfStatic | SelfValue(_) => es,
-        SelfRegion(lifetime, m, name) => {
-            SelfRegion(fld.fold_opt_lifetime(lifetime), m, name)
-        }
-        SelfExplicit(typ, name) => {
-            SelfExplicit(fld.fold_ty(typ), name)
-        }
-    }
-}
-
-pub fn noop_fold_explicit_self<T: Folder>(Spanned { span, node }: ExplicitSelf,
-                                          fld: &mut T)
-                                          -> ExplicitSelf {
-    Spanned {
-        node: fld.fold_explicit_self_underscore(node),
-        span: fld.new_span(span),
-    }
-}
-
 pub fn noop_fold_meta_item<T: Folder>(mi: P<MetaItem>, fld: &mut T) -> P<MetaItem> {
     mi.map(|Spanned { node, span }| {
         Spanned {
@@ -941,7 +910,6 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method
     MethodSig {
         generics: folder.fold_generics(sig.generics),
         abi: sig.abi,
-        explicit_self: folder.fold_explicit_self(sig.explicit_self),
         unsafety: sig.unsafety,
         constness: sig.constness,
         decl: folder.fold_fn_decl(sig.decl),
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index ec9b465521b..b387ced4822 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -180,9 +180,6 @@ pub trait Visitor<'v> : Sized {
     fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
         walk_lifetime_def(self, lifetime)
     }
-    fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
-        walk_explicit_self(self, es)
-    }
     fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
         walk_path(self, path)
     }
@@ -258,23 +255,6 @@ pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v
     walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
 }
 
-pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, explicit_self: &'v ExplicitSelf) {
-    match explicit_self.node {
-        SelfStatic => {}
-        SelfValue(name) => {
-            visitor.visit_name(explicit_self.span, name)
-        }
-        SelfRegion(ref opt_lifetime, _, name) => {
-            visitor.visit_name(explicit_self.span, name);
-            walk_list!(visitor, visit_lifetime, opt_lifetime);
-        }
-        SelfExplicit(ref typ, name) => {
-            visitor.visit_name(explicit_self.span, name);
-            visitor.visit_ty(typ)
-        }
-    }
-}
-
 pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
                                   trait_ref: &'v PolyTraitRef,
                                   _modifier: &'v TraitBoundModifier)
@@ -620,7 +600,6 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
         }
         FnKind::Method(_, sig, _, _) => {
             visitor.visit_generics(&sig.generics);
-            visitor.visit_explicit_self(&sig.explicit_self);
         }
         FnKind::Closure(_) => {}
     }
@@ -645,7 +624,6 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
             walk_list!(visitor, visit_expr, default);
         }
         MethodTraitItem(ref sig, None) => {
-            visitor.visit_explicit_self(&sig.explicit_self);
             visitor.visit_generics(&sig.generics);
             walk_fn_decl(visitor, &sig.decl);
         }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 5ca99a7db67..d6a29b03764 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -388,21 +388,6 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_explicit_self_underscore(&mut self, es: &SelfKind) -> hir::ExplicitSelf_ {
-        match *es {
-            SelfKind::Static => hir::SelfStatic,
-            SelfKind::Value(v) => hir::SelfValue(v.name),
-            SelfKind::Region(ref lifetime, m, ident) => {
-                hir::SelfRegion(self.lower_opt_lifetime(lifetime),
-                                self.lower_mutability(m),
-                                ident.name)
-            }
-            SelfKind::Explicit(ref typ, ident) => {
-                hir::SelfExplicit(self.lower_ty(typ), ident.name)
-            }
-        }
-    }
-
     fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
         match m {
             Mutability::Mutable => hir::MutMutable,
@@ -410,13 +395,6 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_explicit_self(&mut self, s: &ExplicitSelf) -> hir::ExplicitSelf {
-        Spanned {
-            node: self.lower_explicit_self_underscore(&s.node),
-            span: s.span,
-        }
-    }
-
     fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
         hir::Arg {
             id: arg.id,
@@ -800,7 +778,6 @@ impl<'a> LoweringContext<'a> {
         hir::MethodSig {
             generics: self.lower_generics(&sig.generics),
             abi: sig.abi,
-            explicit_self: self.lower_explicit_self(&sig.explicit_self),
             unsafety: self.lower_unsafety(sig.unsafety),
             constness: self.lower_constness(sig.constness),
             decl: self.lower_fn_decl(&sig.decl),
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 97c43883819..eb38458a3ac 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -15,7 +15,6 @@ pub use self::BinOp_::*;
 pub use self::BlockCheckMode::*;
 pub use self::CaptureClause::*;
 pub use self::Decl_::*;
-pub use self::ExplicitSelf_::*;
 pub use self::Expr_::*;
 pub use self::FunctionRetTy::*;
 pub use self::ForeignItem_::*;
@@ -37,12 +36,12 @@ use hir::def::Def;
 use hir::def_id::DefId;
 use util::nodemap::{NodeMap, FnvHashSet};
 
-use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId};
+use syntax::codemap::{self, mk_sp, respan, Span, Spanned, ExpnId};
 use syntax::abi::Abi;
 use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
 use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
 use syntax::attr::{ThinAttributes, ThinAttributesExt};
-use syntax::parse::token::InternedString;
+use syntax::parse::token::{keywords, InternedString};
 use syntax::ptr::P;
 
 use std::collections::BTreeMap;
@@ -1055,7 +1054,6 @@ pub struct MethodSig {
     pub abi: Abi,
     pub decl: P<FnDecl>,
     pub generics: Generics,
-    pub explicit_self: ExplicitSelf,
 }
 
 /// Represents an item declaration within a trait declaration,
@@ -1196,25 +1194,41 @@ pub struct Arg {
     pub id: NodeId,
 }
 
+/// Alternative representation for `Arg`s describing `self` parameter of methods.
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum SelfKind {
+    /// `self`, `mut self`
+    Value(Mutability),
+    /// `&'lt self`, `&'lt mut self`
+    Region(Option<Lifetime>, Mutability),
+    /// `self: TYPE`, `mut self: TYPE`
+    Explicit(P<Ty>, Mutability),
+}
+
+pub type ExplicitSelf = Spanned<SelfKind>;
+
 impl Arg {
-    pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
-        let path = Spanned {
-            span: span,
-            node: self_ident,
-        };
-        Arg {
-            // HACK(eddyb) fake type for the self argument.
-            ty: P(Ty {
-                id: DUMMY_NODE_ID,
-                node: TyInfer,
-                span: DUMMY_SP,
-            }),
-            pat: P(Pat {
-                id: DUMMY_NODE_ID,
-                node: PatKind::Ident(BindByValue(mutability), path, None),
-                span: span,
-            }),
-            id: DUMMY_NODE_ID,
+    pub fn to_self(&self) -> Option<ExplicitSelf> {
+        if let PatKind::Ident(BindByValue(mutbl), ident, _) = self.pat.node {
+            if ident.node.unhygienic_name == keywords::SelfValue.name() {
+                return match self.ty.node {
+                    TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
+                    TyRptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyInfer => {
+                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
+                    }
+                    _ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
+                                     SelfKind::Explicit(self.ty.clone(), mutbl)))
+                }
+            }
+        }
+        None
+    }
+
+    pub fn is_self(&self) -> bool {
+        if let PatKind::Ident(_, ident, _) = self.pat.node {
+            ident.node.unhygienic_name == keywords::SelfValue.name()
+        } else {
+            false
         }
     }
 }
@@ -1227,6 +1241,12 @@ pub struct FnDecl {
     pub variadic: bool,
 }
 
+impl FnDecl {
+    pub fn has_self(&self) -> bool {
+        self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Unsafety {
     Unsafe,
@@ -1308,21 +1328,6 @@ impl FunctionRetTy {
     }
 }
 
-/// Represents the kind of 'self' associated with a method
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum ExplicitSelf_ {
-    /// No self
-    SelfStatic,
-    /// `self`
-    SelfValue(Name),
-    /// `&'lt self`, `&'lt mut self`
-    SelfRegion(Option<Lifetime>, Mutability, Name),
-    /// `self: TYPE`
-    SelfExplicit(P<Ty>, Name),
-}
-
-pub type ExplicitSelf = Spanned<ExplicitSelf_>;
-
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index db179c1cc1b..c3617cb768d 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -23,7 +23,7 @@ use syntax::print::pprust::{self as ast_pp, PrintState};
 use syntax::ptr::P;
 
 use hir;
-use hir::{Crate, PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
+use hir::{Crate, PatKind, RegionTyParamBound, SelfKind, TraitTyParamBound, TraitBoundModifier};
 
 use std::io::{self, Write, Read};
 
@@ -281,7 +281,6 @@ pub fn fun_to_string(decl: &hir::FnDecl,
                      unsafety: hir::Unsafety,
                      constness: hir::Constness,
                      name: ast::Name,
-                     opt_explicit_self: Option<&hir::ExplicitSelf_>,
                      generics: &hir::Generics)
                      -> String {
     to_string(|s| {
@@ -292,7 +291,6 @@ pub fn fun_to_string(decl: &hir::FnDecl,
                    Abi::Rust,
                    Some(name),
                    generics,
-                   opt_explicit_self,
                    &hir::Inherited)?;
         s.end()?; // Close the head box
         s.end() // Close the outer box
@@ -309,10 +307,6 @@ pub fn block_to_string(blk: &hir::Block) -> String {
     })
 }
 
-pub fn explicit_self_to_string(explicit_self: &hir::ExplicitSelf_) -> String {
-    to_string(|s| s.print_explicit_self(explicit_self, hir::MutImmutable).map(|_| {}))
-}
-
 pub fn variant_to_string(var: &hir::Variant) -> String {
     to_string(|s| s.print_variant(var))
 }
@@ -526,7 +520,7 @@ impl<'a> State<'a> {
                         predicates: hir::HirVec::new(),
                     },
                 };
-                self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics, None)?;
+                self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics)?;
             }
             hir::TyPath(None, ref path) => {
                 self.print_path(path, false, 0)?;
@@ -573,7 +567,6 @@ impl<'a> State<'a> {
                               Abi::Rust,
                               Some(item.name),
                               generics,
-                              None,
                               &item.vis)?;
                 self.end()?; // end head-ibox
                 word(&mut self.s, ";")?;
@@ -710,7 +703,6 @@ impl<'a> State<'a> {
                               abi,
                               Some(item.name),
                               typarams,
-                              None,
                               &item.vis)?;
                 word(&mut self.s, " ")?;
                 self.print_block_with_attrs(&body, &item.attrs)?;
@@ -976,7 +968,6 @@ impl<'a> State<'a> {
                       m.abi,
                       Some(name),
                       &m.generics,
-                      Some(&m.explicit_self.node),
                       vis)
     }
 
@@ -1881,32 +1872,25 @@ impl<'a> State<'a> {
         self.end() // close enclosing cbox
     }
 
-    // Returns whether it printed anything
-    fn print_explicit_self(&mut self,
-                           explicit_self: &hir::ExplicitSelf_,
-                           mutbl: hir::Mutability)
-                           -> io::Result<bool> {
-        self.print_mutability(mutbl)?;
-        match *explicit_self {
-            hir::SelfStatic => {
-                return Ok(false);
-            }
-            hir::SelfValue(_) => {
-                word(&mut self.s, "self")?;
+    fn print_explicit_self(&mut self, explicit_self: &hir::ExplicitSelf) -> io::Result<()> {
+        match explicit_self.node {
+            SelfKind::Value(m) => {
+                self.print_mutability(m)?;
+                word(&mut self.s, "self")
             }
-            hir::SelfRegion(ref lt, m, _) => {
+            SelfKind::Region(ref lt, m) => {
                 word(&mut self.s, "&")?;
                 self.print_opt_lifetime(lt)?;
                 self.print_mutability(m)?;
-                word(&mut self.s, "self")?;
+                word(&mut self.s, "self")
             }
-            hir::SelfExplicit(ref typ, _) => {
+            SelfKind::Explicit(ref typ, m) => {
+                self.print_mutability(m)?;
                 word(&mut self.s, "self")?;
                 self.word_space(":")?;
-                self.print_type(&typ)?;
+                self.print_type(&typ)
             }
         }
-        return Ok(true);
     }
 
     pub fn print_fn(&mut self,
@@ -1916,7 +1900,6 @@ impl<'a> State<'a> {
                     abi: Abi,
                     name: Option<ast::Name>,
                     generics: &hir::Generics,
-                    opt_explicit_self: Option<&hir::ExplicitSelf_>,
                     vis: &hir::Visibility)
                     -> io::Result<()> {
         self.print_fn_header_info(unsafety, constness, abi, vis)?;
@@ -1926,55 +1909,13 @@ impl<'a> State<'a> {
             self.print_name(name)?;
         }
         self.print_generics(generics)?;
-        self.print_fn_args_and_ret(decl, opt_explicit_self)?;
+        self.print_fn_args_and_ret(decl)?;
         self.print_where_clause(&generics.where_clause)
     }
 
-    pub fn print_fn_args(&mut self,
-                         decl: &hir::FnDecl,
-                         opt_explicit_self: Option<&hir::ExplicitSelf_>,
-                         is_closure: bool)
-                         -> io::Result<()> {
-        // It is unfortunate to duplicate the commasep logic, but we want the
-        // self type and the args all in the same box.
-        self.rbox(0, Inconsistent)?;
-        let mut first = true;
-        if let Some(explicit_self) = opt_explicit_self {
-            let m = match explicit_self {
-                &hir::SelfStatic => hir::MutImmutable,
-                _ => match decl.inputs[0].pat.node {
-                    PatKind::Ident(hir::BindByValue(m), _, _) => m,
-                    _ => hir::MutImmutable,
-                },
-            };
-            first = !self.print_explicit_self(explicit_self, m)?;
-        }
-
-        // HACK(eddyb) ignore the separately printed self argument.
-        let args = if first {
-            &decl.inputs[..]
-        } else {
-            &decl.inputs[1..]
-        };
-
-        for arg in args {
-            if first {
-                first = false;
-            } else {
-                self.word_space(",")?;
-            }
-            self.print_arg(arg, is_closure)?;
-        }
-
-        self.end()
-    }
-
-    pub fn print_fn_args_and_ret(&mut self,
-                                 decl: &hir::FnDecl,
-                                 opt_explicit_self: Option<&hir::ExplicitSelf_>)
-                                 -> io::Result<()> {
+    pub fn print_fn_args_and_ret(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
         self.popen()?;
-        self.print_fn_args(decl, opt_explicit_self, false)?;
+        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?;
         if decl.variadic {
             word(&mut self.s, ", ...")?;
         }
@@ -1985,7 +1926,7 @@ impl<'a> State<'a> {
 
     pub fn print_fn_block_args(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
         word(&mut self.s, "|")?;
-        self.print_fn_args(decl, None, true)?;
+        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))?;
         word(&mut self.s, "|")?;
 
         if let hir::DefaultReturn(..) = decl.output {
@@ -2207,18 +2148,21 @@ impl<'a> State<'a> {
         match input.ty.node {
             hir::TyInfer if is_closure => self.print_pat(&input.pat)?,
             _ => {
-                match input.pat.node {
-                    PatKind::Ident(_, ref path1, _)
-                            if path1.node.name == keywords::Invalid.name() => {
-                        // Do nothing.
-                    }
-                    _ => {
+                if let Some(eself) = input.to_self() {
+                    self.print_explicit_self(&eself)?;
+                } else {
+                    let invalid = if let PatKind::Ident(_, ident, _) = input.pat.node {
+                        ident.node.name == keywords::Invalid.name()
+                    } else {
+                        false
+                    };
+                    if !invalid {
                         self.print_pat(&input.pat)?;
                         word(&mut self.s, ":")?;
                         space(&mut self.s)?;
                     }
+                    self.print_type(&input.ty)?;
                 }
-                self.print_type(&input.ty)?;
             }
         }
         self.end()
@@ -2250,8 +2194,7 @@ impl<'a> State<'a> {
                        unsafety: hir::Unsafety,
                        decl: &hir::FnDecl,
                        name: Option<ast::Name>,
-                       generics: &hir::Generics,
-                       opt_explicit_self: Option<&hir::ExplicitSelf_>)
+                       generics: &hir::Generics)
                        -> io::Result<()> {
         self.ibox(indent_unit)?;
         if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
@@ -2272,7 +2215,6 @@ impl<'a> State<'a> {
                       abi,
                       name,
                       &generics,
-                      opt_explicit_self,
                       &hir::Inherited)?;
         self.end()
     }
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs
index 3900fab2d93..cabc004a65d 100644
--- a/src/librustc/infer/error_reporting.rs
+++ b/src/librustc/infer/error_reporting.rs
@@ -976,8 +976,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 ast_map::NodeItem(ref item) => {
                     match item.node {
                         hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
-                            Some((fn_decl, gen, unsafety, constness,
-                                  item.name, None, item.span))
+                            Some((fn_decl, gen, unsafety, constness, item.name, item.span))
                         },
                         _ => None
                     }
@@ -990,7 +989,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                   sig.unsafety,
                                   sig.constness,
                                   item.name,
-                                  Some(&sig.explicit_self.node),
                                   item.span))
                         }
                         _ => None,
@@ -1004,7 +1002,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                   sig.unsafety,
                                   sig.constness,
                                   item.name,
-                                  Some(&sig.explicit_self.node),
                                   item.span))
                         }
                         _ => None
@@ -1014,13 +1011,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             },
             None => None
         };
-        let (fn_decl, generics, unsafety, constness, name, expl_self, span)
+        let (fn_decl, generics, unsafety, constness, name, span)
                                     = node_inner.expect("expect item fn");
-        let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
-                                       generics, same_regions, &life_giver);
-        let (fn_decl, expl_self, generics) = rebuilder.rebuild();
-        self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name,
-                                      expl_self.as_ref(), &generics, span);
+        let rebuilder = Rebuilder::new(self.tcx, fn_decl, generics, same_regions, &life_giver);
+        let (fn_decl, generics) = rebuilder.rebuild();
+        self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name, &generics, span);
     }
 }
 
@@ -1038,7 +1033,6 @@ struct RebuildPathInfo<'a> {
 struct Rebuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     fn_decl: &'a hir::FnDecl,
-    expl_self_opt: Option<&'a hir::ExplicitSelf_>,
     generics: &'a hir::Generics,
     same_regions: &'a [SameRegions],
     life_giver: &'a LifeGiver,
@@ -1054,7 +1048,6 @@ enum FreshOrKept {
 impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
     fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
            fn_decl: &'a hir::FnDecl,
-           expl_self_opt: Option<&'a hir::ExplicitSelf_>,
            generics: &'a hir::Generics,
            same_regions: &'a [SameRegions],
            life_giver: &'a LifeGiver)
@@ -1062,7 +1055,6 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
         Rebuilder {
             tcx: tcx,
             fn_decl: fn_decl,
-            expl_self_opt: expl_self_opt,
             generics: generics,
             same_regions: same_regions,
             life_giver: life_giver,
@@ -1071,9 +1063,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
         }
     }
 
-    fn rebuild(&self)
-               -> (hir::FnDecl, Option<hir::ExplicitSelf_>, hir::Generics) {
-        let mut expl_self_opt = self.expl_self_opt.cloned();
+    fn rebuild(&self) -> (hir::FnDecl, hir::Generics) {
         let mut inputs = self.fn_decl.inputs.clone();
         let mut output = self.fn_decl.output.clone();
         let mut ty_params = self.generics.ty_params.clone();
@@ -1089,8 +1079,6 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
                 Kept => { kept_lifetimes.insert(lifetime.name); }
                 _ => ()
             }
-            expl_self_opt = self.rebuild_expl_self(expl_self_opt, lifetime,
-                                                   &anon_nums, &region_names);
             inputs = self.rebuild_args_ty(&inputs[..], lifetime,
                                           &anon_nums, &region_names);
             output = self.rebuild_output(&output, lifetime, &anon_nums, &region_names);
@@ -1110,7 +1098,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
             output: output,
             variadic: self.fn_decl.variadic
         };
-        (new_fn_decl, expl_self_opt, generics)
+        (new_fn_decl, generics)
     }
 
     fn pick_lifetime(&self,
@@ -1250,34 +1238,6 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
         }).collect()
     }
 
-    fn rebuild_expl_self(&self,
-                         expl_self_opt: Option<hir::ExplicitSelf_>,
-                         lifetime: hir::Lifetime,
-                         anon_nums: &HashSet<u32>,
-                         region_names: &HashSet<ast::Name>)
-                         -> Option<hir::ExplicitSelf_> {
-        match expl_self_opt {
-            Some(ref expl_self) => match *expl_self {
-                hir::SelfRegion(lt_opt, muta, id) => match lt_opt {
-                    Some(lt) => if region_names.contains(&lt.name) {
-                        return Some(hir::SelfRegion(Some(lifetime), muta, id));
-                    },
-                    None => {
-                        let anon = self.cur_anon.get();
-                        self.inc_and_offset_cur_anon(1);
-                        if anon_nums.contains(&anon) {
-                            self.track_anon(anon);
-                            return Some(hir::SelfRegion(Some(lifetime), muta, id));
-                        }
-                    }
-                },
-                _ => ()
-            },
-            None => ()
-        }
-        expl_self_opt
-    }
-
     fn rebuild_generics(&self,
                         generics: &hir::Generics,
                         add: &Vec<hir::Lifetime>,
@@ -1575,11 +1535,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                 unsafety: hir::Unsafety,
                                 constness: hir::Constness,
                                 name: ast::Name,
-                                opt_explicit_self: Option<&hir::ExplicitSelf_>,
                                 generics: &hir::Generics,
                                 span: Span) {
-        let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, name,
-                                                 opt_explicit_self, generics);
+        let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, name, generics);
         let msg = format!("consider using an explicit lifetime \
                            parameter as shown: {}", suggested_fn);
         err.span_help(span, &msg[..]);
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index a4b9b5f4556..0801f8f4ac7 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -889,11 +889,6 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
         run_lints!(self, check_lifetime_def, late_passes, lt);
     }
 
-    fn visit_explicit_self(&mut self, es: &hir::ExplicitSelf) {
-        run_lints!(self, check_explicit_self, late_passes, es);
-        hir_visit::walk_explicit_self(self, es);
-    }
-
     fn visit_path(&mut self, p: &hir::Path, id: ast::NodeId) {
         run_lints!(self, check_path, late_passes, p, id);
         hir_visit::walk_path(self, p);
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 5c062316310..932f2882b49 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -483,7 +483,6 @@ impl<'a> LifetimeContext<'a> {
             FnKind::Method(_, sig, _, _) => {
                 intravisit::walk_fn_decl(self, fd);
                 self.visit_generics(&sig.generics);
-                self.visit_explicit_self(&sig.explicit_self);
             }
             FnKind::Closure(_) => {
                 intravisit::walk_fn_decl(self, fd);
diff --git a/src/librustc_incremental/calculate_svh.rs b/src/librustc_incremental/calculate_svh.rs
index ef3ac4c3426..e914c38963c 100644
--- a/src/librustc_incremental/calculate_svh.rs
+++ b/src/librustc_incremental/calculate_svh.rs
@@ -172,7 +172,6 @@ mod svh_visitor {
         SawImplItem,
         SawStructField,
         SawVariant,
-        SawExplicitSelf,
         SawPath,
         SawBlock,
         SawPat,
@@ -391,10 +390,6 @@ mod svh_visitor {
             SawStructField.hash(self.st); visit::walk_struct_field(self, s)
         }
 
-        fn visit_explicit_self(&mut self, es: &'a ExplicitSelf) {
-            SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es)
-        }
-
         fn visit_path(&mut self, path: &'a Path, _: ast::NodeId) {
             SawPath.hash(self.st); visit::walk_path(self, path)
         }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 0b2763baf4f..f1e744098b9 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -831,8 +831,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx>
                                 }
                             }
                             hir::ImplItemKind::Method(ref sig, _) => {
-                                if sig.explicit_self.node == hir::SelfStatic &&
-                                      self.item_is_public(&impl_item.id, &impl_item.vis) {
+                                if !sig.decl.has_self() &&
+                                        self.item_is_public(&impl_item.id, &impl_item.vis) {
                                     found_pub_static = true;
                                     intravisit::walk_impl_item(self, impl_item);
                                 }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 9cec3a51794..60c8724b8db 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -582,7 +582,6 @@ impl<'a, 'v> Visitor<'v> for Resolver<'a> {
             }
             FnKind::Method(_, sig, _) => {
                 self.visit_generics(&sig.generics);
-                self.visit_explicit_self(&sig.explicit_self);
                 MethodRibKind
             }
             FnKind::Closure => ClosureRibKind(node_id),
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c8e247fb918..4faefb61056 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -75,7 +75,7 @@ use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::parse::token::{self, keywords};
 
 use rustc::hir::print as pprust;
-use rustc::hir;
+use rustc::hir::{self, SelfKind};
 use rustc_back::slice;
 
 pub trait AstConv<'gcx, 'tcx> {
@@ -166,11 +166,6 @@ struct ConvertedBinding<'tcx> {
     span: Span,
 }
 
-struct SelfInfo<'a, 'tcx> {
-    untransformed_self_ty: Ty<'tcx>,
-    explicit_self: &'a hir::ExplicitSelf,
-}
-
 type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec<ty::PolyProjectionPredicate<'tcx>>);
 
 pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime)
@@ -1719,33 +1714,28 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                         sig: &hir::MethodSig,
                         untransformed_self_ty: Ty<'tcx>)
                         -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) {
-        let self_info = Some(SelfInfo {
-            untransformed_self_ty: untransformed_self_ty,
-            explicit_self: &sig.explicit_self,
-        });
         let (bare_fn_ty, optional_explicit_self_category) =
             self.ty_of_method_or_bare_fn(sig.unsafety,
                                          sig.abi,
-                                         self_info,
+                                         Some(untransformed_self_ty),
                                          &sig.decl);
-        (bare_fn_ty, optional_explicit_self_category.unwrap())
+        (bare_fn_ty, optional_explicit_self_category)
     }
 
     pub fn ty_of_bare_fn(&self,
-                         unsafety: hir::Unsafety, abi: abi::Abi,
+                         unsafety: hir::Unsafety,
+                         abi: abi::Abi,
                          decl: &hir::FnDecl)
                          -> &'tcx ty::BareFnTy<'tcx> {
-        let (bare_fn_ty, _) = self.ty_of_method_or_bare_fn(unsafety, abi, None, decl);
-        bare_fn_ty
+        self.ty_of_method_or_bare_fn(unsafety, abi, None, decl).0
     }
 
     fn ty_of_method_or_bare_fn<'a>(&self,
                                    unsafety: hir::Unsafety,
                                    abi: abi::Abi,
-                                   opt_self_info: Option<SelfInfo<'a, 'tcx>>,
+                                   opt_untransformed_self_ty: Option<Ty<'tcx>>,
                                    decl: &hir::FnDecl)
-                                   -> (&'tcx ty::BareFnTy<'tcx>,
-                                       Option<ty::ExplicitSelfCategory>)
+                                   -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory)
     {
         debug!("ty_of_method_or_bare_fn");
 
@@ -1758,9 +1748,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         // lifetime elision, we can determine it in two ways. First (determined
         // here), if self is by-reference, then the implied output region is the
         // region of the self parameter.
-        let (self_ty, explicit_self_category) = match opt_self_info {
-            None => (None, None),
-            Some(self_info) => self.determine_self_type(&rb, self_info)
+        let explicit_self = decl.inputs.get(0).and_then(hir::Arg::to_self);
+        let (self_ty, explicit_self_category) = match (opt_untransformed_self_ty, explicit_self) {
+            (Some(untransformed_self_ty), Some(explicit_self)) => {
+                let self_type = self.determine_self_type(&rb, untransformed_self_ty,
+                                                         &explicit_self);
+                (Some(self_type.0), self_type.1)
+            }
+            _ => (None, ty::ExplicitSelfCategory::Static),
         };
 
         // HACK(eddyb) replace the fake self type in the AST with the actual type.
@@ -1778,7 +1773,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         // reference) in the arguments, then any anonymous regions in the output
         // have that lifetime.
         let implied_output_region = match explicit_self_category {
-            Some(ty::ExplicitSelfCategory::ByReference(region, _)) => Ok(region),
+            ty::ExplicitSelfCategory::ByReference(region, _) => Ok(region),
             _ => self.find_implied_output_region(&arg_tys, arg_pats)
         };
 
@@ -1803,29 +1798,29 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
 
     fn determine_self_type<'a>(&self,
                                rscope: &RegionScope,
-                               self_info: SelfInfo<'a, 'tcx>)
-                               -> (Option<Ty<'tcx>>, Option<ty::ExplicitSelfCategory>)
+                               untransformed_self_ty: Ty<'tcx>,
+                               explicit_self: &hir::ExplicitSelf)
+                               -> (Ty<'tcx>, ty::ExplicitSelfCategory)
     {
-        let self_ty = self_info.untransformed_self_ty;
-        return match self_info.explicit_self.node {
-            hir::SelfStatic => (None, Some(ty::ExplicitSelfCategory::Static)),
-            hir::SelfValue(_) => {
-                (Some(self_ty), Some(ty::ExplicitSelfCategory::ByValue))
+        return match explicit_self.node {
+            SelfKind::Value(..) => {
+                (untransformed_self_ty, ty::ExplicitSelfCategory::ByValue)
             }
-            hir::SelfRegion(ref lifetime, mutability, _) => {
+            SelfKind::Region(ref lifetime, mutability) => {
                 let region =
-                    self.opt_ast_region_to_region(rscope,
-                                                  self_info.explicit_self.span,
-                                                  lifetime);
-                (Some(self.tcx().mk_ref(
+                    self.opt_ast_region_to_region(
+                                             rscope,
+                                             explicit_self.span,
+                                             lifetime);
+                (self.tcx().mk_ref(
                     self.tcx().mk_region(region),
                     ty::TypeAndMut {
-                        ty: self_ty,
+                        ty: untransformed_self_ty,
                         mutbl: mutability
-                    })),
-                 Some(ty::ExplicitSelfCategory::ByReference(region, mutability)))
+                    }),
+                 ty::ExplicitSelfCategory::ByReference(region, mutability))
             }
-            hir::SelfExplicit(ref ast_type, _) => {
+            SelfKind::Explicit(ref ast_type, _) => {
                 let explicit_type = self.ast_ty_to_ty(rscope, &ast_type);
 
                 // We wish to (for now) categorize an explicit self
@@ -1857,13 +1852,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                 // type has two, so we end up with
                 // ExplicitSelfCategory::ByReference.
 
-                let impl_modifiers = count_modifiers(self_info.untransformed_self_ty);
+                let impl_modifiers = count_modifiers(untransformed_self_ty);
                 let method_modifiers = count_modifiers(explicit_type);
 
                 debug!("determine_explicit_self_category(self_info.untransformed_self_ty={:?} \
                        explicit_type={:?} \
                        modifiers=({},{})",
-                       self_info.untransformed_self_ty,
+                       untransformed_self_ty,
                        explicit_type,
                        impl_modifiers,
                        method_modifiers);
@@ -1878,7 +1873,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                     }
                 };
 
-                (Some(explicit_type), Some(category))
+                (explicit_type, category)
             }
         };
 
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index c9df54dfef2..f5d54123f37 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -361,7 +361,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
                 let mut item = method.clean(cx);
                 item.inner = match item.inner.clone() {
                     clean::TyMethodItem(clean::TyMethod {
-                        unsafety, decl, self_, generics, abi
+                        unsafety, decl, generics, abi
                     }) => {
                         let constness = if tcx.sess.cstore.is_const_fn(did) {
                             hir::Constness::Const
@@ -373,7 +373,6 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
                             unsafety: unsafety,
                             constness: constness,
                             decl: decl,
-                            self_: self_,
                             generics: generics,
                             abi: abi
                         })
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index a89609fad6b..7c7a2cfc21c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1025,7 +1025,6 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Method {
     pub generics: Generics,
-    pub self_: SelfTy,
     pub unsafety: hir::Unsafety,
     pub constness: hir::Constness,
     pub decl: FnDecl,
@@ -1034,14 +1033,9 @@ pub struct Method {
 
 impl Clean<Method> for hir::MethodSig {
     fn clean(&self, cx: &DocContext) -> Method {
-        let all_inputs = &self.decl.inputs;
-        let inputs = match self.explicit_self.node {
-            hir::SelfStatic => &**all_inputs,
-            _ => &all_inputs[1..]
-        };
         let decl = FnDecl {
             inputs: Arguments {
-                values: inputs.clean(cx),
+                values: self.decl.inputs.clean(cx),
             },
             output: self.decl.output.clean(cx),
             variadic: false,
@@ -1049,7 +1043,6 @@ impl Clean<Method> for hir::MethodSig {
         };
         Method {
             generics: self.generics.clean(cx),
-            self_: self.explicit_self.node.clean(cx),
             unsafety: self.unsafety,
             constness: self.constness,
             decl: decl,
@@ -1063,19 +1056,14 @@ pub struct TyMethod {
     pub unsafety: hir::Unsafety,
     pub decl: FnDecl,
     pub generics: Generics,
-    pub self_: SelfTy,
     pub abi: Abi,
 }
 
 impl Clean<TyMethod> for hir::MethodSig {
     fn clean(&self, cx: &DocContext) -> TyMethod {
-        let inputs = match self.explicit_self.node {
-            hir::SelfStatic => &*self.decl.inputs,
-            _ => &self.decl.inputs[1..]
-        };
         let decl = FnDecl {
             inputs: Arguments {
-                values: inputs.clean(cx),
+                values: self.decl.inputs.clean(cx),
             },
             output: self.decl.output.clean(cx),
             variadic: false,
@@ -1084,34 +1072,12 @@ impl Clean<TyMethod> for hir::MethodSig {
         TyMethod {
             unsafety: self.unsafety.clone(),
             decl: decl,
-            self_: self.explicit_self.node.clean(cx),
             generics: self.generics.clean(cx),
             abi: self.abi
         }
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
-pub enum SelfTy {
-    SelfStatic,
-    SelfValue,
-    SelfBorrowed(Option<Lifetime>, Mutability),
-    SelfExplicit(Type),
-}
-
-impl Clean<SelfTy> for hir::ExplicitSelf_ {
-    fn clean(&self, cx: &DocContext) -> SelfTy {
-        match *self {
-            hir::SelfStatic => SelfStatic,
-            hir::SelfValue(_) => SelfValue,
-            hir::SelfRegion(ref lt, ref mt, _) => {
-                SelfBorrowed(lt.clean(cx), mt.clean(cx))
-            }
-            hir::SelfExplicit(ref typ, _) => SelfExplicit(typ.clean(cx)),
-        }
-    }
-}
-
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Function {
     pub decl: FnDecl,
@@ -1150,6 +1116,12 @@ pub struct FnDecl {
     pub attrs: Vec<Attribute>,
 }
 
+impl FnDecl {
+    pub fn has_self(&self) -> bool {
+        return self.inputs.values.len() > 0 && self.inputs.values[0].name == "self";
+    }
+}
+
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
 pub struct Arguments {
     pub values: Vec<Argument>,
@@ -1185,9 +1157,6 @@ impl<'a, 'tcx> Clean<FnDecl> for (DefId, &'a ty::PolyFnSig<'tcx>) {
         } else {
             cx.tcx().sess.cstore.method_arg_names(did).into_iter()
         }.peekable();
-        if let Some("self") = names.peek().map(|s| &s[..]) {
-            let _ = names.next();
-        }
         FnDecl {
             output: Return(sig.0.output.clean(cx)),
             attrs: Vec::new(),
@@ -1212,6 +1181,29 @@ pub struct Argument {
     pub id: ast::NodeId,
 }
 
+#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
+pub enum SelfTy {
+    SelfValue,
+    SelfBorrowed(Option<Lifetime>, Mutability),
+    SelfExplicit(Type),
+}
+
+impl Argument {
+    pub fn to_self(&self) -> Option<SelfTy> {
+        if self.name == "self" {
+            match self.type_ {
+                Infer => Some(SelfValue),
+                BorrowedRef{ref lifetime, mutability, ref type_} if **type_ == Infer => {
+                    Some(SelfBorrowed(lifetime.clone(), mutability))
+                }
+                _ => Some(SelfExplicit(self.type_.clone()))
+            }
+        } else {
+            None
+        }
+    }
+}
+
 impl Clean<Argument> for hir::Arg {
     fn clean(&self, cx: &DocContext) -> Argument {
         Argument {
@@ -1346,36 +1338,21 @@ impl Clean<Item> for hir::ImplItem {
 
 impl<'tcx> Clean<Item> for ty::Method<'tcx> {
     fn clean(&self, cx: &DocContext) -> Item {
-        let (self_, sig) = match self.explicit_self {
-            ty::ExplicitSelfCategory::Static => (hir::SelfStatic.clean(cx),
-                                                 self.fty.sig.clone()),
-            s => {
-                let sig = ty::Binder(ty::FnSig {
-                    inputs: self.fty.sig.0.inputs[1..].to_vec(),
-                    ..self.fty.sig.0.clone()
-                });
-                let s = match s {
-                    ty::ExplicitSelfCategory::ByValue => SelfValue,
-                    ty::ExplicitSelfCategory::ByReference(..) => {
-                        match self.fty.sig.0.inputs[0].sty {
-                            ty::TyRef(r, mt) => {
-                                SelfBorrowed(r.clean(cx), mt.mutbl.clean(cx))
-                            }
-                            _ => unreachable!(),
-                        }
-                    }
-                    ty::ExplicitSelfCategory::ByBox => {
-                        SelfExplicit(self.fty.sig.0.inputs[0].clean(cx))
-                    }
-                    ty::ExplicitSelfCategory::Static => unreachable!(),
-                };
-                (s, sig)
-            }
-        };
-
         let generics = (&self.generics, &self.predicates,
                         subst::FnSpace).clean(cx);
-        let decl = (self.def_id, &sig).clean(cx);
+        let mut decl = (self.def_id, &self.fty.sig).clean(cx);
+        match self.explicit_self {
+            ty::ExplicitSelfCategory::ByValue => {
+                decl.inputs.values[0].type_ = Infer;
+            }
+            ty::ExplicitSelfCategory::ByReference(..) => {
+                match decl.inputs.values[0].type_ {
+                    BorrowedRef{ref mut type_, ..} => **type_ = Infer,
+                    _ => unreachable!(),
+                }
+            }
+            _ => {}
+        }
         let provided = match self.container {
             ty::ImplContainer(..) => false,
             ty::TraitContainer(did) => {
@@ -1388,7 +1365,6 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
             MethodItem(Method {
                 unsafety: self.fty.unsafety,
                 generics: generics,
-                self_: self_,
                 decl: decl,
                 abi: self.fty.abi,
 
@@ -1399,7 +1375,6 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
             TyMethodItem(TyMethod {
                 unsafety: self.fty.unsafety,
                 generics: generics,
-                self_: self_,
                 decl: decl,
                 abi: self.fty.abi,
             })
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 7af5322e7bd..95bf66ed30d 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -43,7 +43,7 @@ pub struct UnsafetySpace(pub hir::Unsafety);
 #[derive(Copy, Clone)]
 pub struct ConstnessSpace(pub hir::Constness);
 /// Wrapper struct for properly emitting a method declaration.
-pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
+pub struct Method<'a>(pub &'a clean::FnDecl);
 /// Similar to VisSpace, but used for mutability
 #[derive(Copy, Clone)]
 pub struct MutableSpace(pub clean::Mutability);
@@ -642,29 +642,31 @@ impl fmt::Display for clean::FnDecl {
 
 impl<'a> fmt::Display for Method<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let Method(selfty, d) = *self;
+        let decl = self.0;
         let mut args = String::new();
-        match *selfty {
-            clean::SelfStatic => {},
-            clean::SelfValue => args.push_str("self"),
-            clean::SelfBorrowed(Some(ref lt), mtbl) => {
-                args.push_str(&format!("&amp;{} {}self", *lt, MutableSpace(mtbl)));
-            }
-            clean::SelfBorrowed(None, mtbl) => {
-                args.push_str(&format!("&amp;{}self", MutableSpace(mtbl)));
-            }
-            clean::SelfExplicit(ref typ) => {
-                args.push_str(&format!("self: {}", *typ));
-            }
-        }
-        for (i, input) in d.inputs.values.iter().enumerate() {
+        for (i, input) in decl.inputs.values.iter().enumerate() {
             if i > 0 || !args.is_empty() { args.push_str(", "); }
-            if !input.name.is_empty() {
-                args.push_str(&format!("{}: ", input.name));
+            if let Some(selfty) = input.to_self() {
+                match selfty {
+                    clean::SelfValue => args.push_str("self"),
+                    clean::SelfBorrowed(Some(ref lt), mtbl) => {
+                        args.push_str(&format!("&amp;{} {}self", *lt, MutableSpace(mtbl)));
+                    }
+                    clean::SelfBorrowed(None, mtbl) => {
+                        args.push_str(&format!("&amp;{}self", MutableSpace(mtbl)));
+                    }
+                    clean::SelfExplicit(ref typ) => {
+                        args.push_str(&format!("self: {}", *typ));
+                    }
+                }
+            } else {
+                if !input.name.is_empty() {
+                    args.push_str(&format!("{}: ", input.name));
+                }
+                args.push_str(&format!("{}", input.type_));
             }
-            args.push_str(&format!("{}", input.type_));
         }
-        write!(f, "({args}){arrow}", args = args, arrow = d.output)
+        write!(f, "({args}){arrow}", args = args, arrow = decl.output)
     }
 }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index da0520ebcb8..005e25b07d4 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -62,7 +62,7 @@ use rustc::middle::stability;
 use rustc::session::config::get_unstable_features_setting;
 use rustc::hir;
 
-use clean::{self, SelfTy, Attributes, GetDefId};
+use clean::{self, Attributes, GetDefId};
 use doctree;
 use fold::DocFolder;
 use html::escape::Escape;
@@ -592,8 +592,6 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
     for &(did, ref item) in orphan_methods {
         match paths.get(&did) {
             Some(&(ref fqp, _)) => {
-                // Needed to determine `self` type.
-                let parent_basename = Some(fqp[fqp.len() - 1].clone());
                 search_index.push(IndexItem {
                     ty: shortty(item),
                     name: item.name.clone().unwrap(),
@@ -601,7 +599,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
                     desc: Escape(&shorter(item.doc_value())).to_string(),
                     parent: Some(did),
                     parent_idx: None,
-                    search_type: get_index_search_type(&item, parent_basename),
+                    search_type: get_index_search_type(&item),
                 });
             },
             None => {}
@@ -1081,13 +1079,6 @@ impl DocFolder for Cache {
 
             match parent {
                 (parent, Some(path)) if is_method || (!self.stripped_mod) => {
-                    // Needed to determine `self` type.
-                    let parent_basename = self.parent_stack.first().and_then(|parent| {
-                        match self.paths.get(parent) {
-                            Some(&(ref fqp, _)) => Some(fqp[fqp.len() - 1].clone()),
-                            _ => None
-                        }
-                    });
                     debug_assert!(!item.is_stripped());
 
                     // A crate has a module at its root, containing all items,
@@ -1101,7 +1092,7 @@ impl DocFolder for Cache {
                             desc: Escape(&shorter(item.doc_value())).to_string(),
                             parent: parent,
                             parent_idx: None,
-                            search_type: get_index_search_type(&item, parent_basename),
+                            search_type: get_index_search_type(&item),
                         });
                     }
                 }
@@ -2167,7 +2158,6 @@ fn render_assoc_item(w: &mut fmt::Formatter,
               constness: hir::Constness,
               abi: abi::Abi,
               g: &clean::Generics,
-              selfty: &clean::SelfTy,
               d: &clean::FnDecl,
               link: AssocItemLink)
               -> fmt::Result {
@@ -2201,18 +2191,18 @@ fn render_assoc_item(w: &mut fmt::Formatter,
                href = href,
                name = name,
                generics = *g,
-               decl = Method(selfty, d),
+               decl = Method(d),
                where_clause = WhereClause(g))
     }
     match item.inner {
         clean::StrippedItem(..) => Ok(()),
         clean::TyMethodItem(ref m) => {
             method(w, item, m.unsafety, hir::Constness::NotConst,
-                   m.abi, &m.generics, &m.self_, &m.decl, link)
+                   m.abi, &m.generics, &m.decl, link)
         }
         clean::MethodItem(ref m) => {
             method(w, item, m.unsafety, m.constness,
-                   m.abi, &m.generics, &m.self_, &m.decl,
+                   m.abi, &m.generics, &m.decl,
                    link)
         }
         clean::AssociatedConstItem(ref ty, ref default) => {
@@ -2570,8 +2560,8 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
         let name = item.name.as_ref().unwrap();
 
         let is_static = match item.inner {
-            clean::MethodItem(ref method) => method.self_ == SelfTy::SelfStatic,
-            clean::TyMethodItem(ref method) => method.self_ == SelfTy::SelfStatic,
+            clean::MethodItem(ref method) => !method.decl.has_self(),
+            clean::TyMethodItem(ref method) => !method.decl.has_self(),
             _ => false
         };
 
@@ -2760,27 +2750,15 @@ fn make_item_keywords(it: &clean::Item) -> String {
     format!("{}, {}", BASIC_KEYWORDS, it.name.as_ref().unwrap())
 }
 
-fn get_index_search_type(item: &clean::Item,
-                         parent: Option<String>) -> Option<IndexItemFunctionType> {
-    let (decl, selfty) = match item.inner {
-        clean::FunctionItem(ref f) => (&f.decl, None),
-        clean::MethodItem(ref m) => (&m.decl, Some(&m.self_)),
-        clean::TyMethodItem(ref m) => (&m.decl, Some(&m.self_)),
+fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
+    let decl = match item.inner {
+        clean::FunctionItem(ref f) => &f.decl,
+        clean::MethodItem(ref m) => &m.decl,
+        clean::TyMethodItem(ref m) => &m.decl,
         _ => return None
     };
 
-    let mut inputs = Vec::new();
-
-    // Consider `self` an argument as well.
-    match parent.and_then(|p| selfty.map(|s| (p, s)) ) {
-        Some((_, &clean::SelfStatic)) | None => (),
-        Some((name, _)) => inputs.push(Type { name: Some(name.to_ascii_lowercase()) }),
-    }
-
-    inputs.extend(&mut decl.inputs.values.iter().map(|arg| {
-        get_index_type(&arg.type_)
-    }));
-
+    let inputs = decl.inputs.values.iter().map(|arg| get_index_type(&arg.type_)).collect();
     let output = match decl.output {
         clean::FunctionRetTy::Return(ref return_type) => Some(get_index_type(return_type)),
         _ => None