diff options
| author | bors <bors@rust-lang.org> | 2014-01-27 09:31:44 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-01-27 09:31:44 -0800 |
| commit | d6d7812da841ddedf6c765eebb655be9866956ce (patch) | |
| tree | 462e190485176d8089f3212a8acdfe783e447fbd /src/libsyntax | |
| parent | be974bf499a977530703fd62b3794a9377b6cbc4 (diff) | |
| parent | 15ba0c310a2bfe2ab69670d0d87529a29d527973 (diff) | |
| download | rust-d6d7812da841ddedf6c765eebb655be9866956ce.tar.gz rust-d6d7812da841ddedf6c765eebb655be9866956ce.zip | |
auto merge of #11595 : eddyb/rust/env-et-self-no-more, r=nikomatsakis
Non-exhaustive change list: * `self` is now present in argument lists (modulo type-checking code I don't trust myself to refactor) * methods have the same calling convention as bare functions (including the self argument) * the env param is gone from all bare functions (and methods), only used by closures and `proc`s * bare functions can only be coerced to closures and `proc`s if they are statically resolved, as they now require creating a wrapper specific to that function, to avoid indirect wrappers (equivalent to `impl<..Args, Ret> Fn<..Args, Ret> for fn(..Args) -> Ret`) that might not be optimizable by LLVM and don't work for `proc`s * refactored some `trans::closure` code, leading to the removal of `trans::glue::make_free_glue` and `ty_opaque_closure_ptr`
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 51 | ||||
| -rw-r--r-- | src/libsyntax/ast_map.rs | 27 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 41 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/ty.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 70 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 53 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 7 |
11 files changed, 135 insertions, 148 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 03b7f1891a1..10b1aad8138 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -10,10 +10,11 @@ // The Rust abstract syntax tree. -use codemap::{Span, Spanned}; +use codemap::{Span, Spanned, DUMMY_SP}; use abi::AbiSet; +use ast_util; use opt_vec::OptVec; -use parse::token::{interner_get, str_to_ident}; +use parse::token::{interner_get, str_to_ident, special_idents}; use std::cell::RefCell; use std::hashmap::HashMap; @@ -236,7 +237,6 @@ pub enum MethodProvenance { pub enum Def { DefFn(DefId, Purity), DefStaticMethod(/* method */ DefId, MethodProvenance, Purity), - DefSelf(NodeId, bool /* is_mutbl */), DefSelfTy(/* trait id */ NodeId), DefMod(DefId), DefForeignMod(DefId), @@ -357,7 +357,7 @@ pub enum BindingMode { pub enum Pat_ { PatWild, PatWildMulti, - // A pat_ident may either be a new bound variable, + // A PatIdent may either be a new bound variable, // or a nullary enum (in which case the second field // is None). // In the nullary enum case, the parser can't determine @@ -366,7 +366,7 @@ pub enum Pat_ { // set (of "pat_idents that refer to nullary enums") PatIdent(BindingMode, Path, Option<@Pat>), PatEnum(Path, Option<~[@Pat]>), /* "none" means a * pattern where - * we don't bind the fields to names */ + * we don't bind the fields to names */ PatStruct(Path, ~[FieldPat], bool), PatTup(~[@Pat]), PatUniq(@Pat), @@ -374,7 +374,7 @@ pub enum Pat_ { PatLit(@Expr), PatRange(@Expr, @Expr), // [a, b, ..i, y, z] is represented as - // pat_vec(~[a, b], Some(i), ~[y, z]) + // PatVec(~[a, b], Some(i), ~[y, z]) PatVec(~[@Pat], Option<@Pat>, ~[@Pat]) } @@ -526,7 +526,7 @@ pub struct Expr { impl Expr { pub fn get_callee_id(&self) -> Option<NodeId> { match self.node { - ExprMethodCall(callee_id, _, _, _, _, _) | + ExprMethodCall(callee_id, _, _, _, _) | ExprIndex(callee_id, _, _) | ExprBinary(callee_id, _, _, _) | ExprAssignOp(callee_id, _, _, _) | @@ -550,7 +550,7 @@ pub enum Expr_ { ExprBox(@Expr, @Expr), ExprVec(~[@Expr], Mutability), ExprCall(@Expr, ~[@Expr], CallSugar), - ExprMethodCall(NodeId, @Expr, Ident, ~[P<Ty>], ~[@Expr], CallSugar), + ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr], CallSugar), ExprTup(~[@Expr]), ExprBinary(NodeId, BinOp, @Expr, @Expr), ExprUnary(NodeId, UnOp, @Expr), @@ -579,8 +579,6 @@ pub enum Expr_ { /// of a function call. ExprPath(Path), - /// The special identifier `self`. - ExprSelf, ExprAddrOf(Mutability, @Expr), ExprBreak(Option<Name>), ExprAgain(Option<Name>), @@ -783,7 +781,7 @@ pub enum IntTy { impl ToStr for IntTy { fn to_str(&self) -> ~str { - ::ast_util::int_ty_to_str(*self) + ast_util::int_ty_to_str(*self) } } @@ -798,7 +796,7 @@ pub enum UintTy { impl ToStr for UintTy { fn to_str(&self) -> ~str { - ::ast_util::uint_ty_to_str(*self) + ast_util::uint_ty_to_str(*self) } } @@ -810,7 +808,7 @@ pub enum FloatTy { impl ToStr for FloatTy { fn to_str(&self) -> ~str { - ::ast_util::float_ty_to_str(*self) + ast_util::float_ty_to_str(*self) } } @@ -886,7 +884,7 @@ pub enum Ty_ { TyTup(~[P<Ty>]), TyPath(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above TyTypeof(@Expr), - // ty_infer means the type should be inferred instead of it having been + // TyInfer means the type should be inferred instead of it having been // specified. This should only appear at the "top level" of a type and not // nested in one. TyInfer, @@ -917,6 +915,26 @@ pub struct Arg { id: NodeId, } +impl Arg { + pub fn new_self(span: Span, mutability: Mutability) -> Arg { + let path = ast_util::ident_to_path(span, special_idents::self_); + Arg { + // HACK(eddyb) fake type for the self argument. + ty: P(Ty { + id: DUMMY_NODE_ID, + node: TyInfer, + span: DUMMY_SP, + }), + pat: @Pat { + id: DUMMY_NODE_ID, + node: PatIdent(BindByValue(mutability), path, None), + span: span + }, + id: DUMMY_NODE_ID + } + } +} + #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct FnDecl { inputs: ~[Arg], @@ -952,10 +970,10 @@ pub enum RetStyle { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum ExplicitSelf_ { SelfStatic, // no self - SelfValue(Mutability), // `self`, `mut self` + SelfValue, // `self` SelfRegion(Option<Lifetime>, Mutability), // `&'lt self`, `&'lt mut self` SelfBox, // `@self` - SelfUniq(Mutability) // `~self`, `mut ~self` + SelfUniq // `~self` } pub type ExplicitSelf = Spanned<ExplicitSelf_>; @@ -971,7 +989,6 @@ pub struct Method { body: P<Block>, id: NodeId, span: Span, - self_id: NodeId, vis: Visibility, } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 49bea6a33a9..bb66d620d29 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -17,7 +17,6 @@ use diagnostic::SpanHandler; use fold::Folder; use fold; use parse::token::{get_ident_interner, IdentInterner}; -use parse::token::special_idents; use print::pprust; use util::small_vector::SmallVector; @@ -163,10 +162,7 @@ pub enum Node { NodeExpr(@Expr), NodeStmt(@Stmt), NodeArg(@Pat), - // HACK(eddyb) should always be a pattern, but `self` is not, and thus it - // is identified only by an ident and no span is available. In all other - // cases, node_span will return the proper span (required by borrowck). - NodeLocal(Ident, Option<@Pat>), + NodeLocal(@Pat), NodeBlock(P<Block>), /// NodeStructCtor represents a tuple struct. @@ -246,10 +242,6 @@ impl<F> Ctx<F> { let mut map = self.map.map.borrow_mut(); map.get().insert(id as uint, node); } - - fn map_self(&self, m: @Method) { - self.insert(m.self_id, NodeLocal(special_idents::self_, None)); - } } impl<F: FoldOps> Folder for Ctx<F> { @@ -285,7 +277,6 @@ impl<F: FoldOps> Folder for Ctx<F> { let impl_did = ast_util::local_def(i.id); for &m in ms.iter() { self.insert(m.id, NodeMethod(m, impl_did, p)); - self.map_self(m); } } @@ -332,7 +323,6 @@ impl<F: FoldOps> Folder for Ctx<F> { } Provided(m) => { self.insert(m.id, NodeTraitMethod(@Provided(m), d_id, p)); - self.map_self(m); } } } @@ -348,9 +338,9 @@ impl<F: FoldOps> Folder for Ctx<F> { fn fold_pat(&mut self, pat: @Pat) -> @Pat { let pat = fold::noop_fold_pat(pat, self); match pat.node { - PatIdent(_, ref path, _) => { + PatIdent(..) => { // Note: this is at least *potentially* a pattern... - self.insert(pat.id, NodeLocal(ast_util::path_to_ident(path), Some(pat))); + self.insert(pat.id, NodeLocal(pat)); } _ => {} } @@ -467,7 +457,6 @@ pub fn map_decoded_item<F: 'static + FoldOps>(diag: @SpanHandler, NodeMethod(m, impl_did, @path) }; cx.insert(m.id, entry); - cx.map_self(m); } } @@ -525,8 +514,8 @@ pub fn node_id_to_str(map: Map, id: NodeId, itr: @IdentInterner) -> ~str { Some(NodeArg(pat)) => { format!("arg {} (id={})", pprust::pat_to_str(pat, itr), id) } - Some(NodeLocal(ident, _)) => { - format!("local (id={}, name={})", id, itr.get(ident.name)) + Some(NodeLocal(pat)) => { + format!("local {} (id={})", pprust::pat_to_str(pat, itr), id) } Some(NodeBlock(block)) => { format!("block {} (id={})", pprust::block_to_str(block, itr), id) @@ -559,11 +548,7 @@ pub fn node_span(items: Map, id: ast::NodeId) -> Span { Some(NodeVariant(variant, _, _)) => variant.span, Some(NodeExpr(expr)) => expr.span, Some(NodeStmt(stmt)) => stmt.span, - Some(NodeArg(pat)) => pat.span, - Some(NodeLocal(_, pat)) => match pat { - Some(pat) => pat.span, - None => fail!("node_span: cannot get span from NodeLocal (likely `self`)") - }, + Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span, Some(NodeBlock(block)) => block.span, Some(NodeStructCtor(_, item, _)) => item.span, Some(NodeCalleeScope(expr)) => expr.span, diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index d3504f8d204..405de5c5542 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -60,19 +60,19 @@ pub fn variant_def_ids(d: Def) -> Option<(DefId, DefId)> { pub fn def_id_of_def(d: Def) -> DefId { match d { - DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) | - DefForeignMod(id) | DefStatic(id, _) | - DefVariant(_, id, _) | DefTy(id) | DefTyParam(id, _) | - DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => { - id - } - DefArg(id, _) | DefLocal(id, _) | DefSelf(id, _) | DefSelfTy(id) - | DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id) - | DefTyParamBinder(id) | DefLabel(id) => { - local_def(id) - } + DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) | + DefForeignMod(id) | DefStatic(id, _) | + DefVariant(_, id, _) | DefTy(id) | DefTyParam(id, _) | + DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => { + id + } + DefArg(id, _) | DefLocal(id, _) | DefSelfTy(id) + | DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id) + | DefTyParamBinder(id) | DefLabel(id) => { + local_def(id) + } - DefPrimTy(_) => fail!() + DefPrimTy(_) => fail!() } } @@ -292,16 +292,6 @@ pub fn struct_field_visibility(field: ast::StructField) -> Visibility { } } -/* True if d is either a def_self, or a chain of def_upvars - referring to a def_self */ -pub fn is_self(d: ast::Def) -> bool { - match d { - DefSelf(..) => true, - DefUpvar(_, d, _, _) => is_self(*d), - _ => false - } -} - /// Maps a binary operator to its precedence pub fn operator_prec(op: ast::BinOp) -> uint { match op { @@ -504,11 +494,8 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> { self.operation.visit_id(node_id); match *function_kind { - visit::FkItemFn(_, generics, _, _) => { - self.visit_generics_helper(generics) - } - visit::FkMethod(_, generics, method) => { - self.operation.visit_id(method.self_id); + visit::FkItemFn(_, generics, _, _) | + visit::FkMethod(_, generics, _) => { self.visit_generics_helper(generics) } visit::FkFnBlock => {} diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 3b2cc4ca6ed..3b43c96a184 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -18,6 +18,7 @@ use ext::quote::rt::*; use fold::Folder; use opt_vec; use opt_vec::OptVec; +use parse::token::special_idents; pub struct Field { ident: ast::Ident, @@ -478,7 +479,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr_path(self.path_ident(span, id)) } fn expr_self(&self, span: Span) -> @ast::Expr { - self.expr(span, ast::ExprSelf) + self.expr_ident(span, special_idents::self_) } fn expr_binary(&self, sp: Span, op: ast::BinOp, @@ -523,9 +524,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn expr_method_call(&self, span: Span, expr: @ast::Expr, ident: ast::Ident, - args: ~[@ast::Expr]) -> @ast::Expr { - self.expr(span, - ast::ExprMethodCall(ast::DUMMY_NODE_ID, expr, ident, ~[], args, ast::NoSugar)) + mut args: ~[@ast::Expr]) -> @ast::Expr { + args.unshift(expr); + self.expr(span, ast::ExprMethodCall(ast::DUMMY_NODE_ID, ident, ~[], args, ast::NoSugar)) } fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr { self.expr(b.span, ast::ExprBlock(b)) diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 1f778779fbd..e1fb80049e0 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -551,9 +551,14 @@ impl<'a> MethodDef<'a> { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(trait_.cx, trait_.span, type_ident, generics); + let self_arg = match explicit_self.node { + ast::SelfStatic => None, + _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable)) + }; let args = arg_types.move_iter().map(|(name, ty)| { trait_.cx.arg(trait_.span, name, ty) - }).collect(); + }); + let args = self_arg.move_iter().chain(args).collect(); let ret_type = self.get_ret_ty(trait_, generics, type_ident); @@ -578,7 +583,6 @@ impl<'a> MethodDef<'a> { body: body_block, id: ast::DUMMY_NODE_ID, span: trait_.span, - self_id: ast::DUMMY_NODE_ID, vis: ast::Inherited, } } diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs index c2b32b45ce4..b22dcfe0da2 100644 --- a/src/libsyntax/ext/deriving/ty.rs +++ b/src/libsyntax/ext/deriving/ty.rs @@ -244,13 +244,13 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>) let self_path = cx.expr_self(span); match *self_ptr { None => { - (self_path, respan(span, ast::SelfValue(ast::MutImmutable))) + (self_path, respan(span, ast::SelfValue)) } Some(ref ptr) => { let self_ty = respan( span, match *ptr { - Send => ast::SelfUniq(ast::MutImmutable), + Send => ast::SelfUniq, Managed => ast::SelfBox, Borrowed(ref lt, mutbl) => { let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s))); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 7a86dd6e4ce..c739fb911ba 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -306,9 +306,7 @@ pub trait Folder { fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ { match *es { - SelfStatic | SelfValue(_) | SelfUniq(_) | SelfBox => { - *es - } + SelfStatic | SelfValue | SelfUniq | SelfBox => *es, SelfRegion(ref lifetime, m) => { SelfRegion(fold_opt_lifetime(lifetime, self), m) } @@ -666,7 +664,6 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method { body: folder.fold_block(m.body), id: folder.new_id(m.id), span: folder.new_span(m.span), - self_id: folder.new_id(m.self_id), vis: m.vis } } @@ -737,10 +734,9 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr { args.map(|&x| folder.fold_expr(x)), blk) } - ExprMethodCall(callee_id, f, i, ref tps, ref args, blk) => { + ExprMethodCall(callee_id, i, ref tps, ref args, blk) => { ExprMethodCall( folder.new_id(callee_id), - folder.fold_expr(f), folder.fold_ident(i), tps.map(|&x| folder.fold_ty(x)), args.map(|&x| folder.fold_expr(x)), @@ -811,7 +807,6 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr { folder.fold_expr(er)) } ExprPath(ref pth) => ExprPath(folder.fold_path(pth)), - ExprSelf => ExprSelf, ExprLogLevel => ExprLogLevel, ExprBreak(opt_ident) => ExprBreak(opt_ident), ExprAgain(opt_ident) => ExprAgain(opt_ident), diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 1204cbc2eea..61c80919b6e 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -31,8 +31,8 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::Expr) -> bool { | ast::ExprForLoop(..) | ast::ExprCall(_, _, ast::DoSugar) | ast::ExprCall(_, _, ast::ForSugar) - | ast::ExprMethodCall(_, _, _, _, _, ast::DoSugar) - | ast::ExprMethodCall(_, _, _, _, _, ast::ForSugar) => false, + | ast::ExprMethodCall(_, _, _, _, ast::DoSugar) + | ast::ExprMethodCall(_, _, _, _, ast::ForSugar) => false, _ => true } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e110ebae093..17590ccf523 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -27,8 +27,8 @@ use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast, ExprDoBody}; use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex}; use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac}; -use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc, ExprRepeat}; -use ast::{ExprRet, ExprSelf, ExprStruct, ExprTup, ExprUnary}; +use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc}; +use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; use ast::{ExprVec, ExprVstore, ExprVstoreSlice, ExprVstoreBox}; use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, ExternFn, Field, FnDecl}; use ast::{ExprVstoreUniq, Onceness, Once, Many}; @@ -1093,7 +1093,6 @@ impl Parser { body: body, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - self_id: ast::DUMMY_NODE_ID, vis: vis, }) } @@ -1687,13 +1686,9 @@ impl Parser { ExprCall(f, args, sugar) } - pub fn mk_method_call(&mut self, - rcvr: @Expr, - ident: Ident, - tps: ~[P<Ty>], - args: ~[@Expr], + fn mk_method_call(&mut self, ident: Ident, tps: ~[P<Ty>], args: ~[@Expr], sugar: CallSugar) -> ast::Expr_ { - ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar) + ExprMethodCall(ast::DUMMY_NODE_ID, ident, tps, args, sugar) } pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ { @@ -1794,7 +1789,8 @@ impl Parser { return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock)); } else if self.eat_keyword(keywords::Self) { - ex = ExprSelf; + let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_); + ex = ExprPath(path); hi = self.span.hi; } else if self.eat_keyword(keywords::If) { return self.parse_if_expr(); @@ -1993,7 +1989,7 @@ impl Parser { // expr.f() method call match self.token { token::LPAREN => { - let es = self.parse_unspanned_seq( + let mut es = self.parse_unspanned_seq( &token::LPAREN, &token::RPAREN, seq_sep_trailing_disallowed(token::COMMA), @@ -2001,7 +1997,8 @@ impl Parser { ); hi = self.span.hi; - let nd = self.mk_method_call(e, i, tys, es, NoSugar); + es.unshift(e); + let nd = self.mk_method_call(i, tys, es, NoSugar); e = self.mk_expr(lo, hi, nd); } _ => { @@ -2569,16 +2566,15 @@ impl Parser { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); - let args = vec::append((*args).clone(), [last_arg]); + let args = vec::append_one((*args).clone(), last_arg); self.mk_expr(lo, block.span.hi, ExprCall(f, args, sugar)) } - ExprMethodCall(_, f, i, ref tps, ref args, NoSugar) => { + ExprMethodCall(_, i, ref tps, ref args, NoSugar) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); - let args = vec::append((*args).clone(), [last_arg]); - let method_call = self.mk_method_call(f, - i, + let args = vec::append_one((*args).clone(), last_arg); + let method_call = self.mk_method_call(i, (*tps).clone(), args, sugar); @@ -2588,10 +2584,9 @@ impl Parser { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); - let method_call = self.mk_method_call(f, - i, + let method_call = self.mk_method_call(i, (*tps).clone(), - ~[last_arg], + ~[f, last_arg], sugar); self.mk_expr(lo, block.span.hi, method_call) } @@ -3712,6 +3707,7 @@ impl Parser { // A bit of complexity and lookahead is needed here in order to be // backwards compatible. let lo = self.span.lo; + let mut mutbl_self = MutImmutable; let explicit_self = match self.token { token::BINOP(token::AND) => { maybe_parse_borrowed_explicit_self(self) @@ -3720,57 +3716,60 @@ impl Parser { maybe_parse_explicit_self(SelfBox, self) } token::TILDE => { - maybe_parse_explicit_self(SelfUniq(MutImmutable), self) + maybe_parse_explicit_self(SelfUniq, self) } token::IDENT(..) if self.is_self_ident() => { self.bump(); - SelfValue(MutImmutable) + SelfValue } token::BINOP(token::STAR) => { // Possibly "*self" or "*mut self" -- not supported. Try to avoid // emitting cryptic "unexpected token" errors. self.bump(); - let mutability = if Parser::token_is_mutability(&self.token) { + let _mutability = if Parser::token_is_mutability(&self.token) { self.parse_mutability() } else { MutImmutable }; if self.is_self_ident() { self.span_err(self.span, "cannot pass self by unsafe pointer"); self.bump(); } - SelfValue(mutability) + SelfValue } _ if Parser::token_is_mutability(&self.token) && self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => { - let mutability = self.parse_mutability(); + mutbl_self = self.parse_mutability(); self.expect_self_ident(); - SelfValue(mutability) + SelfValue } _ if Parser::token_is_mutability(&self.token) && self.look_ahead(1, |t| *t == token::TILDE) && self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => { - let mutability = self.parse_mutability(); + mutbl_self = self.parse_mutability(); self.bump(); self.expect_self_ident(); - SelfUniq(mutability) + SelfUniq } _ => SelfStatic }; + let explicit_self_sp = mk_sp(lo, self.span.hi); + // If we parsed a self type, expect a comma before the argument list. - let fn_inputs; - if explicit_self != SelfStatic { + let fn_inputs = if explicit_self != SelfStatic { match self.token { token::COMMA => { self.bump(); let sep = seq_sep_trailing_disallowed(token::COMMA); - fn_inputs = self.parse_seq_to_before_end( + let mut fn_inputs = self.parse_seq_to_before_end( &token::RPAREN, sep, parse_arg_fn ); + fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self)); + fn_inputs } token::RPAREN => { - fn_inputs = ~[]; + ~[Arg::new_self(explicit_self_sp, mutbl_self)] } _ => { let token_str = self.this_token_to_str(); @@ -3780,10 +3779,8 @@ impl Parser { } } else { let sep = seq_sep_trailing_disallowed(token::COMMA); - fn_inputs = self.parse_seq_to_before_end(&token::RPAREN, - sep, - parse_arg_fn); - } + self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn) + }; self.expect(&token::RPAREN); @@ -3918,7 +3915,6 @@ impl Parser { body: body, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - self_id: ast::DUMMY_NODE_ID, vis: visa, } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 36a87658c11..d3c194b6af6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1213,10 +1213,10 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) { print_expr(s, func); print_call_post(s, sugar, &blk, &mut base_args); } - ast::ExprMethodCall(_, func, ident, ref tys, ref args, sugar) => { - let mut base_args = (*args).clone(); + ast::ExprMethodCall(_, ident, ref tys, ref args, sugar) => { + let mut base_args = args.slice_from(1).to_owned(); let blk = print_call_pre(s, sugar, &mut base_args); - print_expr(s, func); + print_expr(s, args[0]); word(&mut s.s, "."); print_ident(s, ident); if tys.len() > 0u { @@ -1445,7 +1445,6 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) { word(&mut s.s, "]"); } ast::ExprPath(ref path) => print_path(s, path, true), - ast::ExprSelf => word(&mut s.s, "self"), ast::ExprBreak(opt_ident) => { word(&mut s.s, "break"); space(&mut s.s); @@ -1749,19 +1748,20 @@ pub fn print_pat(s: &mut State, pat: &ast::Pat) { } pub fn explicit_self_to_str(explicit_self: &ast::ExplicitSelf_, intr: @IdentInterner) -> ~str { - to_str(explicit_self, |a, &b| { print_explicit_self(a, b); () }, intr) + to_str(explicit_self, |a, &b| { print_explicit_self(a, b, ast::MutImmutable); () }, intr) } // Returns whether it printed anything -pub fn print_explicit_self(s: &mut State, explicit_self: ast::ExplicitSelf_) -> bool { +fn print_explicit_self(s: &mut State, + explicit_self: ast::ExplicitSelf_, + mutbl: ast::Mutability) -> bool { + print_mutability(s, mutbl); match explicit_self { ast::SelfStatic => { return false; } - ast::SelfValue(m) => { - print_mutability(s, m); + ast::SelfValue => { word(&mut s.s, "self"); } - ast::SelfUniq(m) => { - print_mutability(s, m); + ast::SelfUniq => { word(&mut s.s, "~self"); } ast::SelfRegion(ref lt, m) => { @@ -1799,11 +1799,25 @@ pub fn print_fn_args(s: &mut State, decl: &ast::FnDecl, // self type and the args all in the same box. rbox(s, 0u, Inconsistent); let mut first = true; - for explicit_self in opt_explicit_self.iter() { - first = !print_explicit_self(s, *explicit_self); + for &explicit_self in opt_explicit_self.iter() { + let m = match explicit_self { + ast::SelfStatic => ast::MutImmutable, + _ => match decl.inputs[0].pat.node { + ast::PatIdent(ast::BindByValue(m), _, _) => m, + _ => ast::MutImmutable + } + }; + first = !print_explicit_self(s, explicit_self, m); } - for arg in decl.inputs.iter() { + // HACK(eddyb) ignore the separately printed self argument. + let args = if first { + decl.inputs.as_slice() + } else { + decl.inputs.slice_from(1) + }; + + for arg in args.iter() { if first { first = false; } else { word_space(s, ","); } print_arg(s, arg); } @@ -2090,18 +2104,7 @@ pub fn print_ty_fn(s: &mut State, popen(s); } - // It is unfortunate to duplicate the commasep logic, but we want the - // self type and the args all in the same box. - rbox(s, 0u, Inconsistent); - let mut first = true; - for explicit_self in opt_explicit_self.iter() { - first = !print_explicit_self(s, *explicit_self); - } - for arg in decl.inputs.iter() { - if first { first = false; } else { word_space(s, ","); } - print_arg(s, arg); - } - end(s); + print_fn_args(s, decl, opt_explicit_self); if opt_sigil == Some(ast::BorrowedSigil) { word(&mut s.s, "|"); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 484f8dce1f7..5e7ad3af526 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -186,7 +186,7 @@ fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V, explicit_self: &ExplicitSelf, env: E) { match explicit_self.node { - SelfStatic | SelfValue(_) | SelfBox | SelfUniq(_) => {} + SelfStatic | SelfValue | SelfBox | SelfUniq => {} SelfRegion(ref lifetime, _) => { visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env) } @@ -654,12 +654,11 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en } visitor.visit_expr(callee_expression, env.clone()) } - ExprMethodCall(_, callee, _, ref types, ref arguments, _) => { + ExprMethodCall(_, _, ref types, ref arguments, _) => { walk_exprs(visitor, *arguments, env.clone()); for &typ in types.iter() { visitor.visit_ty(typ, env.clone()) } - visitor.visit_expr(callee, env.clone()) } ExprBinary(_, _, left_expression, right_expression) => { visitor.visit_expr(left_expression, env.clone()); @@ -734,7 +733,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en ExprPath(ref path) => { visitor.visit_path(path, expression.id, env.clone()) } - ExprSelf | ExprBreak(_) | ExprAgain(_) => {} + ExprBreak(_) | ExprAgain(_) => {} ExprRet(optional_expression) => { walk_expr_opt(visitor, optional_expression, env.clone()) } |
