提交 766f9b5a 编写于 作者: V Vadim Petrochenkov

Remove ExplicitSelf from HIR

上级 212d5d43
...@@ -158,14 +158,6 @@ fn fold_local(&mut self, l: P<Local>) -> P<Local> { ...@@ -158,14 +158,6 @@ fn fold_local(&mut self, l: P<Local>) -> P<Local> {
noop_fold_local(l, self) 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 { fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime {
noop_fold_lifetime(l, self) noop_fold_lifetime(l, self)
} }
...@@ -495,29 +487,6 @@ pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attr ...@@ -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> { pub fn noop_fold_meta_item<T: Folder>(mi: P<MetaItem>, fld: &mut T) -> P<MetaItem> {
mi.map(|Spanned { node, span }| { mi.map(|Spanned { node, span }| {
Spanned { Spanned {
...@@ -941,7 +910,6 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method ...@@ -941,7 +910,6 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method
MethodSig { MethodSig {
generics: folder.fold_generics(sig.generics), generics: folder.fold_generics(sig.generics),
abi: sig.abi, abi: sig.abi,
explicit_self: folder.fold_explicit_self(sig.explicit_self),
unsafety: sig.unsafety, unsafety: sig.unsafety,
constness: sig.constness, constness: sig.constness,
decl: folder.fold_fn_decl(sig.decl), decl: folder.fold_fn_decl(sig.decl),
......
...@@ -180,9 +180,6 @@ fn visit_lifetime(&mut self, lifetime: &'v Lifetime) { ...@@ -180,9 +180,6 @@ fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) { fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
walk_lifetime_def(self, lifetime) 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) { fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
walk_path(self, path) walk_path(self, path)
} }
...@@ -258,23 +255,6 @@ pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v ...@@ -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); 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, pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
trait_ref: &'v PolyTraitRef, trait_ref: &'v PolyTraitRef,
_modifier: &'v TraitBoundModifier) _modifier: &'v TraitBoundModifier)
...@@ -620,7 +600,6 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<' ...@@ -620,7 +600,6 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
} }
FnKind::Method(_, sig, _, _) => { FnKind::Method(_, sig, _, _) => {
visitor.visit_generics(&sig.generics); visitor.visit_generics(&sig.generics);
visitor.visit_explicit_self(&sig.explicit_self);
} }
FnKind::Closure(_) => {} FnKind::Closure(_) => {}
} }
...@@ -645,7 +624,6 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai ...@@ -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); walk_list!(visitor, visit_expr, default);
} }
MethodTraitItem(ref sig, None) => { MethodTraitItem(ref sig, None) => {
visitor.visit_explicit_self(&sig.explicit_self);
visitor.visit_generics(&sig.generics); visitor.visit_generics(&sig.generics);
walk_fn_decl(visitor, &sig.decl); walk_fn_decl(visitor, &sig.decl);
} }
......
...@@ -388,21 +388,6 @@ fn lower_local(&mut self, l: &Local) -> P<hir::Local> { ...@@ -388,21 +388,6 @@ fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
}) })
} }
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 { fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
match m { match m {
Mutability::Mutable => hir::MutMutable, Mutability::Mutable => hir::MutMutable,
...@@ -410,13 +395,6 @@ fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability { ...@@ -410,13 +395,6 @@ fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
} }
} }
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 { fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
hir::Arg { hir::Arg {
id: arg.id, id: arg.id,
...@@ -800,7 +778,6 @@ fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig { ...@@ -800,7 +778,6 @@ fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
hir::MethodSig { hir::MethodSig {
generics: self.lower_generics(&sig.generics), generics: self.lower_generics(&sig.generics),
abi: sig.abi, abi: sig.abi,
explicit_self: self.lower_explicit_self(&sig.explicit_self),
unsafety: self.lower_unsafety(sig.unsafety), unsafety: self.lower_unsafety(sig.unsafety),
constness: self.lower_constness(sig.constness), constness: self.lower_constness(sig.constness),
decl: self.lower_fn_decl(&sig.decl), decl: self.lower_fn_decl(&sig.decl),
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
pub use self::BlockCheckMode::*; pub use self::BlockCheckMode::*;
pub use self::CaptureClause::*; pub use self::CaptureClause::*;
pub use self::Decl_::*; pub use self::Decl_::*;
pub use self::ExplicitSelf_::*;
pub use self::Expr_::*; pub use self::Expr_::*;
pub use self::FunctionRetTy::*; pub use self::FunctionRetTy::*;
pub use self::ForeignItem_::*; pub use self::ForeignItem_::*;
...@@ -37,12 +36,12 @@ ...@@ -37,12 +36,12 @@
use hir::def_id::DefId; use hir::def_id::DefId;
use util::nodemap::{NodeMap, FnvHashSet}; 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::abi::Abi;
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
use syntax::attr::{ThinAttributes, ThinAttributesExt}; use syntax::attr::{ThinAttributes, ThinAttributesExt};
use syntax::parse::token::InternedString; use syntax::parse::token::{keywords, InternedString};
use syntax::ptr::P; use syntax::ptr::P;
use std::collections::BTreeMap; use std::collections::BTreeMap;
...@@ -1055,7 +1054,6 @@ pub struct MethodSig { ...@@ -1055,7 +1054,6 @@ pub struct MethodSig {
pub abi: Abi, pub abi: Abi,
pub decl: P<FnDecl>, pub decl: P<FnDecl>,
pub generics: Generics, pub generics: Generics,
pub explicit_self: ExplicitSelf,
} }
/// Represents an item declaration within a trait declaration, /// Represents an item declaration within a trait declaration,
...@@ -1196,25 +1194,41 @@ pub struct Arg { ...@@ -1196,25 +1194,41 @@ pub struct Arg {
pub id: NodeId, 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 { impl Arg {
pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg { pub fn to_self(&self) -> Option<ExplicitSelf> {
let path = Spanned { if let PatKind::Ident(BindByValue(mutbl), ident, _) = self.pat.node {
span: span, if ident.node.unhygienic_name == keywords::SelfValue.name() {
node: self_ident, return match self.ty.node {
}; TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
Arg { TyRptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyInfer => {
// HACK(eddyb) fake type for the self argument. Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
ty: P(Ty { }
id: DUMMY_NODE_ID, _ => Some(respan(mk_sp(self.pat.span.lo, self.ty.span.hi),
node: TyInfer, SelfKind::Explicit(self.ty.clone(), mutbl)))
span: DUMMY_SP, }
}), }
pat: P(Pat { }
id: DUMMY_NODE_ID, None
node: PatKind::Ident(BindByValue(mutability), path, None), }
span: span,
}), pub fn is_self(&self) -> bool {
id: DUMMY_NODE_ID, if let PatKind::Ident(_, ident, _) = self.pat.node {
ident.node.unhygienic_name == keywords::SelfValue.name()
} else {
false
} }
} }
} }
...@@ -1227,6 +1241,12 @@ pub struct FnDecl { ...@@ -1227,6 +1241,12 @@ pub struct FnDecl {
pub variadic: bool, 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)] #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Unsafety { pub enum Unsafety {
Unsafe, Unsafe,
...@@ -1308,21 +1328,6 @@ pub fn span(&self) -> Span { ...@@ -1308,21 +1328,6 @@ pub fn span(&self) -> Span {
} }
} }
/// 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)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Mod { pub struct Mod {
/// A span from the first token past `{` to the last token until `}`. /// A span from the first token past `{` to the last token until `}`.
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
use syntax::ptr::P; use syntax::ptr::P;
use hir; use hir;
use hir::{Crate, PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use hir::{Crate, PatKind, RegionTyParamBound, SelfKind, TraitTyParamBound, TraitBoundModifier};
use std::io::{self, Write, Read}; use std::io::{self, Write, Read};
...@@ -281,7 +281,6 @@ pub fn fun_to_string(decl: &hir::FnDecl, ...@@ -281,7 +281,6 @@ pub fn fun_to_string(decl: &hir::FnDecl,
unsafety: hir::Unsafety, unsafety: hir::Unsafety,
constness: hir::Constness, constness: hir::Constness,
name: ast::Name, name: ast::Name,
opt_explicit_self: Option<&hir::ExplicitSelf_>,
generics: &hir::Generics) generics: &hir::Generics)
-> String { -> String {
to_string(|s| { to_string(|s| {
...@@ -292,7 +291,6 @@ pub fn fun_to_string(decl: &hir::FnDecl, ...@@ -292,7 +291,6 @@ pub fn fun_to_string(decl: &hir::FnDecl,
Abi::Rust, Abi::Rust,
Some(name), Some(name),
generics, generics,
opt_explicit_self,
&hir::Inherited)?; &hir::Inherited)?;
s.end()?; // Close the head box s.end()?; // Close the head box
s.end() // Close the outer box s.end() // Close the outer box
...@@ -309,10 +307,6 @@ pub fn block_to_string(blk: &hir::Block) -> String { ...@@ -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 { pub fn variant_to_string(var: &hir::Variant) -> String {
to_string(|s| s.print_variant(var)) to_string(|s| s.print_variant(var))
} }
...@@ -526,7 +520,7 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> { ...@@ -526,7 +520,7 @@ pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> {
predicates: hir::HirVec::new(), 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) => { hir::TyPath(None, ref path) => {
self.print_path(path, false, 0)?; self.print_path(path, false, 0)?;
...@@ -573,7 +567,6 @@ pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()> ...@@ -573,7 +567,6 @@ pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()>
Abi::Rust, Abi::Rust,
Some(item.name), Some(item.name),
generics, generics,
None,
&item.vis)?; &item.vis)?;
self.end()?; // end head-ibox self.end()?; // end head-ibox
word(&mut self.s, ";")?; word(&mut self.s, ";")?;
...@@ -710,7 +703,6 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> { ...@@ -710,7 +703,6 @@ pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
abi, abi,
Some(item.name), Some(item.name),
typarams, typarams,
None,
&item.vis)?; &item.vis)?;
word(&mut self.s, " ")?; word(&mut self.s, " ")?;
self.print_block_with_attrs(&body, &item.attrs)?; self.print_block_with_attrs(&body, &item.attrs)?;
...@@ -976,7 +968,6 @@ pub fn print_method_sig(&mut self, ...@@ -976,7 +968,6 @@ pub fn print_method_sig(&mut self,
m.abi, m.abi,
Some(name), Some(name),
&m.generics, &m.generics,
Some(&m.explicit_self.node),
vis) vis)
} }
...@@ -1881,32 +1872,25 @@ fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> { ...@@ -1881,32 +1872,25 @@ fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> {
self.end() // close enclosing cbox self.end() // close enclosing cbox
} }
// Returns whether it printed anything fn print_explicit_self(&mut self, explicit_self: &hir::ExplicitSelf) -> io::Result<()> {
fn print_explicit_self(&mut self, match explicit_self.node {
explicit_self: &hir::ExplicitSelf_, SelfKind::Value(m) => {
mutbl: hir::Mutability) self.print_mutability(m)?;
-> io::Result<bool> { word(&mut self.s, "self")
self.print_mutability(mutbl)?;
match *explicit_self {
hir::SelfStatic => {
return Ok(false);
}
hir::SelfValue(_) => {
word(&mut self.s, "self")?;
} }
hir::SelfRegion(ref lt, m, _) => { SelfKind::Region(ref lt, m) => {
word(&mut self.s, "&")?; word(&mut self.s, "&")?;
self.print_opt_lifetime(lt)?; self.print_opt_lifetime(lt)?;
self.print_mutability(m)?; 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")?; word(&mut self.s, "self")?;
self.word_space(":")?; self.word_space(":")?;
self.print_type(&typ)?; self.print_type(&typ)
} }
} }
return Ok(true);
} }
pub fn print_fn(&mut self, pub fn print_fn(&mut self,
...@@ -1916,7 +1900,6 @@ pub fn print_fn(&mut self, ...@@ -1916,7 +1900,6 @@ pub fn print_fn(&mut self,
abi: Abi, abi: Abi,
name: Option<ast::Name>, name: Option<ast::Name>,
generics: &hir::Generics, generics: &hir::Generics,
opt_explicit_self: Option<&hir::ExplicitSelf_>,
vis: &hir::Visibility) vis: &hir::Visibility)
-> io::Result<()> { -> io::Result<()> {
self.print_fn_header_info(unsafety, constness, abi, vis)?; self.print_fn_header_info(unsafety, constness, abi, vis)?;
...@@ -1926,55 +1909,13 @@ pub fn print_fn(&mut self, ...@@ -1926,55 +1909,13 @@ pub fn print_fn(&mut self,
self.print_name(name)?; self.print_name(name)?;
} }
self.print_generics(generics)?; 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) self.print_where_clause(&generics.where_clause)
} }
pub fn print_fn_args(&mut self, pub fn print_fn_args_and_ret(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
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<()> {
self.popen()?; 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 { if decl.variadic {
word(&mut self.s, ", ...")?; word(&mut self.s, ", ...")?;
} }
...@@ -1985,7 +1926,7 @@ pub fn print_fn_args_and_ret(&mut self, ...@@ -1985,7 +1926,7 @@ pub fn print_fn_args_and_ret(&mut self,
pub fn print_fn_block_args(&mut self, decl: &hir::FnDecl) -> io::Result<()> { pub fn print_fn_block_args(&mut self, decl: &hir::FnDecl) -> io::Result<()> {
word(&mut self.s, "|")?; 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, "|")?; word(&mut self.s, "|")?;
if let hir::DefaultReturn(..) = decl.output { if let hir::DefaultReturn(..) = decl.output {
...@@ -2207,18 +2148,21 @@ pub fn print_arg(&mut self, input: &hir::Arg, is_closure: bool) -> io::Result<() ...@@ -2207,18 +2148,21 @@ pub fn print_arg(&mut self, input: &hir::Arg, is_closure: bool) -> io::Result<()
match input.ty.node { match input.ty.node {
hir::TyInfer if is_closure => self.print_pat(&input.pat)?, hir::TyInfer if is_closure => self.print_pat(&input.pat)?,
_ => { _ => {
match input.pat.node { if let Some(eself) = input.to_self() {
PatKind::Ident(_, ref path1, _) self.print_explicit_self(&eself)?;
if path1.node.name == keywords::Invalid.name() => { } else {
// Do nothing. 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)?; self.print_pat(&input.pat)?;
word(&mut self.s, ":")?; word(&mut self.s, ":")?;
space(&mut self.s)?; space(&mut self.s)?;
} }
self.print_type(&input.ty)?;
} }
self.print_type(&input.ty)?;
} }
} }
self.end() self.end()
...@@ -2250,8 +2194,7 @@ pub fn print_ty_fn(&mut self, ...@@ -2250,8 +2194,7 @@ pub fn print_ty_fn(&mut self,
unsafety: hir::Unsafety, unsafety: hir::Unsafety,
decl: &hir::FnDecl, decl: &hir::FnDecl,
name: Option<ast::Name>, name: Option<ast::Name>,
generics: &hir::Generics, generics: &hir::Generics)
opt_explicit_self: Option<&hir::ExplicitSelf_>)
-> io::Result<()> { -> io::Result<()> {
self.ibox(indent_unit)?; self.ibox(indent_unit)?;
if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() { if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() {
...@@ -2272,7 +2215,6 @@ pub fn print_ty_fn(&mut self, ...@@ -2272,7 +2215,6 @@ pub fn print_ty_fn(&mut self,
abi, abi,
name, name,
&generics, &generics,
opt_explicit_self,
&hir::Inherited)?; &hir::Inherited)?;
self.end() self.end()
} }
......
...@@ -976,8 +976,7 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio ...@@ -976,8 +976,7 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio
ast_map::NodeItem(ref item) => { ast_map::NodeItem(ref item) => {
match item.node { match item.node {
hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => { hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
Some((fn_decl, gen, unsafety, constness, Some((fn_decl, gen, unsafety, constness, item.name, item.span))
item.name, None, item.span))
}, },
_ => None _ => None
} }
...@@ -990,7 +989,6 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio ...@@ -990,7 +989,6 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio
sig.unsafety, sig.unsafety,
sig.constness, sig.constness,
item.name, item.name,
Some(&sig.explicit_self.node),
item.span)) item.span))
} }
_ => None, _ => None,
...@@ -1004,7 +1002,6 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio ...@@ -1004,7 +1002,6 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio
sig.unsafety, sig.unsafety,
sig.constness, sig.constness,
item.name, item.name,
Some(&sig.explicit_self.node),
item.span)) item.span))
} }
_ => None _ => None
...@@ -1014,13 +1011,11 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio ...@@ -1014,13 +1011,11 @@ fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegio
}, },
None => None 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"); = node_inner.expect("expect item fn");
let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self, let rebuilder = Rebuilder::new(self.tcx, fn_decl, generics, same_regions, &life_giver);
generics, same_regions, &life_giver); let (fn_decl, generics) = rebuilder.rebuild();
let (fn_decl, expl_self, generics) = rebuilder.rebuild(); self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name, &generics, span);
self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name,
expl_self.as_ref(), &generics, span);
} }
} }
...@@ -1038,7 +1033,6 @@ struct RebuildPathInfo<'a> { ...@@ -1038,7 +1033,6 @@ struct RebuildPathInfo<'a> {
struct Rebuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { struct Rebuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>,
fn_decl: &'a hir::FnDecl, fn_decl: &'a hir::FnDecl,
expl_self_opt: Option<&'a hir::ExplicitSelf_>,
generics: &'a hir::Generics, generics: &'a hir::Generics,
same_regions: &'a [SameRegions], same_regions: &'a [SameRegions],
life_giver: &'a LifeGiver, life_giver: &'a LifeGiver,
...@@ -1054,7 +1048,6 @@ enum FreshOrKept { ...@@ -1054,7 +1048,6 @@ enum FreshOrKept {
impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
fn_decl: &'a hir::FnDecl, fn_decl: &'a hir::FnDecl,
expl_self_opt: Option<&'a hir::ExplicitSelf_>,
generics: &'a hir::Generics, generics: &'a hir::Generics,
same_regions: &'a [SameRegions], same_regions: &'a [SameRegions],
life_giver: &'a LifeGiver) life_giver: &'a LifeGiver)
...@@ -1062,7 +1055,6 @@ fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, ...@@ -1062,7 +1055,6 @@ fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
Rebuilder { Rebuilder {
tcx: tcx, tcx: tcx,
fn_decl: fn_decl, fn_decl: fn_decl,
expl_self_opt: expl_self_opt,
generics: generics, generics: generics,
same_regions: same_regions, same_regions: same_regions,
life_giver: life_giver, life_giver: life_giver,
...@@ -1071,9 +1063,7 @@ fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, ...@@ -1071,9 +1063,7 @@ fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
} }
} }
fn rebuild(&self) fn rebuild(&self) -> (hir::FnDecl, hir::Generics) {
-> (hir::FnDecl, Option<hir::ExplicitSelf_>, hir::Generics) {
let mut expl_self_opt = self.expl_self_opt.cloned();
let mut inputs = self.fn_decl.inputs.clone(); let mut inputs = self.fn_decl.inputs.clone();
let mut output = self.fn_decl.output.clone(); let mut output = self.fn_decl.output.clone();
let mut ty_params = self.generics.ty_params.clone(); let mut ty_params = self.generics.ty_params.clone();
...@@ -1089,8 +1079,6 @@ fn rebuild(&self) ...@@ -1089,8 +1079,6 @@ fn rebuild(&self)
Kept => { kept_lifetimes.insert(lifetime.name); } 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, inputs = self.rebuild_args_ty(&inputs[..], lifetime,
&anon_nums, &region_names); &anon_nums, &region_names);
output = self.rebuild_output(&output, lifetime, &anon_nums, &region_names); output = self.rebuild_output(&output, lifetime, &anon_nums, &region_names);
...@@ -1110,7 +1098,7 @@ fn rebuild(&self) ...@@ -1110,7 +1098,7 @@ fn rebuild(&self)
output: output, output: output,
variadic: self.fn_decl.variadic variadic: self.fn_decl.variadic
}; };
(new_fn_decl, expl_self_opt, generics) (new_fn_decl, generics)
} }
fn pick_lifetime(&self, fn pick_lifetime(&self,
...@@ -1250,34 +1238,6 @@ fn rebuild_ty_param_bounds(&self, ...@@ -1250,34 +1238,6 @@ fn rebuild_ty_param_bounds(&self,
}).collect() }).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, fn rebuild_generics(&self,
generics: &hir::Generics, generics: &hir::Generics,
add: &Vec<hir::Lifetime>, add: &Vec<hir::Lifetime>,
...@@ -1575,11 +1535,9 @@ fn give_expl_lifetime_param(&self, ...@@ -1575,11 +1535,9 @@ fn give_expl_lifetime_param(&self,
unsafety: hir::Unsafety, unsafety: hir::Unsafety,
constness: hir::Constness, constness: hir::Constness,
name: ast::Name, name: ast::Name,
opt_explicit_self: Option<&hir::ExplicitSelf_>,
generics: &hir::Generics, generics: &hir::Generics,
span: Span) { span: Span) {
let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, name, let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, name, generics);
opt_explicit_self, generics);
let msg = format!("consider using an explicit lifetime \ let msg = format!("consider using an explicit lifetime \
parameter as shown: {}", suggested_fn); parameter as shown: {}", suggested_fn);
err.span_help(span, &msg[..]); err.span_help(span, &msg[..]);
......
...@@ -889,11 +889,6 @@ fn visit_lifetime_def(&mut self, lt: &hir::LifetimeDef) { ...@@ -889,11 +889,6 @@ fn visit_lifetime_def(&mut self, lt: &hir::LifetimeDef) {
run_lints!(self, check_lifetime_def, late_passes, lt); 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) { fn visit_path(&mut self, p: &hir::Path, id: ast::NodeId) {
run_lints!(self, check_path, late_passes, p, id); run_lints!(self, check_path, late_passes, p, id);
hir_visit::walk_path(self, p); hir_visit::walk_path(self, p);
......
...@@ -483,7 +483,6 @@ fn add_scope_and_walk_fn<'b>(&mut self, ...@@ -483,7 +483,6 @@ fn add_scope_and_walk_fn<'b>(&mut self,
FnKind::Method(_, sig, _, _) => { FnKind::Method(_, sig, _, _) => {
intravisit::walk_fn_decl(self, fd); intravisit::walk_fn_decl(self, fd);
self.visit_generics(&sig.generics); self.visit_generics(&sig.generics);
self.visit_explicit_self(&sig.explicit_self);
} }
FnKind::Closure(_) => { FnKind::Closure(_) => {
intravisit::walk_fn_decl(self, fd); intravisit::walk_fn_decl(self, fd);
......
...@@ -172,7 +172,6 @@ enum SawAbiComponent<'a> { ...@@ -172,7 +172,6 @@ enum SawAbiComponent<'a> {
SawImplItem, SawImplItem,
SawStructField, SawStructField,
SawVariant, SawVariant,
SawExplicitSelf,
SawPath, SawPath,
SawBlock, SawBlock,
SawPat, SawPat,
...@@ -391,10 +390,6 @@ fn visit_struct_field(&mut self, s: &'a StructField) { ...@@ -391,10 +390,6 @@ fn visit_struct_field(&mut self, s: &'a StructField) {
SawStructField.hash(self.st); visit::walk_struct_field(self, s) 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) { fn visit_path(&mut self, path: &'a Path, _: ast::NodeId) {
SawPath.hash(self.st); visit::walk_path(self, path) SawPath.hash(self.st); visit::walk_path(self, path)
} }
......
...@@ -831,8 +831,8 @@ fn visit_item(&mut self, item: &hir::Item) { ...@@ -831,8 +831,8 @@ fn visit_item(&mut self, item: &hir::Item) {
} }
} }
hir::ImplItemKind::Method(ref sig, _) => { hir::ImplItemKind::Method(ref sig, _) => {
if sig.explicit_self.node == hir::SelfStatic && if !sig.decl.has_self() &&
self.item_is_public(&impl_item.id, &impl_item.vis) { self.item_is_public(&impl_item.id, &impl_item.vis) {
found_pub_static = true; found_pub_static = true;
intravisit::walk_impl_item(self, impl_item); intravisit::walk_impl_item(self, impl_item);
} }
......
...@@ -582,7 +582,6 @@ fn visit_fn(&mut self, ...@@ -582,7 +582,6 @@ fn visit_fn(&mut self,
} }
FnKind::Method(_, sig, _) => { FnKind::Method(_, sig, _) => {
self.visit_generics(&sig.generics); self.visit_generics(&sig.generics);
self.visit_explicit_self(&sig.explicit_self);
MethodRibKind MethodRibKind
} }
FnKind::Closure => ClosureRibKind(node_id), FnKind::Closure => ClosureRibKind(node_id),
......
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
use syntax::parse::token::{self, keywords}; use syntax::parse::token::{self, keywords};
use rustc::hir::print as pprust; use rustc::hir::print as pprust;
use rustc::hir; use rustc::hir::{self, SelfKind};
use rustc_back::slice; use rustc_back::slice;
pub trait AstConv<'gcx, 'tcx> { pub trait AstConv<'gcx, 'tcx> {
...@@ -166,11 +166,6 @@ struct ConvertedBinding<'tcx> { ...@@ -166,11 +166,6 @@ struct ConvertedBinding<'tcx> {
span: Span, 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>>); type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec<ty::PolyProjectionPredicate<'tcx>>);
pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime) pub fn ast_region_to_region(tcx: TyCtxt, lifetime: &hir::Lifetime)
...@@ -1719,33 +1714,28 @@ pub fn ty_of_method(&self, ...@@ -1719,33 +1714,28 @@ pub fn ty_of_method(&self,
sig: &hir::MethodSig, sig: &hir::MethodSig,
untransformed_self_ty: Ty<'tcx>) untransformed_self_ty: Ty<'tcx>)
-> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) { -> (&'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) = let (bare_fn_ty, optional_explicit_self_category) =
self.ty_of_method_or_bare_fn(sig.unsafety, self.ty_of_method_or_bare_fn(sig.unsafety,
sig.abi, sig.abi,
self_info, Some(untransformed_self_ty),
&sig.decl); &sig.decl);
(bare_fn_ty, optional_explicit_self_category.unwrap()) (bare_fn_ty, optional_explicit_self_category)
} }
pub fn ty_of_bare_fn(&self, pub fn ty_of_bare_fn(&self,
unsafety: hir::Unsafety, abi: abi::Abi, unsafety: hir::Unsafety,
abi: abi::Abi,
decl: &hir::FnDecl) decl: &hir::FnDecl)
-> &'tcx ty::BareFnTy<'tcx> { -> &'tcx ty::BareFnTy<'tcx> {
let (bare_fn_ty, _) = self.ty_of_method_or_bare_fn(unsafety, abi, None, decl); self.ty_of_method_or_bare_fn(unsafety, abi, None, decl).0
bare_fn_ty
} }
fn ty_of_method_or_bare_fn<'a>(&self, fn ty_of_method_or_bare_fn<'a>(&self,
unsafety: hir::Unsafety, unsafety: hir::Unsafety,
abi: abi::Abi, abi: abi::Abi,
opt_self_info: Option<SelfInfo<'a, 'tcx>>, opt_untransformed_self_ty: Option<Ty<'tcx>>,
decl: &hir::FnDecl) decl: &hir::FnDecl)
-> (&'tcx ty::BareFnTy<'tcx>, -> (&'tcx ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory)
Option<ty::ExplicitSelfCategory>)
{ {
debug!("ty_of_method_or_bare_fn"); debug!("ty_of_method_or_bare_fn");
...@@ -1758,9 +1748,14 @@ fn ty_of_method_or_bare_fn<'a>(&self, ...@@ -1758,9 +1748,14 @@ fn ty_of_method_or_bare_fn<'a>(&self,
// lifetime elision, we can determine it in two ways. First (determined // lifetime elision, we can determine it in two ways. First (determined
// here), if self is by-reference, then the implied output region is the // here), if self is by-reference, then the implied output region is the
// region of the self parameter. // region of the self parameter.
let (self_ty, explicit_self_category) = match opt_self_info { let explicit_self = decl.inputs.get(0).and_then(hir::Arg::to_self);
None => (None, None), let (self_ty, explicit_self_category) = match (opt_untransformed_self_ty, explicit_self) {
Some(self_info) => self.determine_self_type(&rb, self_info) (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. // HACK(eddyb) replace the fake self type in the AST with the actual type.
...@@ -1778,7 +1773,7 @@ fn ty_of_method_or_bare_fn<'a>(&self, ...@@ -1778,7 +1773,7 @@ fn ty_of_method_or_bare_fn<'a>(&self,
// reference) in the arguments, then any anonymous regions in the output // reference) in the arguments, then any anonymous regions in the output
// have that lifetime. // have that lifetime.
let implied_output_region = match explicit_self_category { 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) _ => self.find_implied_output_region(&arg_tys, arg_pats)
}; };
...@@ -1803,29 +1798,29 @@ fn ty_of_method_or_bare_fn<'a>(&self, ...@@ -1803,29 +1798,29 @@ fn ty_of_method_or_bare_fn<'a>(&self,
fn determine_self_type<'a>(&self, fn determine_self_type<'a>(&self,
rscope: &RegionScope, rscope: &RegionScope,
self_info: SelfInfo<'a, 'tcx>) untransformed_self_ty: Ty<'tcx>,
-> (Option<Ty<'tcx>>, Option<ty::ExplicitSelfCategory>) explicit_self: &hir::ExplicitSelf)
-> (Ty<'tcx>, ty::ExplicitSelfCategory)
{ {
let self_ty = self_info.untransformed_self_ty; return match explicit_self.node {
return match self_info.explicit_self.node { SelfKind::Value(..) => {
hir::SelfStatic => (None, Some(ty::ExplicitSelfCategory::Static)), (untransformed_self_ty, ty::ExplicitSelfCategory::ByValue)
hir::SelfValue(_) => {
(Some(self_ty), Some(ty::ExplicitSelfCategory::ByValue))
} }
hir::SelfRegion(ref lifetime, mutability, _) => { SelfKind::Region(ref lifetime, mutability) => {
let region = let region =
self.opt_ast_region_to_region(rscope, self.opt_ast_region_to_region(
self_info.explicit_self.span, rscope,
lifetime); explicit_self.span,
(Some(self.tcx().mk_ref( lifetime);
(self.tcx().mk_ref(
self.tcx().mk_region(region), self.tcx().mk_region(region),
ty::TypeAndMut { ty::TypeAndMut {
ty: self_ty, ty: untransformed_self_ty,
mutbl: mutability 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); let explicit_type = self.ast_ty_to_ty(rscope, &ast_type);
// We wish to (for now) categorize an explicit self // We wish to (for now) categorize an explicit self
...@@ -1857,13 +1852,13 @@ fn determine_self_type<'a>(&self, ...@@ -1857,13 +1852,13 @@ fn determine_self_type<'a>(&self,
// type has two, so we end up with // type has two, so we end up with
// ExplicitSelfCategory::ByReference. // 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); let method_modifiers = count_modifiers(explicit_type);
debug!("determine_explicit_self_category(self_info.untransformed_self_ty={:?} \ debug!("determine_explicit_self_category(self_info.untransformed_self_ty={:?} \
explicit_type={:?} \ explicit_type={:?} \
modifiers=({},{})", modifiers=({},{})",
self_info.untransformed_self_ty, untransformed_self_ty,
explicit_type, explicit_type,
impl_modifiers, impl_modifiers,
method_modifiers); method_modifiers);
...@@ -1878,7 +1873,7 @@ fn determine_self_type<'a>(&self, ...@@ -1878,7 +1873,7 @@ fn determine_self_type<'a>(&self,
} }
}; };
(Some(explicit_type), Some(category)) (explicit_type, category)
} }
}; };
......
...@@ -361,7 +361,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, ...@@ -361,7 +361,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
let mut item = method.clean(cx); let mut item = method.clean(cx);
item.inner = match item.inner.clone() { item.inner = match item.inner.clone() {
clean::TyMethodItem(clean::TyMethod { clean::TyMethodItem(clean::TyMethod {
unsafety, decl, self_, generics, abi unsafety, decl, generics, abi
}) => { }) => {
let constness = if tcx.sess.cstore.is_const_fn(did) { let constness = if tcx.sess.cstore.is_const_fn(did) {
hir::Constness::Const hir::Constness::Const
...@@ -373,7 +373,6 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, ...@@ -373,7 +373,6 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
unsafety: unsafety, unsafety: unsafety,
constness: constness, constness: constness,
decl: decl, decl: decl,
self_: self_,
generics: generics, generics: generics,
abi: abi abi: abi
}) })
......
...@@ -1025,7 +1025,6 @@ fn clean(&self, cx: &DocContext) -> Generics { ...@@ -1025,7 +1025,6 @@ fn clean(&self, cx: &DocContext) -> Generics {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Method { pub struct Method {
pub generics: Generics, pub generics: Generics,
pub self_: SelfTy,
pub unsafety: hir::Unsafety, pub unsafety: hir::Unsafety,
pub constness: hir::Constness, pub constness: hir::Constness,
pub decl: FnDecl, pub decl: FnDecl,
...@@ -1034,14 +1033,9 @@ pub struct Method { ...@@ -1034,14 +1033,9 @@ pub struct Method {
impl Clean<Method> for hir::MethodSig { impl Clean<Method> for hir::MethodSig {
fn clean(&self, cx: &DocContext) -> Method { 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 { let decl = FnDecl {
inputs: Arguments { inputs: Arguments {
values: inputs.clean(cx), values: self.decl.inputs.clean(cx),
}, },
output: self.decl.output.clean(cx), output: self.decl.output.clean(cx),
variadic: false, variadic: false,
...@@ -1049,7 +1043,6 @@ fn clean(&self, cx: &DocContext) -> Method { ...@@ -1049,7 +1043,6 @@ fn clean(&self, cx: &DocContext) -> Method {
}; };
Method { Method {
generics: self.generics.clean(cx), generics: self.generics.clean(cx),
self_: self.explicit_self.node.clean(cx),
unsafety: self.unsafety, unsafety: self.unsafety,
constness: self.constness, constness: self.constness,
decl: decl, decl: decl,
...@@ -1063,19 +1056,14 @@ pub struct TyMethod { ...@@ -1063,19 +1056,14 @@ pub struct TyMethod {
pub unsafety: hir::Unsafety, pub unsafety: hir::Unsafety,
pub decl: FnDecl, pub decl: FnDecl,
pub generics: Generics, pub generics: Generics,
pub self_: SelfTy,
pub abi: Abi, pub abi: Abi,
} }
impl Clean<TyMethod> for hir::MethodSig { impl Clean<TyMethod> for hir::MethodSig {
fn clean(&self, cx: &DocContext) -> TyMethod { 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 { let decl = FnDecl {
inputs: Arguments { inputs: Arguments {
values: inputs.clean(cx), values: self.decl.inputs.clean(cx),
}, },
output: self.decl.output.clean(cx), output: self.decl.output.clean(cx),
variadic: false, variadic: false,
...@@ -1084,34 +1072,12 @@ fn clean(&self, cx: &DocContext) -> TyMethod { ...@@ -1084,34 +1072,12 @@ fn clean(&self, cx: &DocContext) -> TyMethod {
TyMethod { TyMethod {
unsafety: self.unsafety.clone(), unsafety: self.unsafety.clone(),
decl: decl, decl: decl,
self_: self.explicit_self.node.clean(cx),
generics: self.generics.clean(cx), generics: self.generics.clean(cx),
abi: self.abi 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)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Function { pub struct Function {
pub decl: FnDecl, pub decl: FnDecl,
...@@ -1150,6 +1116,12 @@ pub struct FnDecl { ...@@ -1150,6 +1116,12 @@ pub struct FnDecl {
pub attrs: Vec<Attribute>, 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)] #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
pub struct Arguments { pub struct Arguments {
pub values: Vec<Argument>, pub values: Vec<Argument>,
...@@ -1185,9 +1157,6 @@ fn clean(&self, cx: &DocContext) -> FnDecl { ...@@ -1185,9 +1157,6 @@ fn clean(&self, cx: &DocContext) -> FnDecl {
} else { } else {
cx.tcx().sess.cstore.method_arg_names(did).into_iter() cx.tcx().sess.cstore.method_arg_names(did).into_iter()
}.peekable(); }.peekable();
if let Some("self") = names.peek().map(|s| &s[..]) {
let _ = names.next();
}
FnDecl { FnDecl {
output: Return(sig.0.output.clean(cx)), output: Return(sig.0.output.clean(cx)),
attrs: Vec::new(), attrs: Vec::new(),
...@@ -1212,6 +1181,29 @@ pub struct Argument { ...@@ -1212,6 +1181,29 @@ pub struct Argument {
pub id: ast::NodeId, 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 { impl Clean<Argument> for hir::Arg {
fn clean(&self, cx: &DocContext) -> Argument { fn clean(&self, cx: &DocContext) -> Argument {
Argument { Argument {
...@@ -1346,36 +1338,21 @@ fn clean(&self, cx: &DocContext) -> Item { ...@@ -1346,36 +1338,21 @@ fn clean(&self, cx: &DocContext) -> Item {
impl<'tcx> Clean<Item> for ty::Method<'tcx> { impl<'tcx> Clean<Item> for ty::Method<'tcx> {
fn clean(&self, cx: &DocContext) -> Item { 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, let generics = (&self.generics, &self.predicates,
subst::FnSpace).clean(cx); 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 { let provided = match self.container {
ty::ImplContainer(..) => false, ty::ImplContainer(..) => false,
ty::TraitContainer(did) => { ty::TraitContainer(did) => {
...@@ -1388,7 +1365,6 @@ fn clean(&self, cx: &DocContext) -> Item { ...@@ -1388,7 +1365,6 @@ fn clean(&self, cx: &DocContext) -> Item {
MethodItem(Method { MethodItem(Method {
unsafety: self.fty.unsafety, unsafety: self.fty.unsafety,
generics: generics, generics: generics,
self_: self_,
decl: decl, decl: decl,
abi: self.fty.abi, abi: self.fty.abi,
...@@ -1399,7 +1375,6 @@ fn clean(&self, cx: &DocContext) -> Item { ...@@ -1399,7 +1375,6 @@ fn clean(&self, cx: &DocContext) -> Item {
TyMethodItem(TyMethod { TyMethodItem(TyMethod {
unsafety: self.fty.unsafety, unsafety: self.fty.unsafety,
generics: generics, generics: generics,
self_: self_,
decl: decl, decl: decl,
abi: self.fty.abi, abi: self.fty.abi,
}) })
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct ConstnessSpace(pub hir::Constness); pub struct ConstnessSpace(pub hir::Constness);
/// Wrapper struct for properly emitting a method declaration. /// 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 /// Similar to VisSpace, but used for mutability
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct MutableSpace(pub clean::Mutability); pub struct MutableSpace(pub clean::Mutability);
...@@ -642,29 +642,31 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ...@@ -642,29 +642,31 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
impl<'a> fmt::Display for Method<'a> { impl<'a> fmt::Display for Method<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let Method(selfty, d) = *self; let decl = self.0;
let mut args = String::new(); let mut args = String::new();
match *selfty { for (i, input) in decl.inputs.values.iter().enumerate() {
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() {
if i > 0 || !args.is_empty() { args.push_str(", "); } if i > 0 || !args.is_empty() { args.push_str(", "); }
if !input.name.is_empty() { if let Some(selfty) = input.to_self() {
args.push_str(&format!("{}: ", input.name)); 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)
} }
} }
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
use rustc::session::config::get_unstable_features_setting; use rustc::session::config::get_unstable_features_setting;
use rustc::hir; use rustc::hir;
use clean::{self, SelfTy, Attributes, GetDefId}; use clean::{self, Attributes, GetDefId};
use doctree; use doctree;
use fold::DocFolder; use fold::DocFolder;
use html::escape::Escape; use html::escape::Escape;
...@@ -592,8 +592,6 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { ...@@ -592,8 +592,6 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
for &(did, ref item) in orphan_methods { for &(did, ref item) in orphan_methods {
match paths.get(&did) { match paths.get(&did) {
Some(&(ref fqp, _)) => { Some(&(ref fqp, _)) => {
// Needed to determine `self` type.
let parent_basename = Some(fqp[fqp.len() - 1].clone());
search_index.push(IndexItem { search_index.push(IndexItem {
ty: shortty(item), ty: shortty(item),
name: item.name.clone().unwrap(), name: item.name.clone().unwrap(),
...@@ -601,7 +599,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { ...@@ -601,7 +599,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
desc: Escape(&shorter(item.doc_value())).to_string(), desc: Escape(&shorter(item.doc_value())).to_string(),
parent: Some(did), parent: Some(did),
parent_idx: None, parent_idx: None,
search_type: get_index_search_type(&item, parent_basename), search_type: get_index_search_type(&item),
}); });
}, },
None => {} None => {}
...@@ -1081,13 +1079,6 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { ...@@ -1081,13 +1079,6 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
match parent { match parent {
(parent, Some(path)) if is_method || (!self.stripped_mod) => { (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()); debug_assert!(!item.is_stripped());
// A crate has a module at its root, containing all items, // A crate has a module at its root, containing all items,
...@@ -1101,7 +1092,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> { ...@@ -1101,7 +1092,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
desc: Escape(&shorter(item.doc_value())).to_string(), desc: Escape(&shorter(item.doc_value())).to_string(),
parent: parent, parent: parent,
parent_idx: None, parent_idx: None,
search_type: get_index_search_type(&item, parent_basename), search_type: get_index_search_type(&item),
}); });
} }
} }
...@@ -2167,7 +2158,6 @@ fn method(w: &mut fmt::Formatter, ...@@ -2167,7 +2158,6 @@ fn method(w: &mut fmt::Formatter,
constness: hir::Constness, constness: hir::Constness,
abi: abi::Abi, abi: abi::Abi,
g: &clean::Generics, g: &clean::Generics,
selfty: &clean::SelfTy,
d: &clean::FnDecl, d: &clean::FnDecl,
link: AssocItemLink) link: AssocItemLink)
-> fmt::Result { -> fmt::Result {
...@@ -2201,18 +2191,18 @@ fn method(w: &mut fmt::Formatter, ...@@ -2201,18 +2191,18 @@ fn method(w: &mut fmt::Formatter,
href = href, href = href,
name = name, name = name,
generics = *g, generics = *g,
decl = Method(selfty, d), decl = Method(d),
where_clause = WhereClause(g)) where_clause = WhereClause(g))
} }
match item.inner { match item.inner {
clean::StrippedItem(..) => Ok(()), clean::StrippedItem(..) => Ok(()),
clean::TyMethodItem(ref m) => { clean::TyMethodItem(ref m) => {
method(w, item, m.unsafety, hir::Constness::NotConst, 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) => { clean::MethodItem(ref m) => {
method(w, item, m.unsafety, m.constness, method(w, item, m.unsafety, m.constness,
m.abi, &m.generics, &m.self_, &m.decl, m.abi, &m.generics, &m.decl,
link) link)
} }
clean::AssociatedConstItem(ref ty, ref default) => { clean::AssociatedConstItem(ref ty, ref default) => {
...@@ -2570,8 +2560,8 @@ fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item, ...@@ -2570,8 +2560,8 @@ fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
let name = item.name.as_ref().unwrap(); let name = item.name.as_ref().unwrap();
let is_static = match item.inner { let is_static = match item.inner {
clean::MethodItem(ref method) => method.self_ == SelfTy::SelfStatic, clean::MethodItem(ref method) => !method.decl.has_self(),
clean::TyMethodItem(ref method) => method.self_ == SelfTy::SelfStatic, clean::TyMethodItem(ref method) => !method.decl.has_self(),
_ => false _ => false
}; };
...@@ -2760,27 +2750,15 @@ fn make_item_keywords(it: &clean::Item) -> String { ...@@ -2760,27 +2750,15 @@ fn make_item_keywords(it: &clean::Item) -> String {
format!("{}, {}", BASIC_KEYWORDS, it.name.as_ref().unwrap()) format!("{}, {}", BASIC_KEYWORDS, it.name.as_ref().unwrap())
} }
fn get_index_search_type(item: &clean::Item, fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
parent: Option<String>) -> Option<IndexItemFunctionType> { let decl = match item.inner {
let (decl, selfty) = match item.inner { clean::FunctionItem(ref f) => &f.decl,
clean::FunctionItem(ref f) => (&f.decl, None), clean::MethodItem(ref m) => &m.decl,
clean::MethodItem(ref m) => (&m.decl, Some(&m.self_)), clean::TyMethodItem(ref m) => &m.decl,
clean::TyMethodItem(ref m) => (&m.decl, Some(&m.self_)),
_ => return None _ => return None
}; };
let mut inputs = Vec::new(); let inputs = decl.inputs.values.iter().map(|arg| get_index_type(&arg.type_)).collect();
// 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 output = match decl.output { let output = match decl.output {
clean::FunctionRetTy::Return(ref return_type) => Some(get_index_type(return_type)), clean::FunctionRetTy::Return(ref return_type) => Some(get_index_type(return_type)),
_ => None _ => None
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册