diff options
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 407 |
1 files changed, 221 insertions, 186 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5aa45ab3c9b..25b45a5f3b5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -19,14 +19,14 @@ use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer}; use ast::{bind_by_copy, bitand, bitor, bitxor, blk}; use ast::{blk_check_mode, box}; use ast::{crate, crate_cfg, decl, decl_item}; -use ast::{decl_local, default_blk, deref, div, enum_def}; +use ast::{decl_local, default_blk, deref, div, enum_def, explicit_self}; use ast::{expr, expr_, expr_addr_of, expr_match, expr_again}; use ast::{expr_assign, expr_assign_op, expr_binary, expr_block}; use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body}; use ast::{expr_field, expr_fn_block, expr_if, expr_index}; use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac}; use ast::{expr_method_call, expr_paren, expr_path, expr_repeat}; -use ast::{expr_ret, expr_struct, expr_tup, expr_unary}; +use ast::{expr_ret, expr_self, expr_struct, expr_tup, expr_unary}; use ast::{expr_vec, expr_vstore, expr_vstore_mut_box}; use ast::{expr_vstore_slice, expr_vstore_box}; use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl}; @@ -43,7 +43,7 @@ use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum}; use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct}; use ast::{pat_tup, pat_uniq, pat_wild, private}; use ast::{rem, required}; -use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; +use ast::{ret_style, return_val, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; use ast::{struct_variant_kind, subtract}; use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value}; @@ -82,6 +82,7 @@ use parse::obsolete::ObsoleteMode; use parse::obsolete::{ObsoleteLifetimeNotation, ObsoleteConstManagedPointer}; use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod}; use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType}; +use parse::obsolete::{ObsoleteNamedExternModule}; use parse::token::{can_begin_expr, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, special_idents, token_to_binop}; use parse::token; @@ -337,10 +338,10 @@ pub impl Parser { // is this one of the keywords that signals a closure type? fn token_is_closure_keyword(&self, 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("pure", tok) || + self.token_is_keyword("unsafe", tok) || + self.token_is_keyword("once", tok) || + self.token_is_keyword("fn", tok) } fn token_is_lifetime(&self, tok: &token::Token) -> bool { @@ -377,7 +378,7 @@ pub impl Parser { let opt_abis = self.parse_opt_abis(); let abis = opt_abis.get_or_default(AbiSet::Rust()); let purity = self.parse_unsafety(); - self.expect_keyword(&~"fn"); + self.expect_keyword("fn"); let (decl, lifetimes) = self.parse_ty_fn_decl(); return ty_bare_fn(@TyBareFn { abis: abis, @@ -394,12 +395,13 @@ pub impl Parser { -> ty_ { /* - (&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T - ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~^ ^~^ ^ - | | | | | | | - | | | | | | Return type - | | | | | Argument types - | | | | Lifetimes + (&|~|@) ['r] [pure|unsafe] [once] fn [:Bounds] <'lt> (S) -> T + ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~~~~~^ ^~~~^ ^~^ ^ + | | | | | | | | + | | | | | | | Return type + | | | | | | Argument types + | | | | | Lifetimes + | | | | Closure bounds | | | Once-ness (a.k.a., affine) | | Purity | Lifetime bound @@ -412,11 +414,11 @@ pub impl Parser { let purity = self.parse_unsafety(); let onceness = parse_onceness(self); - self.expect_keyword(&~"fn"); + self.expect_keyword("fn"); + let bounds = self.parse_optional_ty_param_bounds(); if self.parse_fn_ty_sigil().is_some() { - self.obsolete(*self.span, - ObsoletePostFnTySigil); + self.obsolete(*self.span, ObsoletePostFnTySigil); } let (decl, lifetimes) = self.parse_ty_fn_decl(); @@ -426,21 +428,26 @@ pub impl Parser { region: region, purity: purity, onceness: onceness, + bounds: bounds, decl: decl, lifetimes: lifetimes, }); - fn parse_onceness(self: &Parser) -> Onceness { - if self.eat_keyword(&~"once") { Once } else { Many } + fn parse_onceness(this: &Parser) -> Onceness { + if this.eat_keyword(~"once") { + Once + } else { + Many + } } } // looks like this should be called parse_unsafety fn parse_unsafety(&self) -> purity { - if self.eat_keyword(&~"pure") { + if self.eat_keyword("pure") { self.obsolete(*self.last_span, ObsoletePurity); return impure_fn; - } else if self.eat_keyword(&~"unsafe") { + } else if self.eat_keyword("unsafe") { return unsafe_fn; } else { return impure_fn; @@ -500,7 +507,7 @@ pub impl Parser { let generics = p.parse_generics(); - let (self_ty, d) = do self.parse_fn_decl_with_self() |p| { + let (explicit_self, d) = do self.parse_fn_decl_with_self() |p| { // This is somewhat dubious; We don't want to allow argument // names to be left off if there is a definition... either::Left(p.parse_arg_general(false)) @@ -522,7 +529,7 @@ pub impl Parser { purity: pur, decl: d, generics: generics, - self_ty: self_ty, + explicit_self: explicit_self, id: p.get_id(), span: mk_sp(lo, hi) }) @@ -536,7 +543,7 @@ pub impl Parser { ident: ident, attrs: attrs, generics: generics, - self_ty: self_ty, + explicit_self: explicit_self, purity: pur, decl: d, body: body, @@ -695,7 +702,7 @@ pub impl Parser { // BORROWED POINTER self.bump(); self.parse_borrowed_pointee() - } else if self.eat_keyword(&~"extern") { + } else if self.eat_keyword("extern") { // EXTERN FUNCTION self.parse_ty_bare_fn() } else if self.token_is_closure_keyword(© *self.token) { @@ -704,7 +711,7 @@ pub impl Parser { self.obsolete(*self.last_span, ObsoleteBareFnType); result } else if *self.token == token::MOD_SEP - || is_ident_or_path(&*self.token) { + || is_ident_or_path(self.token) { // NAMED TYPE let path = self.parse_path_with_tps(false); ty_path(path, self.get_id()) @@ -819,7 +826,7 @@ pub impl Parser { let mut is_mutbl = false; let pat = if require_name || self.is_named_argument() { self.parse_arg_mode(); - is_mutbl = self.eat_keyword(&~"mut"); + is_mutbl = self.eat_keyword("mut"); let pat = self.parse_pat(false); self.expect(&token::COLON); pat @@ -847,7 +854,7 @@ pub impl Parser { // parse an argument in a lambda header e.g. |arg, arg| fn parse_fn_block_arg(&self) -> arg_or_capture_item { self.parse_arg_mode(); - let is_mutbl = self.eat_keyword(&~"mut"); + let is_mutbl = self.eat_keyword("mut"); let pat = self.parse_pat(false); let t = if self.eat(&token::COLON) { self.parse_ty(false) @@ -898,9 +905,9 @@ pub impl Parser { // matches lit = true | false | token_lit fn parse_lit(&self) -> lit { let lo = self.span.lo; - let lit = if self.eat_keyword(&~"true") { + let lit = if self.eat_keyword("true") { lit_bool(true) - } else if self.eat_keyword(&~"false") { + } else if self.eat_keyword("false") { lit_bool(false) } else { // XXX: This is a really bad copy! @@ -911,6 +918,24 @@ pub impl Parser { codemap::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) } } + // matches '-' lit | lit + fn parse_literal_maybe_minus(&self) -> @expr { + let minus_lo = self.span.lo; + let minus_present = self.eat(&token::BINOP(token::MINUS)); + + let lo = self.span.lo; + let literal = @self.parse_lit(); + let hi = self.span.hi; + let expr = self.mk_expr(lo, hi, expr_lit(literal)); + + if minus_present { + let minus_hi = self.span.hi; + self.mk_expr(minus_lo, minus_hi, expr_unary(neg, expr)) + } else { + expr + } + } + // parse a path into a vector of idents, whether the path starts // with ::, and a span. fn parse_path(&self) -> (~[ast::ident],bool,span) { @@ -1118,15 +1143,15 @@ pub impl Parser { } fn token_is_mutability(&self, tok: &token::Token) -> bool { - self.token_is_keyword(&~"mut", tok) || - self.token_is_keyword(&~"const", tok) + self.token_is_keyword("mut", tok) || + self.token_is_keyword("const", tok) } // parse mutability declaration (mut/const/imm) fn parse_mutability(&self) -> mutability { - if self.eat_keyword(&~"mut") { + if self.eat_keyword("mut") { m_mutbl - } else if self.eat_keyword(&~"const") { + } else if self.eat_keyword("const") { m_const } else { m_imm @@ -1224,27 +1249,30 @@ pub impl Parser { expr_block(blk)); } else if token::is_bar(&*self.token) { return self.parse_lambda_expr(); - } else if self.eat_keyword(&~"if") { + } else if self.eat_keyword("self") { + ex = expr_self; + hi = self.span.hi; + } else if self.eat_keyword("if") { return self.parse_if_expr(); - } else if self.eat_keyword(&~"for") { + } else if self.eat_keyword("for") { return self.parse_sugary_call_expr(~"for", ForSugar, expr_loop_body); - } else if self.eat_keyword(&~"do") { + } else if self.eat_keyword("do") { return self.parse_sugary_call_expr(~"do", DoSugar, expr_do_body); - } else if self.eat_keyword(&~"while") { + } else if self.eat_keyword("while") { return self.parse_while_expr(); } else if self.token_is_lifetime(&*self.token) { let lifetime = self.get_lifetime(&*self.token); self.bump(); self.expect(&token::COLON); - self.expect_keyword(&~"loop"); + self.expect_keyword("loop"); return self.parse_loop_expr(Some(lifetime)); - } else if self.eat_keyword(&~"loop") { + } else if self.eat_keyword("loop") { return self.parse_loop_expr(None); - } else if self.eat_keyword(&~"match") { + } else if self.eat_keyword("match") { return self.parse_match_expr(); - } else if self.eat_keyword(&~"unsafe") { + } else if self.eat_keyword("unsafe") { return self.parse_block_expr(lo, unsafe_blk); } else if *self.token == token::LBRACKET { self.bump(); @@ -1284,7 +1312,7 @@ pub impl Parser { } } hi = self.span.hi; - } else if self.eat_keyword(&~"__log") { + } else if self.eat_keyword("__log") { // LOG expression self.expect(&token::LPAREN); let lvl = self.parse_expr(); @@ -1293,14 +1321,14 @@ pub impl Parser { ex = expr_log(lvl, e); hi = self.span.hi; self.expect(&token::RPAREN); - } else if self.eat_keyword(&~"return") { + } else if self.eat_keyword("return") { // RETURN expression if can_begin_expr(&*self.token) { let e = self.parse_expr(); hi = e.span.hi; ex = expr_ret(Some(e)); } else { ex = expr_ret(None); } - } else if self.eat_keyword(&~"break") { + } else if self.eat_keyword("break") { // BREAK expression if self.token_is_lifetime(&*self.token) { let lifetime = self.get_lifetime(&*self.token); @@ -1310,14 +1338,14 @@ pub impl Parser { ex = expr_break(None); } hi = self.span.hi; - } else if self.eat_keyword(&~"copy") { + } else if self.eat_keyword("copy") { // COPY expression let e = self.parse_expr(); ex = expr_copy(e); hi = e.span.hi; } else if *self.token == token::MOD_SEP || - is_ident(&*self.token) && !self.is_keyword(&~"true") && - !self.is_keyword(&~"false") { + is_ident(&*self.token) && !self.is_keyword("true") && + !self.is_keyword("false") { let pth = self.parse_path_with_tps(true); // `!`, as an operator, is prefix, so we know this isn't that @@ -1531,9 +1559,12 @@ pub impl Parser { |p| p.parse_token_tree() ); let (s, z) = p.parse_sep_and_zerok(); + let seq = match seq { + spanned { node, _ } => node, + }; tt_seq( - mk_sp(sp.lo ,p.span.hi), - seq.node, + mk_sp(sp.lo, p.span.hi), + seq, s, z ) @@ -1599,9 +1630,9 @@ pub impl Parser { token::LBRACE | token::LPAREN | token::LBRACKET => { self.parse_matcher_subseq( name_idx, - *self.token, + copy *self.token, // tjc: not sure why we need a copy - token::flip_delimiter(&*self.token) + token::flip_delimiter(self.token) ) } _ => self.fatal(~"expected open delimiter") @@ -1794,7 +1825,7 @@ pub impl Parser { } } None => { - if as_prec > min_prec && self.eat_keyword(&~"as") { + if as_prec > min_prec && self.eat_keyword("as") { let rhs = self.parse_ty(true); let _as = self.mk_expr(lhs.span.lo, rhs.span.hi, @@ -1868,7 +1899,7 @@ pub impl Parser { let thn = self.parse_block(); let mut els: Option<@expr> = None; let mut hi = thn.span.hi; - if self.eat_keyword(&~"else") { + if self.eat_keyword("else") { let elexpr = self.parse_else_expr(); els = Some(elexpr); hi = elexpr.span.hi; @@ -1935,7 +1966,7 @@ pub impl Parser { } fn parse_else_expr(&self) -> @expr { - if self.eat_keyword(&~"if") { + if self.eat_keyword("if") { return self.parse_if_expr(); } else { let blk = self.parse_block(); @@ -1961,14 +1992,15 @@ 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, NoSugar) => { + expr_call(f, /*bad*/ copy 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, sugar)) } - expr_method_call(f, i, tps, args, NoSugar) => { + expr_method_call(f, i, /*bad*/ copy tps, + /*bad*/ copy args, NoSugar) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); @@ -1976,7 +2008,7 @@ pub impl Parser { self.mk_expr(lo.lo, block.span.hi, expr_method_call(f, i, tps, args, sugar)) } - expr_field(f, i, tps) => { + expr_field(f, i, /*bad*/ copy tps) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); @@ -2048,7 +2080,7 @@ pub impl Parser { fn looking_at_record_literal(&self) -> bool { let lookahead = self.look_ahead(1); *self.token == token::LBRACE && - (self.token_is_keyword(&~"mut", &lookahead) || + (self.token_is_keyword("mut", &lookahead) || (is_plain_ident(&lookahead) && self.look_ahead(2) == token::COLON)) } @@ -2061,7 +2093,7 @@ pub impl Parser { while *self.token != token::RBRACE { let pats = self.parse_pats(); let mut guard = None; - if self.eat_keyword(&~"if") { guard = Some(self.parse_expr()); } + if self.eat_keyword("if") { guard = Some(self.parse_expr()); } self.expect(&token::FAT_ARROW); let expr = self.parse_expr_res(RESTRICT_STMT_EXPR); @@ -2234,7 +2266,7 @@ pub impl Parser { let lo = self.span.lo; let mut hi = self.span.hi; let pat; - match *self.token { + match /*bad*/ copy *self.token { // parse _ token::UNDERSCORE => { self.bump(); pat = pat_wild; } // parse @pat @@ -2348,24 +2380,33 @@ pub impl Parser { self.expect(&token::RBRACKET); pat = ast::pat_vec(before, slice, after); } - tok => { - if !is_ident_or_path(&tok) - || self.is_keyword(&~"true") - || self.is_keyword(&~"false") + ref tok => { + if !is_ident_or_path(tok) + || self.is_keyword("true") + || self.is_keyword("false") { - // parse an expression pattern or exp .. exp - let val = self.parse_expr_res(RESTRICT_NO_BAR_OP); + // Parse an expression pattern or exp .. exp. + // + // These expressions are limited to literals (possibly + // preceded by unary-minus) or identifiers. + let val = self.parse_literal_maybe_minus(); if self.eat(&token::DOTDOT) { - let end = self.parse_expr_res(RESTRICT_NO_BAR_OP); + let end = if is_ident_or_path(tok) { + let path = self.parse_path_with_tps(true); + let hi = self.span.hi; + self.mk_expr(lo, hi, expr_path(path)) + } else { + self.parse_literal_maybe_minus() + }; pat = pat_range(val, end); } else { pat = pat_lit(val); } - } else if self.eat_keyword(&~"ref") { + } else if self.eat_keyword("ref") { // parse ref pat let mutbl = self.parse_mutability(); pat = self.parse_pat_ident(refutable, bind_by_ref(mutbl)); - } else if self.eat_keyword(&~"copy") { + } else if self.eat_keyword("copy") { // parse copy pat pat = self.parse_pat_ident(refutable, bind_by_copy); } else { @@ -2433,7 +2474,7 @@ pub impl Parser { } }, _ => { - if vec::len(enum_path.idents)==1u { + if enum_path.idents.len()==1u { // it could still be either an enum // or an identifier pattern, resolve // will sort it out: @@ -2514,7 +2555,7 @@ pub impl Parser { // parse a "let" stmt fn parse_let(&self) -> @decl { - let is_mutbl = self.eat_keyword(&~"mut"); + let is_mutbl = self.eat_keyword("mut"); let lo = self.span.lo; let mut locals = ~[self.parse_local(is_mutbl)]; while self.eat(&token::COMMA) { @@ -2528,7 +2569,7 @@ pub impl Parser { pr: visibility, attrs: ~[attribute]) -> @struct_field { let lo = self.span.lo; - if self.eat_keyword(&~"mut") { + if self.eat_keyword("mut") { // Do nothing, for backwards compatibility. // XXX: Remove after snapshot. } @@ -2558,9 +2599,9 @@ pub impl Parser { } let lo = self.span.lo; - if self.is_keyword(&~"let") { + if self.is_keyword("let") { check_expected_item(self, first_item_attrs); - self.expect_keyword(&~"let"); + self.expect_keyword("let"); let decl = self.parse_let(); return @spanned(lo, decl.span.hi, stmt_decl(decl, self.get_id())); } else if is_ident(&*self.token) @@ -2647,7 +2688,7 @@ pub impl Parser { maybe_whole!(self, nt_block); let lo = self.span.lo; - if self.eat_keyword(&~"unsafe") { + if self.eat_keyword("unsafe") { self.obsolete(copy *self.span, ObsoleteUnsafeBlock); } self.expect(&token::LBRACE); @@ -2662,7 +2703,7 @@ pub impl Parser { maybe_whole!(pair_empty self, nt_block); let lo = self.span.lo; - if self.eat_keyword(&~"unsafe") { + if self.eat_keyword("unsafe") { self.obsolete(copy *self.span, ObsoleteUnsafeBlock); } self.expect(&token::LBRACE); @@ -2796,10 +2837,10 @@ pub impl Parser { } fn parse_optional_purity(&self) -> ast::purity { - if self.eat_keyword(&~"pure") { + if self.eat_keyword("pure") { self.obsolete(*self.last_span, ObsoletePurity); ast::impure_fn - } else if self.eat_keyword(&~"unsafe") { + } else if self.eat_keyword("unsafe") { ast::unsafe_fn } else { ast::impure_fn @@ -2807,15 +2848,15 @@ pub impl Parser { } fn parse_optional_onceness(&self) -> ast::Onceness { - if self.eat_keyword(&~"once") { ast::Once } else { ast::Many } + if self.eat_keyword("once") { ast::Once } else { ast::Many } } // matches optbounds = ( ( : ( boundseq )? )? ) // where boundseq = ( bound + boundseq ) | bound // and bound = 'static | ty - fn parse_optional_ty_param_bounds(&self) -> @OptVec<TyParamBound> { + fn parse_optional_ty_param_bounds(&self) -> OptVec<TyParamBound> { if !self.eat(&token::COLON) { - return @opt_vec::Empty; + return opt_vec::Empty; } let mut result = opt_vec::Empty; @@ -2863,19 +2904,19 @@ pub impl Parser { loop; } - if is_ident_or_path(&*self.token) { + if is_ident_or_path(self.token) { self.obsolete(*self.span, ObsoleteTraitBoundSeparator); } } - return @result; + return result; } // matches typaram = IDENT optbounds fn parse_ty_param(&self) -> TyParam { let ident = self.parse_ident(); - let bounds = self.parse_optional_ty_param_bounds(); + let bounds = @self.parse_optional_ty_param_bounds(); ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds } } @@ -2964,16 +3005,16 @@ pub impl Parser { &self, parse_arg_fn: &fn(&Parser) -> arg_or_capture_item - ) -> (self_ty, fn_decl) { - fn maybe_parse_self_ty( - cnstr: &fn(v: mutability) -> ast::self_ty_, + ) -> (explicit_self, fn_decl) { + fn maybe_parse_explicit_self( + cnstr: &fn(v: mutability) -> ast::explicit_self_, p: &Parser - ) -> ast::self_ty_ { + ) -> ast::explicit_self_ { // We need to make sure it isn't a mode or a type - if p.token_is_keyword(&~"self", &p.look_ahead(1)) || - ((p.token_is_keyword(&~"const", &p.look_ahead(1)) || - p.token_is_keyword(&~"mut", &p.look_ahead(1))) && - p.token_is_keyword(&~"self", &p.look_ahead(2))) { + if p.token_is_keyword("self", &p.look_ahead(1)) || + ((p.token_is_keyword("const", &p.look_ahead(1)) || + p.token_is_keyword("mut", &p.look_ahead(1))) && + p.token_is_keyword("self", &p.look_ahead(2))) { p.bump(); let mutability = p.parse_mutability(); @@ -2984,9 +3025,7 @@ pub impl Parser { } } - fn maybe_parse_borrowed_self_ty( - self: &Parser - ) -> ast::self_ty_ { + fn maybe_parse_borrowed_explicit_self(this: &Parser) -> ast::explicit_self_ { // The following things are possible to see here: // // fn(&self) @@ -2996,37 +3035,29 @@ pub impl Parser { // // We already know that the current token is `&`. - if ( - self.token_is_keyword(&~"self", &self.look_ahead(1))) - { - self.bump(); - self.expect_self_ident(); + if (this.token_is_keyword("self", &this.look_ahead(1))) { + this.bump(); + this.expect_self_ident(); sty_region(None, m_imm) - } else if ( - self.token_is_mutability(&self.look_ahead(1)) && - self.token_is_keyword(&~"self", &self.look_ahead(2))) - { - self.bump(); - let mutability = self.parse_mutability(); - self.expect_self_ident(); + } else if (this.token_is_mutability(&this.look_ahead(1)) && + this.token_is_keyword("self", &this.look_ahead(2))) { + this.bump(); + let mutability = this.parse_mutability(); + this.expect_self_ident(); sty_region(None, mutability) - } else if ( - self.token_is_lifetime(&self.look_ahead(1)) && - self.token_is_keyword(&~"self", &self.look_ahead(2))) - { - self.bump(); - let lifetime = @self.parse_lifetime(); - self.expect_self_ident(); + } else if (this.token_is_lifetime(&this.look_ahead(1)) && + this.token_is_keyword("self", &this.look_ahead(2))) { + this.bump(); + let lifetime = @this.parse_lifetime(); + this.expect_self_ident(); sty_region(Some(lifetime), m_imm) - } else if ( - self.token_is_lifetime(&self.look_ahead(1)) && - self.token_is_mutability(&self.look_ahead(2)) && - self.token_is_keyword(&~"self", &self.look_ahead(3))) - { - self.bump(); - let lifetime = @self.parse_lifetime(); - let mutability = self.parse_mutability(); - self.expect_self_ident(); + } else if (this.token_is_lifetime(&this.look_ahead(1)) && + this.token_is_mutability(&this.look_ahead(2)) && + this.token_is_keyword("self", &this.look_ahead(3))) { + this.bump(); + let lifetime = @this.parse_lifetime(); + let mutability = this.parse_mutability(); + this.expect_self_ident(); sty_region(Some(lifetime), mutability) } else { sty_static @@ -3038,15 +3069,15 @@ pub impl Parser { // A bit of complexity and lookahead is needed here in order to to be // backwards compatible. let lo = self.span.lo; - let self_ty = match *self.token { + let explicit_self = match *self.token { token::BINOP(token::AND) => { - maybe_parse_borrowed_self_ty(self) + maybe_parse_borrowed_explicit_self(self) } token::AT => { - maybe_parse_self_ty(sty_box, self) + maybe_parse_explicit_self(sty_box, self) } token::TILDE => { - maybe_parse_self_ty(sty_uniq, self) + maybe_parse_explicit_self(sty_uniq, self) } token::IDENT(*) if self.is_self_ident() => { self.bump(); @@ -3059,7 +3090,7 @@ pub impl Parser { // If we parsed a self type, expect a comma before the argument list. let args_or_capture_items; - if self_ty != sty_static { + if explicit_self != sty_static { match *self.token { token::COMMA => { self.bump(); @@ -3104,7 +3135,7 @@ pub impl Parser { cf: ret_style }; - (spanned(lo, hi, self_ty), fn_decl) + (spanned(lo, hi, explicit_self), fn_decl) } // parse the |arg, arg| header on a lambda @@ -3171,7 +3202,7 @@ pub impl Parser { let pur = self.parse_fn_purity(); let ident = self.parse_ident(); let generics = self.parse_generics(); - let (self_ty, decl) = do self.parse_fn_decl_with_self() |p| { + let (explicit_self, decl) = do self.parse_fn_decl_with_self() |p| { p.parse_arg() }; @@ -3182,7 +3213,7 @@ pub impl Parser { ident: ident, attrs: attrs, generics: generics, - self_ty: self_ty, + explicit_self: explicit_self, purity: pur, decl: decl, body: body, @@ -3231,7 +3262,7 @@ pub impl Parser { let mut ty = self.parse_ty(false); // Parse traits, if necessary. - let opt_trait = if could_be_trait && self.eat_keyword(&~"for") { + let opt_trait = if could_be_trait && self.eat_keyword("for") { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { ty_path(path, node_id) => { @@ -3406,11 +3437,11 @@ pub impl Parser { return ~[]; } - if self.eat_keyword(&~"priv") { + if self.eat_keyword("priv") { return ~[self.parse_single_struct_field(private, attrs)] } - if self.eat_keyword(&~"pub") { + if self.eat_keyword("pub") { return ~[self.parse_single_struct_field(public, attrs)]; } @@ -3423,13 +3454,13 @@ pub impl Parser { // parse visiility: PUB, PRIV, or nothing fn parse_visibility(&self) -> visibility { - if self.eat_keyword(&~"pub") { public } - else if self.eat_keyword(&~"priv") { private } + if self.eat_keyword("pub") { public } + else if self.eat_keyword("priv") { private } else { inherited } } fn parse_staticness(&self) -> bool { - if self.eat_keyword(&~"static") { + if self.eat_keyword("static") { self.obsolete(*self.last_span, ObsoleteStaticMethod); true } else { @@ -3507,6 +3538,7 @@ pub impl Parser { fn parse_item_mod(&self, outer_attrs: ~[ast::attribute]) -> item_info { let id_span = *self.span; let id = self.parse_ident(); + let merge = ::attr::first_attr_value_str_by_name(outer_attrs, "merge"); let info_ = if *self.token == token::SEMI { self.bump(); // This mod is in an external file. Let's go get it! @@ -3526,7 +3558,7 @@ pub impl Parser { // (int-template, iter-trait). If there's a 'merge' attribute // on the mod, then we'll go and suck in another file and merge // its contents - match ::attr::first_attr_value_str_by_name(outer_attrs, ~"merge") { + match merge { Some(path) => { let prefix = Path( self.sess.cm.span_to_filename(*self.span)); @@ -3612,10 +3644,7 @@ pub impl Parser { new_sub_parser_from_file(self.sess, copy self.cfg, &full_path, id_sp); let (inner, next) = p0.parse_inner_attrs_and_next(); - let mod_attrs = vec::append( - /*bad*/ copy outer_attrs, - inner - ); + let mod_attrs = vec::append(outer_attrs, inner); let first_item_outer_attrs = next; let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); return (ast::item_mod(m0), mod_attrs); @@ -3651,10 +3680,10 @@ pub impl Parser { let lo = self.span.lo; // XXX: Obsolete; remove after snap. - if self.eat_keyword(&~"const") { + if self.eat_keyword("const") { self.obsolete(*self.last_span, ObsoleteConstItem); } else { - self.expect_keyword(&~"static"); + self.expect_keyword("static"); } let ident = self.parse_ident(); @@ -3672,14 +3701,14 @@ pub impl Parser { // parse safe/unsafe and fn fn parse_fn_purity(&self) -> purity { - if self.eat_keyword(&~"fn") { impure_fn } - else if self.eat_keyword(&~"pure") { + if self.eat_keyword("fn") { impure_fn } + else if self.eat_keyword("pure") { self.obsolete(*self.last_span, ObsoletePurity); - self.expect_keyword(&~"fn"); + self.expect_keyword("fn"); // NB: We parse this as impure for bootstrapping purposes. impure_fn - } else if self.eat_keyword(&~"unsafe") { - self.expect_keyword(&~"fn"); + } else if self.eat_keyword("unsafe") { + self.expect_keyword("fn"); unsafe_fn } else { self.unexpected(); } @@ -3688,10 +3717,11 @@ pub impl Parser { // at this point, this is essentially a wrapper for // parse_foreign_items. - fn parse_foreign_mod_items(&self, sort: ast::foreign_mod_sort, + fn parse_foreign_mod_items(&self, + sort: ast::foreign_mod_sort, abis: AbiSet, first_item_attrs: ~[attribute]) - -> foreign_mod { + -> foreign_mod { let ParsedItemsAndViewItems { attrs_remaining: _, view_items: view_items, @@ -3714,12 +3744,11 @@ pub impl Parser { visibility: visibility, attrs: ~[attribute], items_allowed: bool) - -> item_or_view_item - { + -> item_or_view_item { let mut must_be_named_mod = false; - if self.is_keyword(&~"mod") { + if self.is_keyword("mod") { must_be_named_mod = true; - self.expect_keyword(&~"mod"); + self.expect_keyword("mod"); } else if *self.token != token::LBRACE { self.span_fatal( copy *self.span, @@ -3750,6 +3779,11 @@ pub impl Parser { // extern mod foo { ... } or extern { ... } if items_allowed && self.eat(&token::LBRACE) { + // `extern mod foo { ... }` is obsolete. + if sort == ast::named { + self.obsolete(*self.last_span, ObsoleteNamedExternModule); + } + let abis = opt_abis.get_or_default(AbiSet::C()); let (inner, next) = self.parse_inner_attrs_and_next(); @@ -3999,7 +4033,7 @@ pub impl Parser { let visibility = self.parse_visibility(); // must be a view item: - if self.eat_keyword(&~"use") { + if self.eat_keyword("use") { // USE ITEM (iovi_view_item) let view_item = self.parse_use(); self.expect(&token::SEMI); @@ -4011,10 +4045,10 @@ pub impl Parser { }); } // either a view item or an item: - if self.eat_keyword(&~"extern") { + if self.eat_keyword("extern") { let opt_abis = self.parse_opt_abis(); - if self.eat_keyword(&~"fn") { + if self.eat_keyword("fn") { // EXTERN FUNCTION ITEM let abis = opt_abis.get_or_default(AbiSet::C()); let (ident, item_, extra_attrs) = @@ -4030,11 +4064,11 @@ pub impl Parser { } } // the rest are all guaranteed to be items: - if (self.is_keyword(&~"const") || - (self.is_keyword(&~"static") && - !self.token_is_keyword(&~"fn", &self.look_ahead(1)))) { + if (self.is_keyword("const") || + (self.is_keyword("static") && + !self.token_is_keyword("fn", &self.look_ahead(1)))) { // CONST / STATIC ITEM - if self.is_keyword(&~"const") { + if self.is_keyword("const") { self.obsolete(*self.span, ObsoleteConstItem); } self.bump(); @@ -4043,7 +4077,7 @@ pub impl Parser { visibility, maybe_append(attrs, extra_attrs))); } - if self.is_keyword(&~"fn") && + if self.is_keyword("fn") && !self.fn_expr_lookahead(self.look_ahead(1u)) { // FUNCTION ITEM self.bump(); @@ -4053,56 +4087,57 @@ pub impl Parser { visibility, maybe_append(attrs, extra_attrs))); } - if self.eat_keyword(&~"pure") { + if self.eat_keyword("pure") { // PURE FUNCTION ITEM (obsolete) self.obsolete(*self.last_span, ObsoletePurity); - self.expect_keyword(&~"fn"); + self.expect_keyword("fn"); let (ident, item_, extra_attrs) = self.parse_item_fn(impure_fn, AbiSet::Rust()); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } - if self.is_keyword(&~"unsafe") + if self.is_keyword("unsafe") && self.look_ahead(1u) != token::LBRACE { // UNSAFE FUNCTION ITEM self.bump(); - self.expect_keyword(&~"fn"); + self.expect_keyword("fn"); let (ident, item_, extra_attrs) = self.parse_item_fn(unsafe_fn, AbiSet::Rust()); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } - if self.eat_keyword(&~"mod") { + if self.eat_keyword("mod") { // MODULE ITEM - let (ident, item_, extra_attrs) = self.parse_item_mod(attrs); + let (ident, item_, extra_attrs) = + self.parse_item_mod(/*bad*/ copy attrs); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } - if self.eat_keyword(&~"type") { + if self.eat_keyword("type") { // TYPE ITEM let (ident, item_, extra_attrs) = self.parse_item_type(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } - if self.eat_keyword(&~"enum") { + if self.eat_keyword("enum") { // ENUM ITEM let (ident, item_, extra_attrs) = self.parse_item_enum(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } - if self.eat_keyword(&~"trait") { + if self.eat_keyword("trait") { // TRAIT ITEM let (ident, item_, extra_attrs) = self.parse_item_trait(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } - if self.eat_keyword(&~"impl") { + if self.eat_keyword("impl") { // IMPL ITEM let (ident, item_, extra_attrs) = self.parse_item_impl(visibility); @@ -4110,7 +4145,7 @@ pub impl Parser { visibility, maybe_append(attrs, extra_attrs))); } - if self.eat_keyword(&~"struct") { + if self.eat_keyword("struct") { // STRUCT ITEM let (ident, item_, extra_attrs) = self.parse_item_struct(); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, @@ -4131,13 +4166,13 @@ pub impl Parser { let visibility = self.parse_visibility(); - if (self.is_keyword(&~"const") || self.is_keyword(&~"static")) { + if (self.is_keyword("const") || self.is_keyword("static")) { // FOREIGN CONST ITEM let item = self.parse_item_foreign_const(visibility, attrs); return iovi_foreign_item(item); } - if (self.is_keyword(&~"fn") || self.is_keyword(&~"pure") || - self.is_keyword(&~"unsafe")) { + if (self.is_keyword("fn") || self.is_keyword("pure") || + self.is_keyword("unsafe")) { // FOREIGN FUNCTION ITEM let item = self.parse_item_foreign_fn(attrs); return iovi_foreign_item(item); @@ -4305,7 +4340,7 @@ pub impl Parser { } _ => () } - let last = path[vec::len(path) - 1u]; + let last = path[path.len() - 1u]; let path = @ast::Path { span: mk_sp(lo, self.span.hi), global: false, idents: path, @@ -4328,16 +4363,16 @@ pub impl Parser { fn is_view_item(&self) -> bool { let tok, next_tok; - if !self.is_keyword(&~"pub") && !self.is_keyword(&~"priv") { + if !self.is_keyword("pub") && !self.is_keyword("priv") { tok = copy *self.token; next_tok = self.look_ahead(1); } else { tok = self.look_ahead(1); next_tok = self.look_ahead(2); }; - self.token_is_keyword(&~"use", &tok) - || (self.token_is_keyword(&~"extern", &tok) && - self.token_is_keyword(&~"mod", &next_tok)) + self.token_is_keyword("use", &tok) + || (self.token_is_keyword("extern", &tok) && + self.token_is_keyword("mod", &next_tok)) } // parse a view item. @@ -4347,10 +4382,10 @@ pub impl Parser { vis: visibility ) -> @view_item { let lo = self.span.lo; - let node = if self.eat_keyword(&~"use") { + let node = if self.eat_keyword("use") { self.parse_use() - } else if self.eat_keyword(&~"extern") { - self.expect_keyword(&~"mod"); + } else if self.eat_keyword("extern") { + self.expect_keyword("mod"); let ident = self.parse_ident(); let metadata = self.parse_optional_meta(); view_item_extern_mod(ident, metadata, self.get_id()) |
