diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 28506fd20fe53..48b4b867ee2d9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -788,10 +788,10 @@ impl<'a> LoweringContext<'a> { fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig { // Check for `self: _` and `self: &_` - if let SelfKind::Explicit(ref ty, _) = sig.explicit_self.node { - match sig.decl.inputs.get(0).and_then(Arg::to_self).map(|eself| eself.node) { + if !sig.self_shortcut { + match sig.decl.get_self().map(|eself| eself.node) { Some(SelfKind::Value(..)) | Some(SelfKind::Region(..)) => { - self.id_assigner.diagnostic().span_err(ty.span, + self.id_assigner.diagnostic().span_err(sig.decl.inputs[0].ty.span, "the type placeholder `_` is not allowed within types on item signatures"); } _ => {} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 39a6ec9f3af27..b9f0f6ab5d56d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1175,6 +1175,9 @@ pub struct FnDecl { } impl FnDecl { + pub fn get_self(&self) -> Option { + self.inputs.get(0).and_then(Arg::to_self) + } pub fn has_self(&self) -> bool { self.inputs.get(0).map(Arg::is_self).unwrap_or(false) } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 0801f8f4ac7ef..94f17ea779ac8 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1043,11 +1043,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> { run_lints!(self, check_lifetime_def, early_passes, lt); } - fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf) { - run_lints!(self, check_explicit_self, early_passes, es); - ast_visit::walk_explicit_self(self, es); - } - fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) { run_lints!(self, check_path, early_passes, p, id); ast_visit::walk_path(self, p); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 28994e1a7c48d..cc7fa54bd0a5e 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -167,7 +167,6 @@ pub trait LateLintPass: LintPass { fn check_variant_post(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { } fn check_lifetime(&mut self, _: &LateContext, _: &hir::Lifetime) { } fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { } - fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { } fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { } fn check_path_list_item(&mut self, _: &LateContext, _: &hir::PathListItem) { } fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { } @@ -218,7 +217,6 @@ pub trait EarlyLintPass: LintPass { fn check_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { } fn check_lifetime(&mut self, _: &EarlyContext, _: &ast::Lifetime) { } fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { } - fn check_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { } fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { } fn check_path_list_item(&mut self, _: &EarlyContext, _: &ast::PathListItem) { } fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index f56b22f924891..e0243bf4fa690 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -35,7 +35,7 @@ use syntax::codemap::{Span, DUMMY_SP}; use syntax::ast::{Block, Crate, DeclKind}; use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind}; use syntax::ast::{Mutability, PathListItemKind}; -use syntax::ast::{SelfKind, Stmt, StmtKind, TraitItemKind}; +use syntax::ast::{Stmt, StmtKind, TraitItemKind}; use syntax::ast::{Variant, ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use syntax::visit::{self, Visitor}; @@ -335,7 +335,7 @@ impl<'b> Resolver<'b> { let (def, ns) = match item.node { TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS), TraitItemKind::Method(ref sig, _) => { - is_static_method = sig.explicit_self.node == SelfKind::Static; + is_static_method = !sig.decl.has_self(); (Def::Method(item_def_id), ValueNS) } TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 1df12b63e0a50..fc1abb56d5abc 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1833,8 +1833,7 @@ 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 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) { + let (self_ty, explicit_self_category) = match (opt_untransformed_self_ty, decl.get_self()) { (Some(untransformed_self_ty), Some(explicit_self)) => { let self_type = self.determine_self_type(&rb, untransformed_self_ty, &explicit_self); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d9409d3bbd921..65bc486372b62 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1387,7 +1387,8 @@ pub struct MethodSig { pub abi: Abi, pub decl: P, pub generics: Generics, - pub explicit_self: ExplicitSelf, + /// A short form of self argument was used (`self`, `&self` etc, but not `self: TYPE`). + pub self_shortcut: bool, } /// Represents an item declaration within a trait declaration, @@ -1677,81 +1678,65 @@ pub struct Arg { pub id: NodeId, } -/// Represents the kind of 'self' associated with a method. -/// String representation of `Ident` here is always "self", but hygiene contexts may differ. +/// Alternative representation for `Arg`s describing `self` parameter of methods. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum SelfKind { - /// No self - Static, /// `self`, `mut self` - Value(Ident), + Value(Mutability), /// `&'lt self`, `&'lt mut self` - Region(Option, Mutability, Ident), + Region(Option, Mutability), /// `self: TYPE`, `mut self: TYPE` - Explicit(P, Ident), + Explicit(P, Mutability), } pub type ExplicitSelf = Spanned; impl Arg { - #[unstable(feature = "rustc_private", issue = "27812")] - #[rustc_deprecated(since = "1.10.0", reason = "use `from_self` instead")] - 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: TyKind::Infer, - span: DUMMY_SP, - }), - pat: P(Pat { - id: DUMMY_NODE_ID, - node: PatKind::Ident(BindingMode::ByValue(mutability), path, None), - span: span - }), - id: DUMMY_NODE_ID - } - } - pub fn to_self(&self) -> Option { - if let PatKind::Ident(_, ident, _) = self.pat.node { + if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node { if ident.node.name == keywords::SelfValue.name() { return match self.ty.node { - TyKind::Infer => Some(respan(self.pat.span, SelfKind::Value(ident.node))), + TyKind::Infer => Some(respan(self.pat.span, SelfKind::Value(mutbl))), TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::Infer => { - Some(respan(self.pat.span, SelfKind::Region(lt, mutbl, ident.node))) + 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(), ident.node))), + SelfKind::Explicit(self.ty.clone(), mutbl))), } } } None } - pub fn from_self(eself: ExplicitSelf, ident_sp: Span, mutbl: Mutability) -> Arg { - let pat = |ident, span| P(Pat { - id: DUMMY_NODE_ID, - node: PatKind::Ident(BindingMode::ByValue(mutbl), respan(ident_sp, ident), None), - span: span, - }); + pub fn is_self(&self) -> bool { + if let PatKind::Ident(_, ident, _) = self.pat.node { + ident.node.name == keywords::SelfValue.name() + } else { + false + } + } + + pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg { let infer_ty = P(Ty { id: DUMMY_NODE_ID, node: TyKind::Infer, span: DUMMY_SP, }); - let arg = |ident, ty, span| Arg { - pat: pat(ident, span), + let arg = |mutbl, ty, span| Arg { + pat: P(Pat { + id: DUMMY_NODE_ID, + node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None), + span: span, + }), ty: ty, id: DUMMY_NODE_ID, }; match eself.node { - SelfKind::Static => panic!("bug: `Arg::from_self` is called \ - with `SelfKind::Static` argument"), - SelfKind::Explicit(ty, ident) => arg(ident, ty, mk_sp(eself.span.lo, ident_sp.hi)), - SelfKind::Value(ident) => arg(ident, infer_ty, eself.span), - SelfKind::Region(lt, mutbl, ident) => arg(ident, P(Ty { + SelfKind::Explicit(ty, mutbl) => { + arg(mutbl, ty, mk_sp(eself.span.lo, eself_ident.span.hi)) + } + SelfKind::Value(mutbl) => arg(mutbl, infer_ty, eself.span), + SelfKind::Region(lt, mutbl) => arg(Mutability::Immutable, P(Ty { id: DUMMY_NODE_ID, node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }), span: DUMMY_SP, @@ -1768,6 +1753,15 @@ pub struct FnDecl { pub variadic: bool } +impl FnDecl { + pub fn get_self(&self) -> Option { + self.inputs.get(0).and_then(Arg::to_self) + } + 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, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f243706eecb80..d90389bef7f79 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1128,7 +1128,7 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P, (ast::MethodSig { generics: fld.fold_generics(sig.generics), abi: sig.abi, - explicit_self: fld.fold_explicit_self(sig.explicit_self), + self_shortcut: sig.self_shortcut, unsafety: sig.unsafety, constness: sig.constness, decl: rewritten_fn_decl diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2c325080c0c26..a8f048c6c4ebe 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -179,14 +179,6 @@ pub trait Folder : Sized { // fold::noop_fold_mac(_mac, self) } - fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf { - noop_fold_explicit_self(es, self) - } - - fn fold_explicit_self_kind(&mut self, es: SelfKind) -> SelfKind { - noop_fold_explicit_self_kind(es, self) - } - fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime { noop_fold_lifetime(l, self) } @@ -523,28 +515,6 @@ pub fn noop_fold_attribute(at: Attribute, fld: &mut T) -> Option(es: SelfKind, fld: &mut T) - -> SelfKind { - match es { - SelfKind::Static | SelfKind::Value(_) => es, - SelfKind::Region(lifetime, m, ident) => { - SelfKind::Region(fld.fold_opt_lifetime(lifetime), m, ident) - } - SelfKind::Explicit(typ, ident) => { - SelfKind::Explicit(fld.fold_ty(typ), ident) - } - } -} - -pub fn noop_fold_explicit_self(Spanned {span, node}: ExplicitSelf, fld: &mut T) - -> ExplicitSelf { - Spanned { - node: fld.fold_explicit_self_kind(node), - span: fld.new_span(span) - } -} - - pub fn noop_fold_mac(Spanned {node, span}: Mac, fld: &mut T) -> Mac { Spanned { node: Mac_ { @@ -1096,7 +1066,7 @@ pub fn noop_fold_method_sig(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), + self_shortcut: sig.self_shortcut, unsafety: sig.unsafety, constness: sig.constness, decl: folder.fold_fn_decl(sig.decl) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fc62cee92fdbc..75f6762af18ee 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -17,7 +17,7 @@ use ast::Block; use ast::{BlockCheckMode, CaptureBy}; use ast::{Constness, Crate, CrateConfig}; use ast::{Decl, DeclKind, Defaultness}; -use ast::{EMPTY_CTXT, EnumDef, ExplicitSelf}; +use ast::{EMPTY_CTXT, EnumDef}; use ast::{Expr, ExprKind, RangeLimits}; use ast::{Field, FnDecl}; use ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; @@ -1310,7 +1310,7 @@ impl<'a> Parser<'a> { let ident = p.parse_ident()?; let mut generics = p.parse_generics()?; - let (explicit_self, d) = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{ + let (d, self_shortcut) = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{ // This is somewhat dubious; We don't want to allow // argument names to be left off if there is a // definition... @@ -1324,7 +1324,7 @@ impl<'a> Parser<'a> { decl: d, generics: generics, abi: abi, - explicit_self: explicit_self, + self_shortcut: self_shortcut, }; let body = match p.token { @@ -4616,25 +4616,19 @@ impl<'a> Parser<'a> { })) } - /// Parse the parameter list and result type of a function that may have a `self` parameter. - fn parse_fn_decl_with_self(&mut self, - parse_arg_fn: F) - -> PResult<'a, (ExplicitSelf, P)> - where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>, - { + /// Returns the parsed optional self argument and whether a self shortcut was used. + fn parse_self_arg(&mut self) -> PResult<'a, (Option, bool)> { let expect_ident = |this: &mut Self| match this.token { - token::Ident(ident) => { this.bump(); ident } // Preserve hygienic context. + // Preserve hygienic context. + token::Ident(ident) => { this.bump(); codemap::respan(this.last_span, ident) } _ => unreachable!() }; - self.expect(&token::OpenDelim(token::Paren))?; - // Parse optional self parameter of a method. // Only a limited set of initial token sequences is considered self parameters, anything // else is parsed as a normal function parameter list, so some lookahead is required. let eself_lo = self.span.lo; - let mut eself_mutbl = Mutability::Immutable; - let (eself, eself_ident_sp) = match self.token { + let (eself, eself_ident) = match self.token { token::BinOp(token::And) => { // &self // &mut self @@ -4643,30 +4637,26 @@ impl<'a> Parser<'a> { // ¬_self if self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); - (SelfKind::Region(None, Mutability::Immutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(None, Mutability::Immutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) && self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); self.bump(); - (SelfKind::Region(None, Mutability::Mutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(None, Mutability::Mutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_lifetime()) && self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); let lt = self.parse_lifetime()?; - (SelfKind::Region(Some(lt), Mutability::Immutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(Some(lt), Mutability::Immutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_lifetime()) && self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) && self.look_ahead(3, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); let lt = self.parse_lifetime()?; self.bump(); - (SelfKind::Region(Some(lt), Mutability::Mutable, expect_ident(self)), - self.last_span) + (SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self)) } else { - (SelfKind::Static, codemap::DUMMY_SP) + return Ok((None, false)); } } token::BinOp(token::Star) => { @@ -4678,15 +4668,15 @@ impl<'a> Parser<'a> { if self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); self.span_err(self.span, "cannot pass `self` by raw pointer"); - (SelfKind::Value(expect_ident(self)), self.last_span) + (SelfKind::Value(Mutability::Immutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_mutability()) && self.look_ahead(2, |t| t.is_keyword(keywords::SelfValue)) { self.bump(); self.bump(); self.span_err(self.span, "cannot pass `self` by raw pointer"); - (SelfKind::Value(expect_ident(self)), self.last_span) + (SelfKind::Value(Mutability::Immutable), expect_ident(self)) } else { - (SelfKind::Static, codemap::DUMMY_SP) + return Ok((None, false)); } } token::Ident(..) => { @@ -4694,64 +4684,72 @@ impl<'a> Parser<'a> { // self // self: TYPE let eself_ident = expect_ident(self); - let eself_ident_sp = self.last_span; if self.eat(&token::Colon) { - (SelfKind::Explicit(self.parse_ty_sum()?, eself_ident), eself_ident_sp) + let ty = self.parse_ty_sum()?; + (SelfKind::Explicit(ty, Mutability::Immutable), eself_ident) } else { - (SelfKind::Value(eself_ident), eself_ident_sp) + (SelfKind::Value(Mutability::Immutable), eself_ident) } } else if self.token.is_keyword(keywords::Mut) && self.look_ahead(1, |t| t.is_keyword(keywords::SelfValue)) { // mut self // mut self: TYPE - eself_mutbl = Mutability::Mutable; self.bump(); let eself_ident = expect_ident(self); - let eself_ident_sp = self.last_span; if self.eat(&token::Colon) { - (SelfKind::Explicit(self.parse_ty_sum()?, eself_ident), eself_ident_sp) + let ty = self.parse_ty_sum()?; + (SelfKind::Explicit(ty, Mutability::Mutable), eself_ident) } else { - (SelfKind::Value(eself_ident), eself_ident_sp) + (SelfKind::Value(Mutability::Mutable), eself_ident) } } else { - (SelfKind::Static, codemap::DUMMY_SP) + return Ok((None, false)); } } - _ => (SelfKind::Static, codemap::DUMMY_SP) + _ => return Ok((None, false)), }; - let mut eself = codemap::respan(mk_sp(eself_lo, self.last_span.hi), eself); + + let self_shortcut = if let SelfKind::Explicit(..) = eself { false } else { true }; + let eself = codemap::respan(mk_sp(eself_lo, self.last_span.hi), eself); + Ok((Some(Arg::from_self(eself, eself_ident)), self_shortcut)) + } + + /// Parse the parameter list and result type of a function that may have a `self` parameter. + fn parse_fn_decl_with_self(&mut self, + parse_arg_fn: F) + -> PResult<'a, (P, bool)> + where F: FnMut(&mut Parser<'a>) -> PResult<'a, Arg>, + { + self.expect(&token::OpenDelim(token::Paren))?; + + // Parse optional self argument + let (self_arg, self_shortcut) = self.parse_self_arg()?; // Parse the rest of the function parameter list. let sep = SeqSep::trailing_allowed(token::Comma); - let fn_inputs = match eself.node { - SelfKind::Static => { - eself.span = codemap::DUMMY_SP; - self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn) - } - SelfKind::Value(..) | SelfKind::Region(..) | SelfKind::Explicit(..) => { - if self.check(&token::CloseDelim(token::Paren)) { - vec![Arg::from_self(eself.clone(), eself_ident_sp, eself_mutbl)] - } else if self.check(&token::Comma) { - self.bump(); - let mut fn_inputs = vec![Arg::from_self(eself.clone(), eself_ident_sp, - eself_mutbl)]; - fn_inputs.append(&mut self.parse_seq_to_before_end( - &token::CloseDelim(token::Paren), sep, parse_arg_fn) - ); - fn_inputs - } else { - return self.unexpected(); - } + let fn_inputs = if let Some(self_arg) = self_arg { + if self.check(&token::CloseDelim(token::Paren)) { + vec![self_arg] + } else if self.eat(&token::Comma) { + let mut fn_inputs = vec![self_arg]; + fn_inputs.append(&mut self.parse_seq_to_before_end( + &token::CloseDelim(token::Paren), sep, parse_arg_fn) + ); + fn_inputs + } else { + return self.unexpected(); } + } else { + self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn) }; // Parse closing paren and return type. self.expect(&token::CloseDelim(token::Paren))?; - Ok((eself, P(FnDecl { + Ok((P(FnDecl { inputs: fn_inputs, output: self.parse_ret_ty()?, variadic: false - }))) + }), self_shortcut)) } // parse the |arg, arg| header on a lambda @@ -4944,15 +4942,13 @@ impl<'a> Parser<'a> { let (constness, unsafety, abi) = self.parse_fn_front_matter()?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| { - p.parse_arg() - })?; + let (decl, self_shortcut) = self.parse_fn_decl_with_self(|p| p.parse_arg())?; generics.where_clause = self.parse_where_clause()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; Ok((ident, inner_attrs, ast::ImplItemKind::Method(ast::MethodSig { generics: generics, abi: abi, - explicit_self: explicit_self, + self_shortcut: self_shortcut, unsafety: unsafety, constness: constness, decl: decl diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ebb4927d69c0b..cf0c0f584a6d5 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -12,7 +12,7 @@ pub use self::AnnNode::*; use abi::{self, Abi}; use ast::{self, TokenTree, BlockCheckMode, PatKind}; -use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; +use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::Attribute; use attr::ThinAttributesExt; use util::parser::AssocOp; @@ -382,13 +382,12 @@ pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, constness: ast::Constness, name: ast::Ident, - opt_explicit_self: Option<&ast::SelfKind>, generics: &ast::Generics) -> String { to_string(|s| { s.head("")?; s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name), - generics, opt_explicit_self, &ast::Visibility::Inherited)?; + generics, &ast::Visibility::Inherited)?; s.end()?; // Close the head box s.end() // Close the outer box }) @@ -416,10 +415,6 @@ pub fn lit_to_string(l: &ast::Lit) -> String { to_string(|s| s.print_literal(l)) } -pub fn explicit_self_to_string(explicit_self: &ast::SelfKind) -> String { - to_string(|s| s.print_explicit_self(explicit_self, ast::Mutability::Immutable).map(|_| {})) -} - pub fn variant_to_string(var: &ast::Variant) -> String { to_string(|s| s.print_variant(var)) } @@ -1005,8 +1000,7 @@ impl<'a> State<'a> { f.unsafety, &f.decl, None, - &generics, - None)?; + &generics)?; } ast::TyKind::Path(None, ref path) => { self.print_path(path, false, 0)?; @@ -1054,7 +1048,7 @@ impl<'a> State<'a> { self.print_fn(decl, ast::Unsafety::Normal, ast::Constness::NotConst, Abi::Rust, Some(item.ident), - generics, None, &item.vis)?; + generics, &item.vis)?; self.end()?; // end head-ibox word(&mut self.s, ";")?; self.end() // end the outer fn box @@ -1182,7 +1176,6 @@ impl<'a> State<'a> { abi, Some(item.ident), typarams, - None, &item.vis )?; word(&mut self.s, " ")?; @@ -1522,7 +1515,6 @@ impl<'a> State<'a> { m.abi, Some(ident), &m.generics, - None, vis) } @@ -2610,29 +2602,25 @@ impl<'a> State<'a> { self.end() // close enclosing cbox } - // Returns whether it printed anything - fn print_explicit_self(&mut self, - explicit_self: &ast::SelfKind, - mutbl: ast::Mutability) -> io::Result { - self.print_mutability(mutbl)?; - match *explicit_self { - ast::SelfKind::Static => { return Ok(false); } - ast::SelfKind::Value(_) => { - word(&mut self.s, "self")?; + fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) -> io::Result<()> { + match explicit_self.node { + SelfKind::Value(m) => { + self.print_mutability(m)?; + word(&mut self.s, "self") } - ast::SelfKind::Region(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") } - ast::SelfKind::Explicit(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, @@ -2642,7 +2630,6 @@ impl<'a> State<'a> { abi: abi::Abi, name: Option, generics: &ast::Generics, - opt_explicit_self: Option<&ast::SelfKind>, vis: &ast::Visibility) -> io::Result<()> { self.print_fn_header_info(unsafety, constness, abi, vis)?; @@ -2651,21 +2638,14 @@ impl<'a> State<'a> { self.print_ident(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: &ast::FnDecl, - _: Option<&ast::SelfKind>, - is_closure: bool) -> io::Result<()> { - self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, is_closure)) - } - - pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl, - opt_explicit_self: Option<&ast::SelfKind>) + pub fn print_fn_args_and_ret(&mut self, decl: &ast::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, ", ...")?; } @@ -2679,7 +2659,7 @@ impl<'a> State<'a> { decl: &ast::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 ast::FunctionRetTy::Default(..) = decl.output { @@ -2929,17 +2909,14 @@ impl<'a> State<'a> { match input.ty.node { ast::TyKind::Infer if is_closure => self.print_pat(&input.pat)?, _ => { - let (mutbl, invalid) = match input.pat.node { - PatKind::Ident(ast::BindingMode::ByValue(mutbl), ident, _) | - PatKind::Ident(ast::BindingMode::ByRef(mutbl), ident, _) => { - (mutbl, ident.node.name == keywords::Invalid.name()) - } - _ => (ast::Mutability::Immutable, false) - }; - if let Some(eself) = input.to_self() { - self.print_explicit_self(&eself.node, mutbl)?; + 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, ":")?; @@ -2980,8 +2957,7 @@ impl<'a> State<'a> { unsafety: ast::Unsafety, decl: &ast::FnDecl, name: Option, - generics: &ast::Generics, - opt_explicit_self: Option<&ast::SelfKind>) + generics: &ast::Generics) -> io::Result<()> { self.ibox(INDENT_UNIT)?; if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() { @@ -3002,7 +2978,6 @@ impl<'a> State<'a> { abi, name, &generics, - opt_explicit_self, &ast::Visibility::Inherited)?; self.end() } @@ -3126,8 +3101,7 @@ mod tests { let generics = ast::Generics::default(); assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal, ast::Constness::NotConst, - abba_ident, - None, &generics), + abba_ident, &generics), "fn abba()"); } diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs index e692ec4452cdd..919dd84b11799 100644 --- a/src/libsyntax/util/node_count.rs +++ b/src/libsyntax/util/node_count.rs @@ -129,10 +129,6 @@ impl<'v> Visitor<'v> for NodeCounter { self.count += 1; walk_lifetime_def(self, lifetime) } - fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) { - self.count += 1; - walk_explicit_self(self, es) - } fn visit_mac(&mut self, _mac: &'v Mac) { self.count += 1; walk_mac(self, _mac) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index f50a480e5e55a..c506921003717 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -99,9 +99,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_mac(&mut self, _mac: &'v Mac) { panic!("visit_mac disabled by default"); // NB: see note about macros above. @@ -196,24 +193,6 @@ pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut 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 { - SelfKind::Static => {}, - SelfKind::Value(ident) => { - visitor.visit_ident(explicit_self.span, ident) - } - SelfKind::Region(ref opt_lifetime, _, ident) => { - visitor.visit_ident(explicit_self.span, ident); - walk_list!(visitor, visit_lifetime, opt_lifetime); - } - SelfKind::Explicit(ref typ, ident) => { - visitor.visit_ident(explicit_self.span, ident); - visitor.visit_ty(typ) - } - } -} - pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v PolyTraitRef, _modifier: &'v TraitBoundModifier) @@ -553,7 +532,6 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, } FnKind::Method(_, ref sig, _) => { visitor.visit_generics(&sig.generics); - visitor.visit_explicit_self(&sig.explicit_self); } FnKind::Closure => {} } @@ -578,7 +556,6 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai walk_list!(visitor, visit_expr, default); } TraitItemKind::Method(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/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 20fb4bf32ccb7..6ecbdb765fac8 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -197,7 +197,7 @@ use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::ext::base::{ExtCtxt, Annotatable}; use syntax::ext::build::AstBuilder; -use syntax::codemap::{self, DUMMY_SP}; +use syntax::codemap::{self, respan, DUMMY_SP}; use syntax::codemap::Span; use syntax::errors::Handler; use syntax::util::move_map::MoveMap; @@ -806,25 +806,21 @@ impl<'a> MethodDef<'a> { trait_: &TraitDef, type_ident: Ident, generics: &Generics) - -> (ast::ExplicitSelf, Vec>, Vec>, Vec<(Ident, P)>) { + -> (Option, Vec>, Vec>, Vec<(Ident, P)>) { let mut self_args = Vec::new(); let mut nonself_args = Vec::new(); let mut arg_tys = Vec::new(); let mut nonstatic = false; - let ast_explicit_self = match self.explicit_self { - Some(ref self_ptr) => { - let (self_expr, explicit_self) = - ty::get_explicit_self(cx, trait_.span, self_ptr); + let ast_explicit_self = self.explicit_self.as_ref().map(|self_ptr| { + let (self_expr, explicit_self) = ty::get_explicit_self(cx, trait_.span, self_ptr); - self_args.push(self_expr); - nonstatic = true; + self_args.push(self_expr); + nonstatic = true; - explicit_self - } - None => codemap::respan(trait_.span, ast::SelfKind::Static), - }; + explicit_self + }); for (i, ty) in self.args.iter().enumerate() { let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics); @@ -857,24 +853,22 @@ impl<'a> MethodDef<'a> { type_ident: Ident, generics: &Generics, abi: Abi, - explicit_self: ast::ExplicitSelf, + explicit_self: Option, arg_types: Vec<(Ident, P)> , body: P) -> ast::ImplItem { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); - let self_arg = match explicit_self.node { - ast::SelfKind::Static => None, - // creating fresh self id - _ => Some(ast::Arg::from_self(explicit_self.clone(), trait_.span, - ast::Mutability::Immutable)), - }; + // derive doesn't generate `self: TYPE` forms + let self_shortcut = explicit_self.is_some(); let args = { - let args = arg_types.into_iter().map(|(name, ty)| { - cx.arg(trait_.span, name, ty) - }); - self_arg.into_iter().chain(args).collect() + let self_args = explicit_self.map(|explicit_self| { + ast::Arg::from_self(explicit_self, respan(trait_.span, keywords::SelfValue.ident())) + }); + let nonself_args = arg_types.into_iter() + .map(|(name, ty)| cx.arg(trait_.span, name, ty)); + self_args.into_iter().chain(nonself_args).collect() }; let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); @@ -900,7 +894,7 @@ impl<'a> MethodDef<'a> { node: ast::ImplItemKind::Method(ast::MethodSig { generics: fn_generics, abi: abi, - explicit_self: explicit_self, + self_shortcut: self_shortcut, unsafety: unsafety, constness: ast::Constness::NotConst, decl: fn_decl diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index e31d45d91a59f..b581f5267eaac 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -15,11 +15,10 @@ pub use self::PtrTy::*; pub use self::Ty::*; use syntax::ast; -use syntax::ast::{Expr,Generics,Ident}; +use syntax::ast::{Expr, Generics, Ident, SelfKind}; use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::codemap::{Span,respan}; -use syntax::parse::token::keywords; use syntax::ptr::P; /// The types of pointers @@ -258,12 +257,11 @@ impl<'a> LifetimeBounds<'a> { pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option) -> (P, ast::ExplicitSelf) { - // this constructs a fresh `self` path, which will match the fresh `self` binding - // created below. + // this constructs a fresh `self` path let self_path = cx.expr_self(span); match *self_ptr { None => { - (self_path, respan(span, ast::SelfKind::Value(keywords::SelfValue.ident()))) + (self_path, respan(span, SelfKind::Value(ast::Mutability::Immutable))) } Some(ref ptr) => { let self_ty = respan( @@ -271,7 +269,7 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option) match *ptr { Borrowed(ref lt, mutbl) => { let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name)); - ast::SelfKind::Region(lt, mutbl, keywords::SelfValue.ident()) + SelfKind::Region(lt, mutbl) } Raw(_) => cx.span_bug(span, "attempted to use *self in deriving definition") });