]> git.lizzy.rs Git - rust.git/commitdiff
Remove ExplicitSelf from AST
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sun, 6 Mar 2016 12:54:44 +0000 (15:54 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Wed, 25 May 2016 18:55:04 +0000 (21:55 +0300)
15 files changed:
src/librustc/hir/lowering.rs
src/librustc/hir/mod.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_typeck/astconv.rs
src/libsyntax/ast.rs
src/libsyntax/ext/expand.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/util/node_count.rs
src/libsyntax/visit.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/generic/ty.rs

index 28506fd20fe53bc3884290069474916c1a39a23f..48b4b867ee2d947c520409f115cffa431b420672 100644 (file)
@@ -788,10 +788,10 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
 
     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");
                 }
                 _ => {}
index 39a6ec9f3af270ed26329079b3a0e9c235ad2211..b9f0f6ab5d56d530eaa9ef36471452de0fc66a23 100644 (file)
@@ -1175,6 +1175,9 @@ pub struct FnDecl {
 }
 
 impl FnDecl {
+    pub fn get_self(&self) -> Option<ExplicitSelf> {
+        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)
     }
index 0801f8f4ac7ef8bc63e5d18325b6fc2fb89c3210..94f17ea779ac8827b86c9176de71b52057d364c1 100644 (file)
@@ -1043,11 +1043,6 @@ fn visit_lifetime_def(&mut self, lt: &ast::LifetimeDef) {
         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);
index 28994e1a7c48d50d82f6c807784a0b3bee4c5989..cc7fa54bd0a5ef6f7959f9b6a2108f6e2f4c51d8 100644 (file)
@@ -167,7 +167,6 @@ fn check_variant(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics
     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 @@ fn check_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generic
     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) { }
index f56b22f924891bf0dca827a52e473e273b91b82e..e0243bf4fa690eeae1171b56973d5dc03676daf9 100644 (file)
@@ -35,7 +35,7 @@
 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 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent_ref: &mut Module<
                     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),
index 1df12b63e0a50e76a12f3fc9beda37f649bdde03..fc1abb56d5abc61631dc42a8f7decb9d8b4136fa 100644 (file)
@@ -1833,8 +1833,7 @@ fn ty_of_method_or_bare_fn<'a>(&self,
         // 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);
index d9409d3bbd9213bf3fe842c69a316b6d67d30153..65bc486372b624ef4e094e59e29734bdee51f58d 100644 (file)
@@ -1387,7 +1387,8 @@ pub struct MethodSig {
     pub abi: Abi,
     pub decl: P<FnDecl>,
     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<Lifetime>, Mutability, Ident),
+    Region(Option<Lifetime>, Mutability),
     /// `self: TYPE`, `mut self: TYPE`
-    Explicit(P<Ty>, Ident),
+    Explicit(P<Ty>, Mutability),
 }
 
 pub type ExplicitSelf = Spanned<SelfKind>;
 
 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<ExplicitSelf> {
-        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<ExplicitSelf> {
+        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,
index f243706eecb8036334960f80ea07e6a46aa0c6bd..d90389bef7f792376cea5452de51a10e4b81e596 100644 (file)
@@ -1128,7 +1128,7 @@ fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
     (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
index 2c325080c0c2681c41447856ead46f4099c1d054..a8f048c6c4ebe039e6ba25a7a951f962e041505f 100644 (file)
@@ -179,14 +179,6 @@ fn fold_mac(&mut self, _mac: Mac) -> Mac {
         // 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<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attr
     })
 }
 
-pub fn noop_fold_explicit_self_kind<T: Folder>(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<T: Folder>(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<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac {
     Spanned {
         node: Mac_ {
@@ -1096,7 +1066,7 @@ 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),
+        self_shortcut: sig.self_shortcut,
         unsafety: sig.unsafety,
         constness: sig.constness,
         decl: folder.fold_fn_decl(sig.decl)
index fc62cee92fdbc5948b2dec120236b7125c927129..75f6762af18ee379c651511c9be35a101817a21e 100644 (file)
@@ -17,7 +17,7 @@
 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 @@ pub fn parse_trait_items(&mut self) -> PResult<'a,  Vec<TraitItem>> {
                 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 @@ pub fn parse_trait_items(&mut self) -> PResult<'a,  Vec<TraitItem>> {
                     decl: d,
                     generics: generics,
                     abi: abi,
-                    explicit_self: explicit_self,
+                    self_shortcut: self_shortcut,
                 };
 
                 let body = match p.token {
@@ -4616,25 +4616,19 @@ pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>>
         }))
     }
 
-    /// Parse the parameter list and result type of a function that may have a `self` parameter.
-    fn parse_fn_decl_with_self<F>(&mut self,
-                                  parse_arg_fn: F)
-                                  -> PResult<'a, (ExplicitSelf, P<FnDecl>)>
-        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<Arg>, 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 @@ fn parse_fn_decl_with_self<F>(&mut self,
                 // &not_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 @@ fn parse_fn_decl_with_self<F>(&mut self,
                 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 @@ fn parse_fn_decl_with_self<F>(&mut self,
                     // 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<F>(&mut self,
+                                  parse_arg_fn: F)
+                                  -> PResult<'a, (P<FnDecl>, 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 @@ fn parse_impl_method(&mut self, vis: &Visibility)
             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
index ebb4927d69c0b7cfad3d5f80bc1c509ca2fc84c6..cf0c0f584a6d58e6bdceb9632d636c8e8467da95 100644 (file)
@@ -12,7 +12,7 @@
 
 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 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
                                  f.unsafety,
                                  &f.decl,
                                  None,
-                                 &generics,
-                                 None)?;
+                                 &generics)?;
             }
             ast::TyKind::Path(None, ref path) => {
                 self.print_path(path, false, 0)?;
@@ -1054,7 +1048,7 @@ pub fn print_foreign_item(&mut self,
                 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 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                     abi,
                     Some(item.ident),
                     typarams,
-                    None,
                     &item.vis
                 )?;
                 word(&mut self.s, " ")?;
@@ -1522,7 +1515,6 @@ pub fn print_method_sig(&mut self,
                       m.abi,
                       Some(ident),
                       &m.generics,
-                      None,
                       vis)
     }
 
@@ -2610,29 +2602,25 @@ fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> {
         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<bool> {
-        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 @@ pub fn print_fn(&mut self,
                     abi: abi::Abi,
                     name: Option<ast::Ident>,
                     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 @@ pub fn print_fn(&mut self,
             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 @@ pub fn print_fn_block_args(
             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 @@ pub fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) -> io::Result<()
         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 @@ pub fn print_ty_fn(&mut self,
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
                        name: Option<ast::Ident>,
-                       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 @@ pub fn print_ty_fn(&mut self,
                       abi,
                       name,
                       &generics,
-                      opt_explicit_self,
                       &ast::Visibility::Inherited)?;
         self.end()
     }
@@ -3126,8 +3101,7 @@ fn test_fun_to_string() {
         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()");
     }
 
index e692ec4452cdd4ed4cb448e80f3b75502fbf7ab3..919dd84b117993292342e07a45ea923a77edeabf 100644 (file)
@@ -129,10 +129,6 @@ fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
         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)
index f50a480e5e55a538081e4e1587717b4a015fd20f..c5069210037173c69ea0cc3015c3fbe078510b27 100644 (file)
@@ -99,9 +99,6 @@ fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
     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);
         }
index 20fb4bf32ccb7671687348f3359779802d085269..6ecbdb765fac86363bd8d82ccd8843533f2c3529 100644 (file)
 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 @@ fn split_self_nonself_args(&self,
                                trait_: &TraitDef,
                                type_ident: Ident,
                                generics: &Generics)
-        -> (ast::ExplicitSelf, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
+        -> (Option<ast::ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
 
         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 @@ fn create_method(&self,
                      type_ident: Ident,
                      generics: &Generics,
                      abi: Abi,
-                     explicit_self: ast::ExplicitSelf,
+                     explicit_self: Option<ast::ExplicitSelf>,
                      arg_types: Vec<(Ident, P<ast::Ty>)> ,
                      body: P<Expr>) -> 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 @@ fn create_method(&self,
             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
index e31d45d91a59f4ef8baf5feb1dad48180ed11b0a..b581f5267eaac221ccfa0cb708b7d0d45d19b13a 100644 (file)
 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 @@ pub fn to_generics(&self,
 
 pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
     -> (P<Expr>, 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<PtrTy>)
                 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")
                 });