diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2013-01-31 17:12:29 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2013-02-07 05:53:30 -0800 |
| commit | a32498d8464e0dfa4e2cb31967a66e076da40109 (patch) | |
| tree | 62fc02049c4d06ccd64a704f6f9e3af53d2835e3 /src/libsyntax | |
| parent | 82d73963334f01b818cda767b44cd0c8f3baf4cc (diff) | |
| download | rust-a32498d8464e0dfa4e2cb31967a66e076da40109.tar.gz rust-a32498d8464e0dfa4e2cb31967a66e076da40109.zip | |
Make ~fn non-copyable, make &fn copyable, split barefn/closure types,
correct handling of moves for struct-record update. Part of #3678. Fixes #2828, #3904, #4719.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 82 | ||||
| -rw-r--r-- | src/libsyntax/attr.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/codemap.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/auto_encode.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 170 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 110 | ||||
| -rw-r--r-- | src/libsyntax/syntax.rc | 1 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 15 |
11 files changed, 243 insertions, 170 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bc808495ca3..574ce281e28 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -399,16 +399,46 @@ pub impl mutability : cmp::Eq { #[auto_encode] #[auto_decode] #[deriving_eq] -pub enum Proto { - ProtoBare, // bare functions (deprecated) - ProtoUniq, // ~fn - ProtoBox, // @fn - ProtoBorrowed, // &fn +pub enum Abi { + RustAbi } -pub impl Proto : to_bytes::IterBytes { +pub impl Abi : to_bytes::IterBytes { pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { - (*self as uint).iter_bytes(lsb0, f); + (*self as uint).iter_bytes(lsb0, f) + } +} + +pub impl Abi : ToStr { + pure fn to_str(&self) -> ~str { + match *self { + RustAbi => ~"\"rust\"" + } + } +} + +#[auto_encode] +#[auto_decode] +#[deriving_eq] +pub enum Sigil { + BorrowedSigil, + OwnedSigil, + ManagedSigil +} + +pub impl Sigil : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as uint).iter_bytes(lsb0, f) + } +} + +pub impl Sigil : ToStr { + pure fn to_str(&self) -> ~str { + match *self { + BorrowedSigil => ~"&", + OwnedSigil => ~"~", + ManagedSigil => ~"@" + } } } @@ -434,13 +464,6 @@ pub enum expr_vstore { expr_vstore_mut_slice, // &mut [1,2,3,4] } -pub pure fn is_blockish(p: Proto) -> bool { - match p { - ProtoBorrowed => true, - ProtoBare | ProtoUniq | ProtoBox => false - } -} - #[auto_encode] #[auto_decode] pub enum binop { @@ -673,12 +696,21 @@ pub enum log_level { error, debug, log_other } #[auto_encode] #[auto_decode] +#[deriving_eq] +pub enum CallSugar { + NoSugar, + DoSugar, + ForSugar +} + +#[auto_encode] +#[auto_decode] pub enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), expr_rec(~[field], Option<@expr>), - expr_call(@expr, ~[@expr], bool), // True iff last argument is a block - expr_method_call(@expr, ident, ~[@Ty], ~[@expr], bool), // Ditto + expr_call(@expr, ~[@expr], CallSugar), + expr_method_call(@expr, ident, ~[@Ty], ~[@expr], CallSugar), expr_tup(~[@expr]), expr_binary(binop, @expr, @expr), expr_unary(unop, @expr), @@ -693,7 +725,7 @@ pub enum expr_ { expr_match(@expr, ~[arm]), // FIXME(#4717) the @() is req'd on windows or else LLVM croaks - expr_fn(Proto, fn_decl, blk, @()), + expr_fn(Sigil, fn_decl, blk, @()), expr_fn_block(fn_decl, blk), // Inner expr is always an expr_fn_block. We need the wrapping node to @@ -1112,12 +1144,19 @@ pub impl Onceness : to_bytes::IterBytes { #[auto_encode] #[auto_decode] -pub struct TyFn { - proto: Proto, +pub struct TyClosure { + sigil: Sigil, region: Option<@region>, purity: purity, onceness: Onceness, - bounds: @~[ty_param_bound], + decl: fn_decl +} + +#[auto_encode] +#[auto_decode] +pub struct TyBareFn { + purity: purity, + abi: Abi, decl: fn_decl } @@ -1133,7 +1172,8 @@ pub enum ty_ { ty_ptr(mt), ty_rptr(@region, mt), ty_rec(~[ty_field]), - ty_fn(@TyFn), + ty_closure(@TyClosure), + ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), ty_path(@path, node_id), ty_mac(mac), diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index ca28641c4a3..c347c04641f 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -154,7 +154,7 @@ pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> option::None } }; - return vec::filter_map(attrs, filter); + return vec::filter_mapped(attrs, filter); } /// Search a list of meta items and return only those with a specific name @@ -277,9 +277,9 @@ pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) -> ~[@ast::meta_item] { - return vec::filter_map(items, |item| { + return vec::filter_mapped(items, |item| { if get_meta_item_name(*item) != name { - option::Some(/* FIXME (#2543) */ copy *item) + option::Some(*item) } else { option::None } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 31ed65d8065..a509325face 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -76,7 +76,7 @@ pub impl BytePos: Sub<BytePos, BytePos> { } pub impl BytePos: to_bytes::IterBytes { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } @@ -99,7 +99,7 @@ pub impl CharPos: cmp::Ord { } pub impl CharPos: to_bytes::IterBytes { - pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(&self, +lsb0: bool, &&f: to_bytes::Cb) { (**self).iter_bytes(lsb0, f) } } diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 03aa0cde811..21154bff01e 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -392,7 +392,7 @@ priv impl ext_ctxt { expr: @ast::expr, args: ~[@ast::expr] ) -> @ast::expr { - self.expr(span, ast::expr_call(expr, args, false)) + self.expr(span, ast::expr_call(expr, args, ast::NoSugar)) } fn lambda_expr(expr: @ast::expr) -> @ast::expr { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 4d8fd39c960..a050b2316e8 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -103,7 +103,7 @@ pub fn mk_addr_of(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr { } pub fn mk_call_(cx: ext_ctxt, sp: span, fn_expr: @ast::expr, args: ~[@ast::expr]) -> @ast::expr { - mk_expr(cx, sp, ast::expr_call(fn_expr, args, false)) + mk_expr(cx, sp, ast::expr_call(fn_expr, args, ast::NoSugar)) } pub fn mk_call(cx: ext_ctxt, sp: span, fn_path: ~[ast::ident], args: ~[@ast::expr]) -> @ast::expr { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cfa8a3c1153..8cecbfb1210 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -536,13 +536,18 @@ pub fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ { ty_rptr(region, mt) => ty_rptr(region, fold_mt(mt, fld)), ty_rec(ref fields) => ty_rec(vec::map((*fields), |f| fold_field(*f, fld))), - ty_fn(f) => - ty_fn(@TyFn { - proto: f.proto, + ty_closure(f) => + ty_closure(@TyClosure { + sigil: f.sigil, purity: f.purity, region: f.region, onceness: f.onceness, - bounds: @vec::map(*f.bounds, |x| fold_ty_param_bound(*x, fld)), + decl: fold_fn_decl(f.decl, fld) + }), + ty_bare_fn(f) => + ty_bare_fn(@TyBareFn { + purity: f.purity, + abi: f.abi, decl: fold_fn_decl(f.decl, fld) }), ty_tup(tys) => ty_tup(vec::map(tys, |ty| fld.fold_ty(*ty))), @@ -557,7 +562,7 @@ pub fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ { pub fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod { ast::_mod { view_items: vec::map(m.view_items, |x| fld.fold_view_item(*x)), - items: vec::filter_map(m.items, |x| fld.fold_item(*x)), + items: vec::filter_mapped(m.items, |x| fld.fold_item(*x)), } } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 4ceb04c55d0..64c4cb3c508 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -23,8 +23,10 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { | ast::expr_block(_) | ast::expr_while(*) | ast::expr_loop(*) - | ast::expr_call(_, _, true) - | ast::expr_method_call(_, _, _, _, true) => false, + | ast::expr_call(_, _, ast::DoSugar) + | ast::expr_call(_, _, ast::ForSugar) + | ast::expr_method_call(_, _, _, _, ast::DoSugar) + | ast::expr_method_call(_, _, _, _, ast::ForSugar) => false, _ => true } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5cd78dd9049..7fb3064c388 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -10,7 +10,10 @@ use core::prelude::*; -use ast::{ProtoBox, ProtoUniq, RegionTyParamBound, TraitTyParamBound}; +use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil, RustAbi}; +use ast::{CallSugar, NoSugar, DoSugar, ForSugar}; +use ast::{TyBareFn, TyClosure}; +use ast::{RegionTyParamBound, TraitTyParamBound}; use ast::{provided, public, pure_fn, purity, re_static}; use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer}; use ast::{bind_by_copy, bitand, bitor, bitxor, blk}; @@ -27,7 +30,7 @@ use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary}; use ast::{expr_vec, expr_vstore, expr_vstore_mut_box}; use ast::{expr_vstore_fixed, expr_vstore_slice, expr_vstore_box}; use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl}; -use ast::{expr_vstore_uniq, TyFn, Onceness, Once, Many}; +use ast::{expr_vstore_uniq, TyClosure, TyBareFn, Onceness, Once, Many}; use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod}; use ast::{ident, impure_fn, infer, inherited, item, item_, item_const}; use ast::{item_const, item_enum, item_fn, item_foreign_mod, item_impl}; @@ -38,15 +41,16 @@ use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mode, module_ns, mt, mul, mutability}; use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum}; use ast::{pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct}; -use ast::{pat_tup, pat_uniq, pat_wild, path, private, Proto, ProtoBare}; -use ast::{ProtoBorrowed, re_self, re_anon, re_named, region, rem, required}; +use ast::{pat_tup, pat_uniq, pat_wild, path, private}; +use ast::{re_self, re_anon, re_named, region, rem, required}; use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract}; use ast::{sty_box, sty_by_ref, sty_region, sty_static, sty_uniq, sty_value}; use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok}; use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box}; -use ast::{ty_field, ty_fixed_length_vec, ty_fn, ty_infer, ty_mac, ty_method}; +use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn}; +use ast::{ty_infer, ty_mac, ty_method}; use ast::{ty_nil, ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr}; use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, type_value_ns, uniq}; use ast::{unnamed_field, unsafe_blk, unsafe_fn, variant, view_item}; @@ -293,25 +297,49 @@ pub impl Parser { pure fn id_to_str(id: ident) -> @~str { self.sess.interner.get(id) } - fn token_is_fn_keyword(+tok: token::Token) -> bool { + fn token_is_closure_keyword(+tok: token::Token) -> bool { self.token_is_keyword(~"pure", tok) || self.token_is_keyword(~"unsafe", tok) || self.token_is_keyword(~"once", tok) || - self.token_is_keyword(~"fn", tok) || - self.token_is_keyword(~"extern", tok) + self.token_is_keyword(~"fn", tok) } - fn parse_ty_fn(pre_proto: Option<ast::Proto>, - pre_region_name: Option<ident>) -> ty_ + fn parse_ty_bare_fn() -> ty_ { /* - (&|~|@) [r/] [pure|unsafe] [once] fn [:K] (S) -> T - ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~^ ^~^ ^ - | | | | | | | - | | | | | | Return type - | | | | | Argument types - | | | | Environment bounds + extern "ABI" [pure|unsafe] fn (S) -> T + ^~~~^ ^~~~~~~~~~~~^ ^~^ ^ + | | | | + | | | Return type + | | Argument types + | | + | | + | Purity + ABI + + */ + + let purity = self.parse_purity(); + self.expect_keyword(~"fn"); + return ty_bare_fn(@TyBareFn { + abi: RustAbi, + purity: purity, + decl: self.parse_ty_fn_decl() + }); + } + + fn parse_ty_closure(pre_sigil: Option<ast::Sigil>, + pre_region_name: Option<ident>) -> ty_ + { + /* + + (&|~|@) [r/] [pure|unsafe] [once] fn (S) -> T + ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~^ ^ + | | | | | | + | | | | | Return type + | | | | Argument types + | | | | | | | Once-ness (a.k.a., affine) | | Purity | Lifetime bound @@ -322,22 +350,13 @@ pub impl Parser { // At this point, the allocation type and lifetime bound have been // parsed. - let purity = parse_purity(&self); + let purity = self.parse_purity(); let onceness = parse_onceness(&self); + self.expect_keyword(~"fn"); + let post_sigil = self.parse_fn_ty_sigil(); - let bounds, post_proto; - if self.eat_keyword(~"extern") { - self.expect_keyword(~"fn"); - post_proto = Some(ast::ProtoBare); - bounds = @~[]; - } else { - self.expect_keyword(~"fn"); - post_proto = self.parse_fn_ty_proto(); - bounds = self.parse_optional_ty_param_bounds(); - }; - - let proto = match (pre_proto, post_proto) { - (None, None) => ast::ProtoBorrowed, + let sigil = match (pre_sigil, post_sigil) { + (None, None) => BorrowedSigil, (Some(p), None) | (None, Some(p)) => p, (Some(_), Some(_)) => { self.fatal(~"cannot combine prefix and postfix \ @@ -352,30 +371,28 @@ pub impl Parser { None }; - return ty_fn(@TyFn { - proto: proto, + return ty_closure(@TyClosure { + sigil: sigil, region: region, purity: purity, onceness: onceness, - bounds: bounds, decl: self.parse_ty_fn_decl() }); - fn parse_purity(self: &Parser) -> purity { - if self.eat_keyword(~"pure") { - return pure_fn; - } else if self.eat_keyword(~"unsafe") { - return unsafe_fn; - } else { - return impure_fn; - } - } - fn parse_onceness(self: &Parser) -> Onceness { if self.eat_keyword(~"once") {Once} else {Many} } } + fn parse_purity() -> purity { + if self.eat_keyword(~"pure") { + return pure_fn; + } else if self.eat_keyword(~"unsafe") { + return unsafe_fn; + } else { + return impure_fn; + } + } fn parse_ty_fn_decl() -> fn_decl { let inputs = do self.parse_unspanned_seq( @@ -560,10 +577,10 @@ pub impl Parser { } } else if self.token == token::AT { self.bump(); - self.parse_box_or_uniq_pointee(ast::ProtoBox, ty_box) + self.parse_box_or_uniq_pointee(ManagedSigil, ty_box) } else if self.token == token::TILDE { self.bump(); - self.parse_box_or_uniq_pointee(ast::ProtoUniq, ty_uniq) + self.parse_box_or_uniq_pointee(OwnedSigil, ty_uniq) } else if self.token == token::BINOP(token::STAR) { self.bump(); ty_ptr(self.parse_mt()) @@ -590,8 +607,10 @@ pub impl Parser { } else if self.token == token::BINOP(token::AND) { self.bump(); self.parse_borrowed_pointee() - } else if self.token_is_fn_keyword(self.token) { - self.parse_ty_fn(None, None) + } else if self.eat_keyword(~"extern") { + self.parse_ty_bare_fn() + } else if self.token_is_closure_keyword(self.token) { + self.parse_ty_closure(None, None) } else if self.token == token::MOD_SEP || is_ident_or_path(self.token) { let path = self.parse_path_with_tps(colons_before_params); @@ -603,19 +622,19 @@ pub impl Parser { } fn parse_box_or_uniq_pointee( - proto: ast::Proto, + sigil: ast::Sigil, ctor: &fn(+v: mt) -> ty_) -> ty_ { // @foo/fn() or @fn() are parsed directly as fn types: match copy self.token { token::IDENT(rname, _) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) && - self.token_is_fn_keyword(self.look_ahead(2u)) + self.token_is_closure_keyword(self.look_ahead(2u)) { self.bump(); self.bump(); - return self.parse_ty_fn(Some(proto), Some(rname)); - } else if self.token_is_fn_keyword(self.token) { - return self.parse_ty_fn(Some(proto), None); + return self.parse_ty_closure(Some(sigil), Some(rname)); + } else if self.token_is_closure_keyword(self.token) { + return self.parse_ty_closure(Some(sigil), None); } } _ => {} @@ -643,8 +662,8 @@ pub impl Parser { _ => { None } }; - if self.token_is_fn_keyword(self.token) { - return self.parse_ty_fn(Some(ProtoBorrowed), rname); + if self.token_is_closure_keyword(self.token) { + return self.parse_ty_closure(Some(BorrowedSigil), rname); } let r = self.region_from_name(rname); @@ -981,9 +1000,11 @@ pub impl Parser { } else if self.eat_keyword(~"if") { return self.parse_if_expr(); } else if self.eat_keyword(~"for") { - return self.parse_sugary_call_expr(~"for", expr_loop_body); + return self.parse_sugary_call_expr(~"for", ForSugar, + expr_loop_body); } else if self.eat_keyword(~"do") { - return self.parse_sugary_call_expr(~"do", expr_do_body); + return self.parse_sugary_call_expr(~"do", DoSugar, + expr_do_body); } else if self.eat_keyword(~"while") { return self.parse_while_expr(); } else if self.eat_keyword(~"loop") { @@ -991,14 +1012,14 @@ pub impl Parser { } else if self.eat_keyword(~"match") { return self.parse_match_expr(); } else if self.eat_keyword(~"fn") { - let opt_proto = self.parse_fn_ty_proto(); - let proto = match opt_proto { - None | Some(ast::ProtoBare) => { + let opt_sigil = self.parse_fn_ty_sigil(); + let sigil = match opt_sigil { + None => { self.fatal(~"fn expr are deprecated, use fn@") } Some(p) => { p } }; - return self.parse_fn_expr(proto); + return self.parse_fn_expr(sigil); } else if self.eat_keyword(~"unsafe") { return self.parse_block_expr(lo, unsafe_blk); } else if self.token == token::LBRACKET { @@ -1176,7 +1197,7 @@ pub impl Parser { |p| p.parse_expr()); hi = self.span.hi; - let nd = expr_method_call(e, i, tys, es, false); + let nd = expr_method_call(e, i, tys, es, NoSugar); e = self.mk_expr(lo, hi, move nd); } _ => { @@ -1198,7 +1219,7 @@ pub impl Parser { |p| p.parse_expr()); hi = self.span.hi; - let nd = expr_call(e, es, false); + let nd = expr_call(e, es, NoSugar); e = self.mk_expr(lo, hi, nd); } @@ -1566,7 +1587,7 @@ pub impl Parser { self.mk_expr(q.lo, q.hi, expr_if(q.cond, q.then, q.els)) } - fn parse_fn_expr(proto: Proto) -> @expr { + fn parse_fn_expr(sigil: Sigil) -> @expr { let lo = self.last_span.lo; // if we want to allow fn expression argument types to be inferred in @@ -1576,7 +1597,7 @@ pub impl Parser { let body = self.parse_block(); self.mk_expr(lo, body.span.hi, - expr_fn(proto, decl, body, @())) + expr_fn(sigil, decl, body, @())) } // `|args| { ... }` like in `do` expressions @@ -1641,6 +1662,7 @@ pub impl Parser { } fn parse_sugary_call_expr(keyword: ~str, + sugar: CallSugar, ctor: fn(+v: @expr) -> expr_) -> @expr { let lo = self.last_span; // Parse the callee `foo` in @@ -1654,27 +1676,27 @@ pub impl Parser { // them as the lambda arguments let e = self.parse_expr_res(RESTRICT_NO_BAR_OR_DOUBLEBAR_OP); match e.node { - expr_call(f, args, false) => { + expr_call(f, 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, ~[last_arg]); - self.mk_expr(lo.lo, block.span.hi, expr_call(f, args, true)) + self.mk_expr(lo.lo, block.span.hi, expr_call(f, args, sugar)) } - expr_method_call(f, i, tps, args, false) => { + expr_method_call(f, i, tps, 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, ~[last_arg]); self.mk_expr(lo.lo, block.span.hi, - expr_method_call(f, i, tps, args, true)) + expr_method_call(f, i, tps, args, sugar)) } expr_field(f, i, tps) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); self.mk_expr(lo.lo, block.span.hi, - expr_method_call(f, i, tps, ~[last_arg], true)) + expr_method_call(f, i, tps, ~[last_arg], sugar)) } expr_path(*) | expr_call(*) | expr_method_call(*) | expr_paren(*) => { @@ -1682,7 +1704,7 @@ pub impl Parser { let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); self.mk_expr(lo.lo, last_arg.span.hi, - expr_call(e, ~[last_arg], true)) + expr_call(e, ~[last_arg], sugar)) } _ => { // There may be other types of expressions that can @@ -3592,19 +3614,19 @@ pub impl Parser { (id, item_enum(enum_definition, ty_params), None) } - fn parse_fn_ty_proto() -> Option<Proto> { + fn parse_fn_ty_sigil() -> Option<Sigil> { match self.token { token::AT => { self.bump(); - Some(ProtoBox) + Some(ManagedSigil) } token::TILDE => { self.bump(); - Some(ProtoUniq) + Some(OwnedSigil) } token::BINOP(token::AND) => { self.bump(); - Some(ProtoBorrowed) + Some(BorrowedSigil) } _ => { None diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5079766239b..bcbee7b2f24 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -404,9 +404,15 @@ pub fn print_type_ex(s: ps, &&ty: @ast::Ty, print_colons: bool) { commasep(s, inconsistent, elts, print_type); pclose(s); } - ast::ty_fn(f) => { - print_ty_fn(s, Some(f.proto), f.region, f.purity, - f.onceness, f.bounds, f.decl, None, None, None); + ast::ty_bare_fn(f) => { + print_ty_fn(s, Some(f.abi), None, None, + f.purity, ast::Many, f.decl, None, + None, None); + } + ast::ty_closure(f) => { + print_ty_fn(s, None, Some(f.sigil), f.region, + f.purity, f.onceness, f.decl, None, + None, None); } ast::ty_path(path, _) => print_path(s, path, print_colons), ast::ty_fixed_length_vec(mt, v) => { @@ -806,8 +812,8 @@ pub fn print_ty_method(s: ps, m: ast::ty_method) { hardbreak_if_not_bol(s); maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); - print_ty_fn(s, None, None, m.purity, ast::Many, - @~[], m.decl, Some(m.ident), Some(m.tps), + print_ty_fn(s, None, None, None, m.purity, ast::Many, + m.decl, Some(m.ident), Some(m.tps), Some(m.self_ty.node)); word(s.s, ~";"); } @@ -1046,32 +1052,32 @@ pub fn print_expr_vstore(s: ps, t: ast::expr_vstore) { } pub fn print_call_pre(s: ps, - has_block: bool, + sugar: ast::CallSugar, base_args: &mut ~[@ast::expr]) -> Option<@ast::expr> { - if has_block { - let blk_arg = base_args.pop(); - match blk_arg.node { - ast::expr_loop_body(_) => { head(s, ~"for"); } - ast::expr_do_body(_) => { head(s, ~"do"); } - _ => {} - } - Some(blk_arg) - } else { - None + match sugar { + ast::DoSugar => { + head(s, ~"do"); + Some(base_args.pop()) + } + ast::ForSugar => { + head(s, ~"for"); + Some(base_args.pop()) + } + ast::NoSugar => None } } pub fn print_call_post(s: ps, - has_block: bool, + sugar: ast::CallSugar, blk: &Option<@ast::expr>, base_args: &mut ~[@ast::expr]) { - if !has_block || !base_args.is_empty() { + if sugar == ast::NoSugar || !base_args.is_empty() { popen(s); commasep_exprs(s, inconsistent, *base_args); pclose(s); } - if has_block { + if sugar != ast::NoSugar { nbsp(s); match blk.get().node { // need to handle closures specifically @@ -1181,15 +1187,15 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { commasep_exprs(s, inconsistent, exprs); pclose(s); } - ast::expr_call(func, args, has_block) => { + ast::expr_call(func, args, sugar) => { let mut base_args = copy args; - let blk = print_call_pre(s, has_block, &mut base_args); + let blk = print_call_pre(s, sugar, &mut base_args); print_expr(s, func); - print_call_post(s, has_block, &blk, &mut base_args); + print_call_post(s, sugar, &blk, &mut base_args); } - ast::expr_method_call(func, ident, tys, args, has_block) => { + ast::expr_method_call(func, ident, tys, args, sugar) => { let mut base_args = copy args; - let blk = print_call_pre(s, has_block, &mut base_args); + let blk = print_call_pre(s, sugar, &mut base_args); print_expr(s, func); word(s.s, ~"."); print_ident(s, ident); @@ -1198,7 +1204,7 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { commasep(s, inconsistent, tys, print_type); word(s.s, ~">"); } - print_call_post(s, has_block, &blk, &mut base_args); + print_call_post(s, sugar, &blk, &mut base_args); } ast::expr_binary(op, lhs, rhs) => { print_expr(s, lhs); @@ -1305,13 +1311,13 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) { } bclose_(s, expr.span, match_indent_unit); } - ast::expr_fn(proto, decl, ref body, _) => { + ast::expr_fn(sigil, decl, ref body, _) => { // containing cbox, will be closed by print-block at } cbox(s, indent_unit); // head-box, will be closed by print-block at start ibox(s, 0u); print_fn_header_info(s, None, None, ast::Many, - Some(proto), ast::inherited); + Some(sigil), ast::inherited); print_fn_args_and_ret(s, decl, None); space(s.s); print_block(s, (*body)); @@ -1900,33 +1906,32 @@ pub fn print_arg(s: ps, input: ast::arg) { } pub fn print_ty_fn(s: ps, - opt_proto: Option<ast::Proto>, + opt_abi: Option<ast::Abi>, + opt_sigil: Option<ast::Sigil>, opt_region: Option<@ast::region>, purity: ast::purity, onceness: ast::Onceness, - bounds: @~[ast::ty_param_bound], decl: ast::fn_decl, id: Option<ast::ident>, tps: Option<~[ast::ty_param]>, opt_self_ty: Option<ast::self_ty_>) { ibox(s, indent_unit); // Duplicates the logic in `print_fn_header_info()`. This is because that - // function prints the proto in the wrong place. That should be fixed. + // function prints the sigil in the wrong place. That should be fixed. print_self_ty_if_static(s, opt_self_ty); - print_opt_proto(s, opt_proto); + print_opt_abi(s, opt_abi); + print_opt_sigil(s, opt_sigil); for opt_region.each |r| { print_region(s, ~"", *r, ~"/"); } print_purity(s, purity); print_onceness(s, onceness); word(s.s, ~"fn"); - print_bounds(s, bounds); match id { Some(id) => { word(s.s, ~" "); print_ident(s, id); } _ => () } match tps { Some(tps) => print_type_params(s, tps), _ => () } zerobreak(s.s); popen(s); - // It is unfortunate to duplicate the commasep logic, but we - // we want the self type, the args, and the capture clauses all - // in the same box. + // It is unfortunate to duplicate the commasep logic, but we we want the + // self type and the args all in the same box. box(s, 0u, inconsistent); let mut first = true; for opt_self_ty.each |self_ty| { @@ -2157,12 +2162,18 @@ pub fn print_opt_purity(s: ps, opt_purity: Option<ast::purity>) { } } -pub fn print_opt_proto(s: ps, opt_proto: Option<ast::Proto>) { - match opt_proto { - Some(ast::ProtoBare) => { word(s.s, ~"extern "); } - Some(ast::ProtoBorrowed) => { word(s.s, ~"&"); } - Some(ast::ProtoUniq) => { word(s.s, ~"~"); } - Some(ast::ProtoBox) => { word(s.s, ~"@"); } +pub fn print_opt_abi(s: ps, opt_abi: Option<ast::Abi>) { + match opt_abi { + Some(ast::RustAbi) => { word_nbsp(s, ~"extern"); } + None => {} + }; +} + +pub fn print_opt_sigil(s: ps, opt_sigil: Option<ast::Sigil>) { + match opt_sigil { + Some(ast::BorrowedSigil) => { word(s.s, ~"&"); } + Some(ast::OwnedSigil) => { word(s.s, ~"~"); } + Some(ast::ManagedSigil) => { word(s.s, ~"@"); } None => {} }; } @@ -2171,20 +2182,20 @@ pub fn print_fn_header_info(s: ps, opt_sty: Option<ast::self_ty_>, opt_purity: Option<ast::purity>, onceness: ast::Onceness, - opt_proto: Option<ast::Proto>, + opt_sigil: Option<ast::Sigil>, vis: ast::visibility) { print_self_ty_if_static(s, opt_sty); word(s.s, visibility_qualified(vis, ~"")); print_opt_purity(s, opt_purity); print_onceness(s, onceness); word(s.s, ~"fn"); - print_opt_proto(s, opt_proto); + print_opt_sigil(s, opt_sigil); } -pub fn opt_proto_to_str(opt_p: Option<ast::Proto>) -> ~str { +pub fn opt_sigil_to_str(opt_p: Option<ast::Sigil>) -> ~str { match opt_p { None => ~"fn", - Some(p) => proto_to_str(p) + Some(p) => fmt!("fn%s", p.to_str()) } } @@ -2218,15 +2229,6 @@ pub fn print_onceness(s: ps, o: ast::Onceness) { } } -pub fn proto_to_str(p: ast::Proto) -> ~str { - return match p { - ast::ProtoBare => ~"extern fn", - ast::ProtoBorrowed => ~"fn&", - ast::ProtoUniq => ~"fn~", - ast::ProtoBox => ~"fn@" - }; -} - #[cfg(test)] pub mod test { use ast; diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index a6d50b9cf09..877817af06c 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -22,7 +22,6 @@ #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; -#[warn(deprecated_pattern)]; #[allow(deprecated_self)]; #[no_core]; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index eea1a6906e4..37b96e05653 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -30,10 +30,10 @@ use core::vec; pub enum vt<E> { mk_vt(visitor<E>), } pub enum fn_kind { - fk_item_fn(ident, ~[ty_param], purity), //< an item declared with fn() - fk_method(ident, ~[ty_param], @method), - fk_anon(Proto), //< an anonymous function like fn@(...) - fk_fn_block, //< a block {||...} + fk_item_fn(ident, ~[ty_param], purity), // fn foo() + fk_method(ident, ~[ty_param], @method), // fn foo(&self) + fk_anon(ast::Sigil), // fn@(x, y) { ... } + fk_fn_block, // |x, y| ... fk_dtor(~[ty_param], ~[attribute], node_id /* self id */, def_id /* parent class id */) // class destructor @@ -217,9 +217,12 @@ pub fn visit_ty<E>(t: @Ty, e: E, v: vt<E>) { ty_tup(ts) => for ts.each |tt| { (v.visit_ty)(*tt, e, v); }, - ty_fn(f) => { + ty_closure(f) => { + for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, e, v); } + (v.visit_ty)(f.decl.output, e, v); + } + ty_bare_fn(f) => { for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, e, v); } - visit_ty_param_bounds(f.bounds, e, v); (v.visit_ty)(f.decl.output, e, v); } ty_path(p, _) => visit_path(p, e, v), |
